tl;dr
The userSMIMECertificate attribute must hold a signed S/MIME message.
To create the contents for userSMIMECertificate, sign an email message with an empty message body, then remove all mail headers except for those describing the signature attachment.
The result should look similar to this (signature only):
Content-Disposition: attachment;
filename=smime.p7s
Content-Type: application/pkcs7-signature;
name=smime.p7s
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIEQTCCBD0w
ggMloAMCAQICAQIwDQYJKoZIhvcNAQELBQAwgbYxGjAYBgNVBAMMEXNhdmlnbmFubyBDRVJULWky
MSUwIwYDVQQKDBxzYXZpZ25hbm8gc29mdHdhcmUgc29sdXRpb25zMR4wHAYDVQQLDBVDZXJ0aWZp
[...and so on...]
wtIEojI4gYW+wg/50/viPjxisPIPm3dEJbM+CN5gnySH9HwAAAAAAAA=
or like this (multipart message):
MIME-Version: 1.0
Content-Type: multipart/signed;
protocol="application/x-pkcs7-signature";
micalg=SHA1;
boundary="----=_NextPart_000_003C_01D7312D.9474A240"
This is a multipart message in MIME format.
------=_NextPart_000_003C_01D7312D.9474A240
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
This contents part may be empty or not and will be ignored.
------=_NextPart_000_003C_01D7312D.9474A240
Content-Disposition: attachment;
filename=smime.p7s
Content-Type: application/pkcs7-signature;
name=smime.p7s
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCCCDUw
ggQDMIIC66ADAgECAgRK+N2BMA0GCSqGSIb3DQEBCwUAMIHAMSMwIQYDVQQDDBpzYXZpZ25hbm8g
[...]
E3toHxuZzFrZMnMobwmt1nbAwNodpSsAAAAAAAA=
------=_NextPart_000_003C_01D7312D.9474A240--
This format can be created manually by signing an empty message using an email client, then saving that email in text format and removing the unwanted headers in an editor.
To create this format with openssl, use:
openssl smime -sign -in empty.txt -text -out userSMIMEcertificate.txt -signer mycert.pem -certfile intermediatecerts.pem
where mycert.pem
is the signer's private certificate including its key and intermediatecerts.pem
are any additional certificates that should be included. Add -inkey mykey.pem
if the key is separate rather than included in the private certificate.
Note that, in order to sign the message, the certificate owner's private key is required.
Background Details
Format
The userSMIMECertificate is designed to hold a signed message that is signed using the user's email certificate. Additionally, it can and it should also contain the other certificates needed for chaining and verifying the user certificate. It's also designed to provide details about the encryption algorithms which are supported and preferred by the email client.
The userSMIMECertificate LDAP attribute is defined in RFC 2798: Definition of the inetOrgPerson LDAP Object Class as
A PKCS#7 [RFC2315] SignedData, where the content that is signed is
ignored by consumers of userSMIMECertificate values.
The format is based on RFC 2315: PKCS #7: Cryptographic Message Syntax. I find this RFC hard to understand, but fortunately, there is another document RFC 4134: Examples of S/MIME Messages that exhibits an example in chapter 4.9 S/MIME application/pkcs7-mime Signed Message.
As we can see there, it is an S/MIME signed email as created by any email client when sending a signed (but not encrypted) email.
According to this, it's not even necessary to remove any headers, but I recommend it for improved compatibility.
Purpose
In a quote from an original discussion with the creators of the userSMIMECertificate LDAP attribute, one of the authors explains:
Now we come to the question of why we felt we needed a new directory attribute for S/MIME certificates. I was told by our directory engineers that the existing userCertificate attribute was defined as a single raw certificate. That leaves no place to store the other certificates needed for chaining, and no place to store the algorithm capabilities. We had an existing package available to us that could contain both the certificates and the capabilities. That package is an S/MIME signed message.
The format of the userSMIMECertificate attribute is an S/MIME signed message with a zero length body. It contains the user's entire certificate chain and the signed attribute that describes their algorithm capabilities.
There is also a draft about the format to publish the data in userSMIMECertificate that provides some insight, but it has expired in 2001, and there doesn't seem to be successor to it.
Practical Notes
Weak Support
Most email clients seem not to understand a userSMIMECertificate that holds a PKCS#7 signed message. They do understand DER encoded certificates in this attribute. I'm planning to create a compatibility table but haven't yet.
Removed Headers
My above recommendation to remove all headers so only the signature is left is made because I have otherwise experienced problems with some clients, but I don't remember which. The actual definition does not require such modifications.
Algorithm Capabilities
One of the ideas for userSMIMECertificate was that the PKCS#7 data can include the owner's encryption capabilities (i.e. which ciphers they support). That way the encrypting client can select the best encryption cipher supported by both the sender and recipient of the email.
However, in extensive testing I've learned that in practice, only some (older) email clients provide such capabilities. My guess is that this feature has become obsolete by the fact that nowadays users are not confined to using only one email client all the time. Therefore, including one client's capabilities would be useless at best and might even lead to problems with the other client(s).