NSS libPKIX Brainstorming
Integrating libPKIX functionality is an important task for the future of NSS.
The LibPKIX API Overview
PKIX is split into two layers:
- an independent layer that has main control over cert chain building and verification. It implements algorithm compatible with one described in RFC 3280(6.2 Extending Path Validation).
- a portability layer that supports multiple cert stores (local pkcs11, and remote ldap, http), and OCSP cert validation. This layer does most of it’s work by delegating operations to the underlying crypto platform. It also implements a number of platform-dependent cert chain checkers.
Main functions:
- PKIX_BuildChain: the function attempts to build and validate a certificate chain according to the ProcessingParams using an RFC 3280-compliant validation algorithm. If successful, this function returns NULL(PKIX_Error*) and stores the build result at "pResult", which holds the built certificate chain, as well as additional information, such as the policy tree and the target's public key. If unsuccessful, an Error is returned.
- PKIX_ValidateChain: the function attempts to validate the certificate chian that has been set in the PKIX_ValidateParams pointed to by "params" using an RFC 3280-compliant algorithm. If successful, this function returns NULL and stores the PKIX_ValidateResult at "pResult", which holds additional information, such as the policy tree and the target's public key.
Main structures:
- PKIX_ProcessingParams: are parameters used when validating or building a chain of certificates. Using the parameters, the caller can specify several things, including the various inputs to the PKIX chain validation algorithm (such as trust anchors, initial policies, etc), any customized functionality, such as CertChainCheckers, RevocationCheckers, CertStores(PK11, LDAP, HTTP), CertSelectors(selects certs based on name constrain extension), ResourceLimits(controls work time, chain depth, max number of used certs and crls), and whether revocation checking should be disabled.
- PKIX_BuildResults: represents the result of a PKIX_BuildChain call. It consists of a ValidateResult object, as well as the built and validated certificate chain.
- PKIX_ValidateResults: represents the result of a PKIX_ValidateChain call. It consists of the valid policy tree and public key resulting from validation, as well as the trust anchor used for this chain.
Integration Approach
LibPKIX API provides wide set of types and functions that user should know about and call to set up and run certificate chain building and/or validation. It is agreed that to improve a user experience nss should provide simpler way to access the functionality provided by the library. Existing libPKIX API should be kept private for all external users of NSS. NSS on it's turn should provide a wrapper - a new API, that will bridge the two libraries and will provide easy access to libPKIX certificate validation engine.
LibPKIX validation algorithm implementation is a superior to current NSS implementation in two main areas:
- it is capable to operate in bridge ca environment
- it takes in to the account certificate/user policies.
Today NSS truck has two different implementation of validation algorithm represented by NSS API(CERT_Verify*) and LibPKIX API(PKIX_Build and PKIX_Validate). The two APIs may produce two different, even possibly opposite, answers as a result of their differences. Two avoid asynchronous answers, an old implementation of NSS certificate validation API will be rewritten to call the new libPKIX API. In it's turn, a call to old NSS API will added the new libPKIX API. These two calls will be controlled by the validation engine switch, a control of which will be available to a user by either an environment variable or a programmatic API.
To be able to use most of the features provided by libPKIX, users will need to pass extra parameters to libPKIX(extra parameters compare to current NSS cert validation API) in order to utilize the algorithm that is capable to validate certificate chain while taking in account certificate policy extensions. Extra parameters will also be needed to activate different libPKIX features like use of LDAP and HTTP cert stores, to set revocation options and required name constraints. Return parameter will also be expanded and will include a valid certificate chain and a valid policy tree associated with validated certificate and requested policy parameters.
But in most of the times parameters provided by the old NSS API should be sufficient to receive a valid result from libPKIX provided that the rest of the required parameters are set to the default. And so, an old CERT_Verify* functions should be used when ever caller has no extra parameters, such as policies parameters. In other cases a caller should use the new API when extra new parameters are available for certificate chain validation or there is a need for further process of extra values, such as valid cert chain and policy tree, return by libPKIX.
In addition some changes will be made through out the NSS libraries because two reasons:
- internally NSS makes quite a few CERT_Verify* function calls. I've counted up to 30 of direct and indirect calls to these functions. All these cases should be reviewed and changed if requited.
- extra set of parameters and validation should be propagated to caller application.
- changes to chain building process(see "Open Questions")
Note, that non of the current applications that use NSS library at ReadHat and Sun sides are ready to provide extended set of parameter at the present time. The only major requirement for the first release is to provide a set of valid policies associated with validated certificate.
Open Questions
The following questions need to be discussed/answered before libPKIX can be used in production.
- 1. NSS has several functions that take a leaf cert, and construct and return a cert chain for that leaf cert, without verifying it. These functions operate on the assumption (valid before the advent of cross-certified CAs) that for each cert, there is only one chain leading to a root. These functions construct as much of the chain and they can, and stop when they come to a root or to a CA whose issuer cannot be found. They succeed even if the constructed chain stops short of a root CA, and even if it stops short of a trusted CA cert. In other words, they succeed even if they cannot verify the chain they produce.
- NSS typically uses such a function when constructing a chain for a "user cert" (a cert for which the local user has the private key). The functions assume (IIRC) that user certs are valid unless expired.
- In the PKIX world of cross certified (bridge) CAs, where it may be possible to construct multiple cert chains that lead to multiple roots, we may instead want to construct chains that lead to a trusted root. That is something that libPKIX can do.
- 2. There is a function that takes a list of Issuer names (names of CA cert Subjects) and finds a user cert whose chain leads up to one of the CAs named in the list of Issuer names. In effect, we treat the list of issuer names as a list of trusted roots, and find a user cert whose chain leads up to one of them. This is done by SSL clients to build a cert chain with which to respond to a server's cert request. Today NSS does this without validating the cert chain as we construct it, and we don't handle bridge CAs (cross certified CAs) that may have more than one issuer. We will need to handle those in the world of PKIX.
- 3. NSS has functions that find a user cert that is believed to be valid for a purpose, e.g. find a user cert valid for email signing. Today, the algorithm assumes that all unexpired user certs are valid, and so it merely filters user certs based on cert extensions (such as Key Usage, Extended Key Usage, Netscape Cert type) to find the first cert valid for the purpose. We may want a version of these functions that chooses a cert that is verifiably valid against one of our trusted roots.
- The next step is to find all the functions in each of these categories, so that we can examine their signatures to see what arguments they are already taking, which will tell us what information the callers already possess.
- The next step after that will be to look at all the callers of those functions, to see if they will have access to additional information (such as policy info) with which to construct a chain or choose a cert.
- 4. One of the parameters of the validation process that libPKIX produces is a validated policy tree. I'm wondering if there is going to be a use of a policy tree in the browser.
- One of the application that I can think of is to use the tree in the UI, to show user why this particular policy and it's modifier was picked. If there is no use of it, we can limit API to return only the set of valid policy oids of he leaf certificate. Please not, that policy tree is not available if build/validation process failed.
Features
- Ensure that our new code can handle the (client auth) case, where the trust information relevant to the cert path construction (on the client side) is different from the locally stored trust information (in the client).
- The libPKIX relies on caller to supply trust anchor information for a particular chain validation. The new API to libPKIX will provide a call back functionality that should be used by caller to supply arbitrary trust anchors.
Performance Comparison
- Comparison was made between NSS current certificate verification (CERT_VerifyCertificate) and libPKIX (PKIX_BuildChain) functions with the following conditions:
- Machine: amd 2 core opteron with Linux 2.6.16
- Chain contains three certificate. Leaf cert -> enterm CA -> trusted CA installed into the certificate db.
- if lib ckbi is installed then nss will try to find a proper trust anchor among 106 trusted CA certs.
- caches are primed with prior cert chain verification.
- measurement is taken for 1000 tries.
- Results:
- (with lib ckbi is installed)
- libpkix: 720 microsec | nss code: 980 microsec
- (without lib ckbi is installed)
- libpkix: 540 microsec | nss code: 840 microsec
- Certificate traversal time for 106 certs with ckbi installed is around 2600 microseconds.
- (with lib ckbi is installed)
Identified Tasks for the First Release
- The libPKIX development branch contains changes to existing NSS source files. These have not yet landed on NSS trunk. TODO:
- Tracker bug to land the diff: bug 358785
- The existing NSS functions that are now exported (in order to be accessible by libPKIX) must have their names changed to follow the style.
- Review the patch and check it in.
- Alexei is working on this item. Work in progress.
- Get initial figures for libPKIX performance.
- Compare chain building and validation performance of old NSS API with new libPKIX API.
- This task is done(see results in "LibPKIX performance section).
- Get performance numbers for the building and validation of a chain that includes certs with policy extensions and cross-certification.
- Work in progress... Looking for such cert chain.
- Compare chain building and validation performance of old NSS API with new libPKIX API.
- Ensure consistency of verification decisions across all existing and new certificate verification functions, in particular:
- add new verification function(s) that offers libPKIX parameters in its API.
- The internals of the implementation of the function are written. Finalizing API design. For more information see bug 294531
- keep all existing verification API, but change their implementation to call libPKIX functions
- The following is the list of functions that form the NSS chain building/validation API, which potentially will be modified:
- Cert chain build functions:
- CERT_CertChainFromCert
- CERT_GetCertChainFromCert
- Cert chain validation functions:
- CERT_VerifyCert
- CERT_VerifyCertChain
- CERT_VerifyCertificate
- CERT_VerifyCertificateNow
- CERT_VerifyCertNow
- CERT_VerifyCACertForUsage
- Cert chain build functions:
- The following is the list of functions that form the NSS chain building/validation API, which potentially will be modified:
- Provide functionality to switch from the original NSS certificate chain validation implementation to the libPKIX implementation and back.
- Implement Cert validity time and cert subject name overrides. These overrides make possible to skip certificate time and subject validation based on users blessing.
- This is founded on the difference between the current cert validation implementation and the one in libPKIX.
- But as Nelson mentioned that it may not be used anymore. Need to be verified
- Alexei will start working on it after new API is finalized.
- add new verification function(s) that offers libPKIX parameters in its API.
- Enhance certutil to support policy extensions and generate a CSR without regenerating a public key(reuse already generated public key).
- Resolve code duplication in libPKIX.
- Some NSS code was copied into the libPKIX source during the course of development. This was done to avoid delay of libPKIX development interruption related to the patch review process.
- If this duplication can not be resolved, then the code in question should at least be brought up to date.
- Merge patch related to CRL Distribution Point certificate extension, as well as CRL Issuing Distribution Point CRL extension.
- Depends on the agreement with Entrust. Still pending...
- Enhancement to softoken:
- to support issuing distribution point CRLs (IDP).
- to support delta CRLs.
- NSPR enhancement is needed in order to support related sockets. Bug 234130
- NSS internal libraries such as libSSL and libSMIME that utilize NSS chain building and validation features will need to be modified in order to leverage new functionalities provided by libPKIX. These changes are related to propagating policy parameters for certificate chain building/validation API from user application to NSS libraries and back. There are also open questions regarding changes in chain building process(See "Open Questions" 1-3) answers to that will result in NSS libraries modifications.(See bug 324867 for a particular change that libSSL will require)
- After all of above items are done, we will not be able to say that libPKIX NSS is fully integrated in NSS. There are number of features that PKIX/NSS/NSPR still lacks. Here is the list of bugs: pkix bug list
- Bugs/features need to be reviewed and the target release should be assign for the ones that will hold 3.12 release.
- Fix bugs that have 3.12 as the target release.
- NSS tools must also be modified to to be able to use new API.
- Tests and QA
- Here is the set of goals that we need to achieve, listed in priority order:
- Combine PKIX test programs into a smaller number of programs and compile them statically. This will reduce the amount of memory each program takes and will allow us not to export (unnecessarily) private libPKIX functions.
- Get performance numbers for libPKIX cert chain validation. -- Done.
- Verify libPKIX certificate chain validation compatibility with NSS. This task will requires to possess very wide set of, preferably life, certificates. One way to obtain them is to use search engine to find variety of websites that can provide us site certificates and certificate chains.
- Here is the set of goals that we need to achieve, listed in priority order:
- As an example of a certificate-searching scenario we can use wget to submit query to a search website to get all possible sites that have words "bank", "account", "mortgage". After parsing the results we can use wget to try to get certificate associated with these sites.
- Verify libPKIX certificate chain building compatibility with NSS. Same certificates that were used to check verifying compatibility can be used to for this task.
- Extended validation functionality testing provided by PKIX. This testing task includes checking validation based on policies and various certificate policy extensions. The current set of tests will be enough to verify that the libPKIX works correctly. But these tests will be modified to be launched using new NSS certificate chain validation API.
Identified Tasks for the Next Release
- Allow user of a new API to validate cert based on Key usage. The current implementation of the NSS validation function allows a cert to be chosen by CERTCertificateUsage, but not by usage of the key contained in the certificate. As a result, the user cannot ask to validate a cert that was issued to be used as an ssl certificate, but can only be used for signing.
- Implement an option that will turn on OCSP cert verification for leaf cert or a whole chain. Sometimes users prefer to limit the cert chain verification time. One of the ways to achieve this is by limiting network I/O by switching off OCSP cert verification for non-leaf certificates.
- NIST cert validation policy. There are a couple of differences in how NIST treats the presence of a CRL, compared to NSS (for more info see [bug 233806) :
- if an issuer CRL is not present, this is considered an error (cert revoked).
- if a CRL has a nextUpdate that is before the date against which a certificate is being verified, this is considered an error.
- Define and implement an API that will abort chain building/validation upon user request.
- HTTPS over SSL. See bug 205436
- Dynamically defined slop time. Sloptime is currently defined as global value (set by default to 24h) that nss library functions use to adjust cert validity time. libPKIX code will require some modification to allow sloptime to be set by cert chain validation function.
- Proxy support. The current implementation of HTTP and ldap clients requires direct connection to servers.