Here's an example for adding a set of S/MIME client capability extensions when signing an S/MIME user cert, taken from an example on the OpenSSL mailing list:

[my_cert_extensions]
basicConstraints         = CA:FALSE
keyUsage                 = critical, keyEncipherment, dataEncipherment
SMIME-CAPS               = ASN1:SEQUENCE:smime_seq
subjectKeyIdentifier     = hash
authorityKeyIdentifier   = keyid,issuer

[ smime_seq ]
SMIMECapability.0 = SEQWRAP,OID:sha1
SMIMECapability.1 = SEQWRAP,OID:sha256
SMIMECapability.2 = SEQWRAP,OID:sha1WithRSA
SMIMECapability.3 = SEQWRAP,OID:aes-256-ecb
SMIMECapability.4 = SEQWRAP,OID:aes-256-cbc
SMIMECapability.5 = SEQWRAP,OID:aes-256-ofb
SMIMECapability.6 = SEQWRAP,OID:aes-128-ecb
SMIMECapability.7 = SEQWRAP,OID:aes-128-cbc
SMIMECapability.8 = SEQWRAP,OID:aes-128-ecb
SMIMECapability.9 = SEQUENCE:rsa_enc

[ rsa_enc ]
capabilityID = OID:rsaEncryption
parameter = NULL

This is activated by, amongst other ways, using openssl command-line option -extensions my_cert_extensions.

There are two more pieces to the puzzle:

  • more details on how extension data can be constructed is in the OpenSSL API documentation here, but you need to know a little about ASN.1 and OIDs to make sense of that.
  • if your extension really is custom then you probably should apply to IANA for a Private Enterprise Number (this is a must if your extensions may be seen in the wild)

If you wish to add text using an existing extension it's usually a little easier, if you have:

[ CA_default ]
...
x509_extensions = usr_cert

[ usr_cert ]
basicConstraints=CA:FALSE
...
nsComment = "This is my comment"

CA_default is used during the normal CA signing, if you can use a pre-defined extension then all you have to do is add it to the usr_cert section, no extra command line options required. (nsComment is technically deprecated, but it still works, it's a simple example and is easily viewable within certificate properties in common browsers).

See the x509v3_config man page which explains extensions basics, and the OpenSSL source crypto/objects/objects.txt for the somewhat cryptic details (this file is processed and used to generate code).

An OID is typically associated with a discrete concept, like a noun, a verb, an attribute or even something less tangible (like UUIDs, but hierarchical). nsComment has a defined meaning (free-form text comments inside certificates), others like keyUsage have stricter semantics.

Within OpenSSL the name "nsComment" is mapped to OID 2.16.840.1.113730.1.13, as set in objects.txt. Every extension in an X.509v3 certificate has an OID, see https://stackoverflow.com/questions/15299201/asn-1-octet-strings .

If there is no suitable extension in OpenSSL (see RFC 5280 §4.2 Certificate Extensions), you may be able to find one and add it (see the "Arbitrary Extensions" section in the x509v3_config man page linked above). Otherwise you will need to define OIDs for your own purposes.


Add the custom extension to either a custom openssl.cnf configuration file or a specific extensions file and reference that on your commandline e.g.

openssl ca -config ./my-openssl.cnf -extensions ./my-openssl-extensions.cnf <options>

From the manual page:

-extensions section the section of the configuration file containing certificate extensions to be added when a certificate is issued (defaults to x509_extensions unless the -extfile option is used). If no extension section is present then, a V1 certificate is created. If the extension section is present (even if it is empty), then a V3 certificate is created. See the x509v3_config(5) manual page for details of the extension section format.