| Index: net/base/x509_certificate.h
|
| diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h
|
| index 8a1608806826d8afbefce822a8375cd21e555be7..d8621104bfba4daf0094c6211967b89a036428ba 100644
|
| --- a/net/base/x509_certificate.h
|
| +++ b/net/base/x509_certificate.h
|
| @@ -28,7 +28,7 @@
|
| #include "base/synchronization/lock.h"
|
| #elif defined(USE_OPENSSL)
|
| // Forward declaration; real one in <x509.h>
|
| -struct x509_st;
|
| +typedef struct x509_st X509;
|
| typedef struct x509_store_st X509_STORE;
|
| #elif defined(USE_NSS)
|
| // Forward declaration; real one in <cert.h>
|
| @@ -56,15 +56,15 @@ typedef std::vector<scoped_refptr<X509Certificate> > CertificateList;
|
| class NET_EXPORT X509Certificate
|
| : public base::RefCountedThreadSafe<X509Certificate> {
|
| public:
|
| - // A handle to the certificate object in the underlying crypto library.
|
| - // We assume that OSCertHandle is a pointer type on all platforms and
|
| - // NULL is an invalid OSCertHandle.
|
| + // An OSCertHandle is a handle to a certificate object in the underlying
|
| + // crypto library. We assume that OSCertHandle is a pointer type on all
|
| + // platforms and that NULL represents an invalid OSCertHandle.
|
| #if defined(OS_WIN)
|
| typedef PCCERT_CONTEXT OSCertHandle;
|
| #elif defined(OS_MACOSX)
|
| typedef SecCertificateRef OSCertHandle;
|
| #elif defined(USE_OPENSSL)
|
| - typedef struct x509_st* OSCertHandle;
|
| + typedef X509* OSCertHandle;
|
| #elif defined(USE_NSS)
|
| typedef struct CERTCertificateStr* OSCertHandle;
|
| #else
|
| @@ -288,6 +288,13 @@ class NET_EXPORT X509Certificate
|
|
|
| // Creates the chain of certs to use for this client identity cert.
|
| CFArrayRef CreateClientCertificateChain() const;
|
| +
|
| + // Returns a new CFArrayRef containing this certificate and its intermediate
|
| + // certificates in the form expected by Security.framework and Keychain
|
| + // Services, or NULL on failure.
|
| + // The first item in the array will be this certificate, followed by its
|
| + // intermediates, if any.
|
| + CFArrayRef CreateOSCertChainForCert() const;
|
| #endif
|
|
|
| #if defined(OS_WIN)
|
| @@ -299,6 +306,52 @@ class NET_EXPORT X509Certificate
|
| // this store so that we can close the system store when we finish
|
| // searching for client certificates.
|
| static HCERTSTORE cert_store();
|
| +
|
| + // Returns a new PCCERT_CONTEXT containing this certificate and its
|
| + // intermediate certificates, or NULL on failure. The returned
|
| + // PCCERT_CONTEXT *MUST NOT* be stored in an X509Certificate, as then
|
| + // os_cert_handle() will not return the correct result. This function is
|
| + // only necessary if the CERT_CONTEXT.hCertStore member will be accessed or
|
| + // enumerated, which is generally true for any CryptoAPI functions involving
|
| + // certificate chains, including validation or certificate display.
|
| + //
|
| + // Remarks:
|
| + // Depending on the CryptoAPI function, Windows may need to access the
|
| + // HCERTSTORE that the passed-in PCCERT_CONTEXT belongs to, such as to
|
| + // locate additional intermediates. However, in the current X509Certificate
|
| + // implementation on Windows, all X509Certificate::OSCertHandles belong to
|
| + // the same HCERTSTORE - X509Certificate::cert_store(). Since certificates
|
| + // may be created and accessed on any number of threads, if CryptoAPI is
|
| + // trying to read this global store while additional certificates are being
|
| + // added, it may return inconsistent results while enumerating the store.
|
| + // While the memory accesses themselves are thread-safe, the resultant view
|
| + // of what is in the store may be altered.
|
| + //
|
| + // If OSCertHandles were instead added to a NULL HCERTSTORE, which is valid
|
| + // in CryptoAPI, then Windows would be unable to locate any of the
|
| + // intermediates supplied in |intermediate_ca_certs_|, because the
|
| + // hCertStore will refer to a magic value that indicates "only this
|
| + // certificate."
|
| + //
|
| + // To avoid these problems, a new in-memory HCERTSTORE is created containing
|
| + // just this certificate and its intermediates. The handle to the version of
|
| + // this certificate in the new HCERTSTORE is then returned, with the
|
| + // HCERTSTORE set to be automatically freed when the returned certificate
|
| + // is freed.
|
| + //
|
| + // This function is only needed when the HCERTSTORE of the os_cert_handle()
|
| + // will be accessed, which is generally only during certificate validation
|
| + // or display. While the returned PCCERT_CONTEXT and its HCERTSTORE can
|
| + // safely be used on multiple threads if no further modifications happen, it
|
| + // is generally preferable for each thread that needs such a context to
|
| + // obtain its own, rather than risk thread-safety issues by sharing.
|
| + //
|
| + // Because of how X509Certificate caching is implemented, attempting to
|
| + // create an X509Certificate from the returned PCCERT_CONTEXT may result in
|
| + // the original handle (and thus the originall HCERTSTORE) being returned by
|
| + // os_cert_handle(). For this reason, the returned PCCERT_CONTEXT *MUST NOT*
|
| + // be stored in an X509Certificate.
|
| + PCCERT_CONTEXT CreateOSCertChainForCert() const;
|
| #endif
|
|
|
| #if defined(OS_ANDROID)
|
| @@ -345,6 +398,11 @@ class NET_EXPORT X509Certificate
|
| // The content of the DER encoded certificate is written to |encoded|.
|
| bool GetDEREncoded(std::string* encoded);
|
|
|
| + // Returns the OSCertHandle of this object. Because of caching, this may
|
| + // differ from the OSCertHandle originally supplied during initialization.
|
| + // Note: On Windows, CryptoAPI may return unexpected results if this handle
|
| + // is used across multiple threads. For more details, see
|
| + // CreateOSCertChainForCert().
|
| OSCertHandle os_cert_handle() const { return cert_handle_; }
|
|
|
| // Returns true if two OSCertHandles refer to identical certificates.
|
|
|