Storing Trust Assertions in PKCS#11 Modules Rough "rougher than burlap underwear" draft December 2010 Stef Walter Collabora Ltd
stefw@collabora.co.uk
Introduction Trust assertions are represent bits of trust information used by an application to make trust decisions. For example, trust assertions can represent certificate authority anchors, pinned certificate exceptions, or revocation lists. Trust assertions do not represent the trust decision itself. They are merely one factor in the trust decision. However by using trust assertions applications (and libraries) can make consistent trust decisions and interoperate with one another. This is a building block toward a usable crypto experience for the user of such applications. PKCS#11 is a useful and widely supported standard for storage and use of keys and certificates. It is often used with smart cards. This specification outlines how to store and lookup trust assertions via the PKCS#11 API. We detail an extension which accomplishes this. A word on terminology. We use the word trust quite a bit in this document. This is a highly overloaded and subjective term, and its use in this specification is unfortunate. An unambiguous term is desirable. The author cringes every time the word trust is used. The author cringes a lot.
Trust Assertions A trust assertion is a generic concept. Each trust assertion describes a level of trust in a certain subject for a given purpose. Conceptually each trust assertion is a triple containing the following: Reference to the subject Purpose Level of trust We examine each of these parts of the triple in further detail below.
Level of Trust This describes the level of trust represented by the trust assertion. Untrusted The trust assertion marks the subject as explicitly untrusted. This overrides other trust. Trusted The trust assertion marks the subject as explicitly trusted. Anchor The trust assertion marks the subject as trusted to confer its trust (eg: via signatures) on other subjects (eg: via a certificate chain). We can call trust assertions which establish trust positive trust assertions. In essence these trust assertions build up trust in a subject. These have a level of trust of trusted or anchor. Examples of this kind of trust assertion are certificate authority trust anchors. Trust assertions that falsify trust can be called negative trust assertions. These trust assertions tear down trust in a subject. They assume the subject is already trusted, and want to revoke or falsify that trust. These have a level of trust of untrusted. Examples of this kind of trust assertion are certificate revocation lists. Negative trust assertions always override positive trust assertions.
Purpose A trust assertion always refers to a specific purpose or usage. This is the thing that the subject is trusted to do. For example a certificate may be trusted for purposes like: email, code signing, or authenticating a remote host. In addition, the purpose can contain a peer, which further narrows what the subject is trusted to do. It is then only trusted for for the given purpose when the given peer is involved. For example the peer might be the host name of a server.
Subject Reference Each trust assertion contains a reference to the subject. This is the thing that is trusted. In this specification we will deal exclusively with X.509 certificates as the subject of trust assertions.
PKCS#11 Trust Assertion Objects Trust assertions are stored as objects on a PKCS#11 token. Although these are specific to a certificate, they do not need to be stored on the same token as the certificate. When represented as PKCS#11 objects, trust assertions become less elegant than the reference + purpose + trust-level triple described above. This is done because of limitations in the PKCS#11 API and also to minimizing the number of PKCS#11 lookups required to use trust assertions. There are two ways that a trust assertion refers to a certificate. Certificates used in 'positive' trust assertions are referred to by the complete DER encoding of the certificate. Certificates used in 'negative' trust assertions are referred to by the DER value of the certificate's issuer field and its serial number. Unfortunately, we cannot have a single way to refer to certificates used in both positive and negative trust assertions. For example, referring to a certificate authority trust anchor by its issuer and serial number would be meaningless. And using a full DER value to refer to negative trust assertions would preclude uses such as certificate revocation lists. Therefore different methods must be used to refer to certificates in these different situations. The objects below reflect this.
Common Trust Assertion Object Attributes First we describe the attributes that all trust assertion objects have in common. All trust assertions are of the class CKO_X_TRUST_ASSERTION. General trust assertion attributes Attribute Data Type Description CKA_CLASS CK_OBJECT_CLASS CKO_X_TRUST_ASSERTION CKA_X_ASSERTION_TYPE CK_X_ASSERTION_TYPE The type of trust assertion. This represents the level of trust. See the various assertion types. CKA_X_PURPOSE CK_UTF8_CHAR array The string representation of the purpose, usually an OID, and often one of the predefined purposes.
The CKA_X_PURPOSE attribute contains a string which represents the purpose of the trust assertion. These are generally OIDs. The following predefined values match those of the Extended Key Usage X.509 extension. Other values may be used when interoperability of the trust assertion between multiple applications is not required. Predefined Purposes Value Description 1.3.6.1.5.5.7.3.1 TLS Server Authentication 1.3.6.1.5.5.7.3.2 TLS Client Authentication 1.3.6.1.5.5.7.3.3 Code Signing 1.3.6.1.5.5.7.3.4 Email Protection 1.3.6.1.5.5.7.3.5 IPsec Endpoint 1.3.6.1.5.5.7.3.6 IPsec Tunnel 1.3.6.1.5.5.7.3.7 IPsec User 1.3.6.1.5.5.7.3.8 Time Stamping
Each different type of trust assertion is represented by a different CK_X_ASSERTION_TYPE value. These represent the level of trust. Each type of trust assertion has additional attributes and is a distinctly different type of PKCS#11 object. The following types are defined. Trust assertion types Trust Type Description CKT_X_ANCHORED_CERTIFICATE A positive trust assertion that represents a trust anchor which is used as the anchor of a certificate chain. CKT_X_PINNED_CERTIFICATE A positive trust assertion that represents an explicit trust in a certificate. CKT_X_UNTRUSTED_CERTIFICATE A negative trust assertion that represents an explicit untrust in a certificate.
Anchored Certificate Assertion An anchored certificate is a trust assertion which is to be used with a certificate authority that has signed other trusted certificates. It is to be used as the anchor in a certificate chain. Because it is a positive trust assertion, the certificate is referenced by using the entire DER encoding of the certificate. In addition to the following attributes, all the general trust assertion attributes are present on a anchored certificate trust assertion. Anchored Certificate Assertion Attributes Attribute Data Type Description CKA_X_ASSERTION_TYPE CK_X_ASSERTION_TYPE CKT_X_CERTIFICATE_TRUST_ANCHOR CKA_X_CERTIFICATE_VALUE Byte array The DER encoding of the certificate.
Pinned Certificate Assertion A pinned certificate is an endpoint certificate (not an authority) which is trusted explicitly. The expectation is that all other trust validation is overridden by this pinned trust. Because it is a positive trust assertion, the certificate is referenced by using the entire DER encoding of the certificate. All pinned certificate trust assertions have a designated peer with which the pinned certificate assertion is relevant. In the case of the TLS authentication purpose, this is the host name of the peer that is being communicated with. In the case of the email protection purpose this is the email address this certificate is to being used with. In addition to the following, all the general trust assertion attributes are present on a pinned certificate trust assertion. Pinned Certificate Assertion Attributes Attribute Data Type Description CKA_X_ASSERTION_TYPE CK_X_ASSERTION_TYPE CKT_X_PINNED_CERTIFICATE CKA_X_PEER CK_UTF8_CHAR array The peer part of the purpose. CKA_X_CERTIFICATE_VALUE Byte array The DER encoding of the certificate.
Untrusted Certificate Assertion An untrusted certificate is a trust assertion which signifies the explicit lack of trust in a certificate. An example of this is an item in a CRL or a certificate explicitly marked as untrusted by a user. Because it is a negative trust assertion, the certificate is referenced by a using the issuer and serial number of the certificate in question. In addition to the following, all the general trust assertion attributes are present on a untrusted certificate assertion. Untrusted Certificate Assertion Attributes Attribute Data Type Description CKA_X_ASSERTION_TYPE CK_X_ASSERTION_TYPE CKT_X_UNTRUSTED_CERTIFICATE CKA_ISSUER Byte array DER-encoding of the certificate issuer name CKA_SERIAL_NUMBER Byte array DER-encoding of the certificate serial number
Operations
Building a Certificate Chain During TLS or other certificate verification operations, a certificate chain must be built. The certificate chain starts with a endpoint certificate for the peer, and usually ends with a certificate explicitly trusted in some way, such as a certificate authority trust anchor. The certificates in the chain are each in turn signed by the next certificate in the chain. Conceptually building a certificate chain has two parts 1) building the chain based on positive trust assertions, and 2) allowing then allowing falsification of all or part of the chain based on negative trust assertions. Here is how this is accomplished. For interoperability it is important to perform the following lookups using the attributes described: Check if the endpoint certificate has a pinned certificate for the given purpose and peer. If a pinned certificate is found then the certificate chain consists of one certificate and is considered valid at this point. To check for pinned certificates, perform a C_FindObject operation with the following attributes: CKA_CLASS: CKO_X_ASSERTION_TYPE CKA_X_ASSERTION_TYPE: CKT_X_PINNED_CERTIFICATE CKA_X_CERTIFICATE_VALUE: DER encoding of certificate CKA_X_PURPOSE: purpose string CKA_X_PEER: peer string Use PKCS#11 to find all the certificates necessary for the certificate chain. Often a peer will not send a complete chain and only send its own certificate. Build up the chain using the certificate issuer of each certificate to search for issuing certificates. This is done until a self-signed issuing certificate is found, or an issuing certificate is not found. To lookup issuing certificates, perform a C_FindObject operation with the following attributes: CKA_CLASS: CKO_CERTIFICATE CKA_CERTIFICATE_TYPE: CKC_X_509 CKA_SUBJECT: Der encoding of subject of issued certificate Check for an anchored certificate assertion for each certificate in the chain starting from the certificate that signed the endpoint certificate. The endpoint certificate is not considered for a possible anchor. When a anchor is found then the certificate chain is truncated at that point. Certificates past the trust anchor are ignored. To check for anchored certificates, perform a C_FindObject operation with the following attributes: CKA_CLASS: CKO_X_ASSERTION_TYPE CKA_X_ASSERTION_TYPE: CKT_X_ANCHORED_CERTIFICATE CKA_X_CERTIFICATE_VALUE: DER encoding of certificate CKA_X_PURPOSE: purpose string Allow falsification for each certificate in the resulting certificate chain by checking whether each certificate has an untrusted certificate assertion. If at any point an untrusted assertion is found (eg: a certificate listed on a certificate revocation list) then the certificate chain is considered invalid. To check for untrusted certificates, perform a C_FindObject operation with the following attributes: CKA_CLASS: CKO_X_ASSERTION_TYPE CKA_X_ASSERTION_TYPE: CKT_X_UNTRUSTED_CERTIFICATE CKA_X_CERTIFICATE_VALUE: DER encoding of certificate CKA_X_PURPOSE: purpose string Pass the resulting certificate chain to the crypto library for further validation of signers, identity matching, etc.
Justifications Some answers to why this spec was designed as it is.
Why use a complete certificate DER encoding for positive trust assertions? Conceivably we could use a hash of the certificate instead of the CKA_X_CERTIFICATE_VALUE. NSS Trust Objects use hashes in this way. In the current climate where many hash algorithms are broken in various ways it seems prudent to avoid the hashing of the certificate and just use the complete certificate DER encoding for lookups. This allows a robust standard that is not dependent on the long term viability of a specific hash algorithm.
Why refer to certificates in negative trust assertions by issuer and serial number? Certificate revocation lists do not generally contain the full value of the certificate or a hash thereof. They simply contain serial numbers, which when combined with the issuer of the certificate revocation list, are meant to uniquely identify a given certificate. In order to support CRLs exposed as untrusted certificate assertions (which is one of the design goals of this specification) we must limit ourselves to this method of referencing certificates in negative trust assertions.
Why not use NSS Trust Objects? NSS contains an implementation of storing trust information via PKCS#11. This has not been completely documented, but an overview is available. This method of storing trust information has been in use by NSS for many years. However the NSS method is starting to show its age. After study of NSS's method of storing trust information, and discussion with others, the following inherent problems are apparent. Mandates the use SHA1 and MD5 hashes both of which are cryptographically broken in various way. Neither MD5 or SHA1 are currently recommended for use in specifications. Only supports a distinct set of purposes, new purposes are not supported. Does not support a storage of a peer along with the purpose, which precludes storage of pinned certificate assertions. Objects represent a number of trust assertions stored in a single PKCS#11 object leading to more complex lookup and modification operations.
Why not use PKCS#11 URIs? The PKCS#11 URI Scheme is a useful draft standard which can be used to identify objects stored on a PKCS#11 token. It has been suggested that a list of PKCS#11 URIs could be used to identify which certificates are useful as certificate anchors. As outlined above, positive trust assertions build up trust. Certificates used in positive trust assertions must be identified by the certificate value or a hash thereof. PKCS#11 URIs do not have the ability to uniquely identify a certificate by its DER encoding or a hash thereof.
How is this related to CKA_TRUSTED? Later versions of the PKCS#11 spec contain an attribute called CKA_TRUSTED. This attribute can be set on public keys, secret keys, and certificates by an application as a flag indicating trust in some form. CKA_TRUSTED can be used as a crude form of marking which certificates can be used as a certificate authority trust anchor. We see this specification as complementary to CKA_TRUSTED. This specification defines a fine grained method for representing all sorts of positive and negative trust assertions, and not just anchored certificates.