Table of Contents
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.
In this specification we deal only with trust assertions related to certificates. In theory, trust assertions can relate to secret keys, and other subjects as well. Future versions of this specification may specify trust assertions for these other subjects.
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:
We examine each of these parts of the triple in further detail below.
This describes the level of trust represented by the trust assertion.
The trust assertion marks the subject as explicitly distrusted. This overrides other trust.
The trust assertion marks the subject as explicitly trusted.
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 distrusted. Examples of this kind of trust assertion are certificate revocation lists.
Negative trust assertions always override positive trust assertions.
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.
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.
First we describe the attributes that all trust assertion objects have in
common. All trust assertions are of the class
CKO_X_TRUST_ASSERTION
.
In addition to the following trust assertion attributes, all the stardard
PKCS#11 storage object attributes of CKA_TOKEN
,
CKA_PRIVATE
, CKA_MODIFIABLE
and
CKA_LABEL
may be present.
Table 1. 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.
Applications should ignore trust assertions whose CKA_X_PURPOSE
attribute
they do not understand. They should not treat them as negative assertions.
Table 2. 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.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.
Table 3. 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_DISTRUSTED_CERTIFICATE | A negative trust assertion that represents an explicit distrust in a certificate. |
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.
Table 4. 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. |
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.
Table 5. 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. |
An distrusted 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 distrusted 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 distrusted certificate assertion.
Table 6. Distrusted Certificate Assertion Attributes
Attribute | Data Type | Description |
---|---|---|
CKA_X_ASSERTION_TYPE | CK_X_ASSERTION_TYPE | CKT_X_DISTRUSTED_CERTIFICATE |
CKA_ISSUER | Byte array | DER-encoding of the certificate issuer name |
CKA_SERIAL_NUMBER | Byte array | DER-encoding of the certificate serial number |
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 distrusted certificate assertion. If at any point an distrusted assertion is found (eg: a certificate listed on a certificate revocation list) then the certificate chain is considered invalid.
To check for distrusted certificates, perform a
C_FindObject
operation with the following
attributes:
CKA_CLASS: CKO_X_ASSERTION_TYPE CKA_X_ASSERTION_TYPE: CKT_X_DISTRUSTED_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.
Some answers to why this spec was designed as it is.
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.
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 distrusted 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.
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.
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.
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.