# What exactly is the contents of the LDAP userSMIMECertificate attribute?

I'm trying to setup an LDAP with user certificates. I have already learned that certificates can be stored in either the userCertificate attribute in DER format, or in userSMIMECertificate in PKCS#7 format, the latter having the advantage of being able to contain the full certificate chain, plus the S/MIME algorithms supported and/or preferred by the client.

However, I'm struggling with what variation of the PKCS#7 format has to be used. I can export certificates as p7b file which - as I understand it - is just a certificate bundle containing multiple certificates, but no further information.

The userSMIMECertificate obviously expects a (signed?) CMS message with no (or at least a negligible) message text. Is this the p7m format created by email clients? But that seems to be encrypted? How can I create the required userSMIMECertificate format?

• – SEJPM Jul 5 '18 at 14:09
• Thank you for that, however, the info I‘ve posted comes from this RFC, but it doesn’t answer my question how to create the contents of the attribute. – not2savvy Jul 6 '18 at 16:41

It is PKCS7 signed message. In .Net you can use SignedCMS object

...
using System.Security.Cryptography.Pkcs;
...

var ctx = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain);
var userPrincipal  = System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(ctx, System.DirectoryServices.AccountManagement.IdentityType.SamAccountName, "...account...");

var sm = adObject.Properties["userSMIMECertificate"] as byte[];
var sCMS = new SignedCms();
sCMS.Decode(smc);


ContentType is of type 1.2.840.113549.1.7.1 ( "PKCS 7 Data" ).

In my case it was not empty but contained 45 6d 70 74 79 20 42 6f 64 79

"Empty Body"

If you only need the certificates of this object, you can use the import function of the X509Certificate2Collection


var col = new System.Security.Cryptography.X509Certificates.X509Certificate2Collection();
col.Import((byte[])smc);



Creating this userSMIMECertificate object has one issue : you need access to the private keys. So it will be the user itself, or a smartcard management system (which has the card when issuing), who can create the object.

It is not necessary to use "userSMIMECertificate" , but only use "userCertificate". The latter is enterprise manageable, and using the two can give conflicts when different. It also depends on the client which one is used first.

• Thanks for your additional information. However, I've never come across a recommendation not to use userSMIMECertificate. Can you elaborate on this and provide a source for your quote? My findings are that userSMIMECertificate is preferred because it is able to provide the certificate chain, while userCertificate can hold only one certificate. – not2savvy Jan 21 '19 at 9:51
• Moreover, the p7m format in userSMIMECertificate can hold information about the client's supported and preferred encryption algorithms which userCertificate cannot provide. – not2savvy Jan 21 '19 at 9:56
• userSMIMECertificate will be used first, if available. – Luc Vandenbroucke Jan 21 '19 at 13:16
• some of the answer was gone. From an "advanced user" perspective, userSMimeCertificate is usefull, but from the enterprise managed perspective, ICT cannot (technically, yes with key archival, but that should not be done) sign or manage the users sMimeCertificate, only they can maintain userCertificate. So Microsoft also has an option to disable publish to userSmimeCeriticate in group policy.. – Luc Vandenbroucke Jan 22 '19 at 13:04

tl;dr

The userSMIMECertificate attribute must hold a signed message.

To create the contents of the 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 like similar to this:

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=


This can even be performed 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.

Details

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 format is based on RFC 2315: PKCS #7: Cryptographic Message Syntax.

However, I haven't been able to find a definite and exact definition of the userSMIMECertificate attribute contents. I base my answer on the following resources:

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.

Although there is a draft about the format of the data in userSMIMECertificate, it has expired in 2001, and there doesn't seem to be successor to it.