Storing Trust Assertions in PKCS#11 Modules

Stef Walter

Collabora Ltd

Rough "rougher than burlap underwear" draft


Table of Contents

Introduction
Trust Assertions
Level of Trust
Purpose
Subject Reference
PKCS#11 Trust Assertion Objects
Common Trust Assertion Object Attributes
Anchored Certificate Assertion
Pinned Certificate Assertion
Distrusted Certificate Assertion
Operations
Building a Certificate Chain
Justifications
Why use a complete certificate DER encoding for positive trust assertions?
Why refer to certificates in negative trust assertions by issuer and serial number?
Why not use NSS Trust Objects?
Why not use PKCS#11 URIs?
How is this related to CKA_TRUSTED?

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.

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.

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:

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.

Distrusted

The trust assertion marks the subject as explicitly distrusted. 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 distrusted. 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.

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

AttributeData TypeDescription
CKA_CLASSCK_OBJECT_CLASSCKO_X_TRUST_ASSERTION
CKA_X_ASSERTION_TYPECK_X_ASSERTION_TYPEThe type of trust assertion. This represents the level of trust. See the various assertion types.
CKA_X_PURPOSECK_UTF8_CHAR arrayThe 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

ValueDescription
1.3.6.1.5.5.7.3.1TLS Server Authentication
1.3.6.1.5.5.7.3.2TLS Client Authentication
1.3.6.1.5.5.7.3.3Code Signing
1.3.6.1.5.5.7.3.4Email Protection
1.3.6.1.5.5.7.3.8Time 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 TypeDescription
CKT_X_ANCHORED_CERTIFICATEA positive trust assertion that represents a trust anchor which is used as the anchor of a certificate chain.
CKT_X_PINNED_CERTIFICATEA positive trust assertion that represents an explicit trust in a certificate.
CKT_X_DISTRUSTED_CERTIFICATEA negative trust assertion that represents an explicit distrust 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.

Table 4. Anchored Certificate Assertion Attributes

AttributeData TypeDescription
CKA_X_ASSERTION_TYPECK_X_ASSERTION_TYPECKT_X_CERTIFICATE_TRUST_ANCHOR
CKA_X_CERTIFICATE_VALUEByte arrayThe 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.

Table 5. Pinned Certificate Assertion Attributes

AttributeData TypeDescription
CKA_X_ASSERTION_TYPECK_X_ASSERTION_TYPECKT_X_PINNED_CERTIFICATE
CKA_X_PEERCK_UTF8_CHAR arrayThe peer part of the purpose.
CKA_X_CERTIFICATE_VALUEByte arrayThe DER encoding of the certificate.

Distrusted Certificate Assertion

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

AttributeData TypeDescription
CKA_X_ASSERTION_TYPECK_X_ASSERTION_TYPECKT_X_DISTRUSTED_CERTIFICATE
CKA_ISSUERByte arrayDER-encoding of the certificate issuer name
CKA_SERIAL_NUMBERByte arrayDER-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:

  1. 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
    	
  2. 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
    	
  3. 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
    	
  4. 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
    	
  5. 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 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.

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.