There are two ways of defining the KU and EKU for certificates generated by the step toolchain; both require the use of templates. Here’s a basic example of the default template generating an X.509 certificate with some listed settings for Key Usage and Extended Key Usage:
{ "subject": {{ toJson .Subject }}, "sans": {{ toJson .SANs }}, {{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }} "keyUsage": ["keyEncipherment", "digitalSignature"], {{- else }} "keyUsage": ["digitalSignature"], {{- end }} "extKeyUsage": ["serverAuth", "clientAuth"] }
Hard-Coded Values
If you simply need all certificates generated by a given provisioner to have digitalSignature, keyEncipherment, keyAgreement, and serverAuth abilities (eg. requirements for OpenVPN servers), your template could be as simple as the following:
{ "subject": {{ toJson .Subject }}, "sans": {{ toJson .SANs }}, "keyUsage": ["digitalSignature", "keyEncipherment", "keyAgreement"], "extKeyUsage": ["serverAuth"] }
From here, you can create a new provisioner (or update an existing provisioner) that uses this template to sign certificates:
$ step ca provisioner add <name> --type JWK --create \ --x509-template <template_file>
Passing Values with Variables
If you would like anyone with access to a given provisioner to request any KU/EKU of their choosing, you can use variables and the --set command to allow users to define the desired settings. The following template uses two user-based variables:
{ "subject": {{ toJson .Subject }}, "sans": {{ toJson .SANs }}, {{- if .Insecure.User.keyUsage }} "keyUsage": {{ toJson .Insecure.User.keyUsage }}, {{- else }} "keyUsage": ["digitalSignature"], {{- end }} {{- if .Insecure.User.extKeyUsage }} "extKeyUsage": {{ toJson .Insecure.User.extKeyUsage }}, {{- else }} "extKeyUsage": ["serverAuth", "clientAuth"] {{- end }} }
This template will check if the user has defined the keyUsage and extendedKeyUsage fields when requesting a certificate. If they did, then the certificate will use these values instead of the ones listed as defaults on the template.
Once this template is in place, a user can pass the --set flags to specify the keyUsage and extendedKeyUsage fields when requesting a certificate:
$ step ca certificate "Test Certificate" test.crt test.key \ --provisioner <name> \ --set keyUsage='["digitalSignature", "keyAgreement"]' \ --set extKeyUsage='["clientAuth"]'