Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_BASE_X509_CERTIFICATE_H_
      6 #define NET_BASE_X509_CERTIFICATE_H_
      7 
      8 #include <string.h>
      9 
     10 #include <map>
     11 #include <set>
     12 #include <string>
     13 #include <vector>
     14 
     15 #include "base/ref_counted.h"
     16 #include "base/singleton.h"
     17 #include "base/time.h"
     18 #include "testing/gtest/include/gtest/gtest_prod.h"
     19 
     20 #if defined(OS_WIN)
     21 #include <windows.h>
     22 #include <wincrypt.h>
     23 #elif defined(OS_MACOSX)
     24 #include <Security/Security.h>
     25 #elif defined(USE_NSS)
     26 // Forward declaration; real one in <cert.h>
     27 struct CERTCertificateStr;
     28 #endif
     29 
     30 class Pickle;
     31 
     32 namespace net {
     33 
     34 class CertVerifyResult;
     35 
     36 // X509Certificate represents an X.509 certificate used by SSL.
     37 class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> {
     38  public:
     39   // SHA-1 fingerprint (160 bits) of a certificate.
     40   struct Fingerprint {
     41     bool Equals(const Fingerprint& other) const {
     42       return memcmp(data, other.data, sizeof(data)) == 0;
     43     }
     44 
     45     unsigned char data[20];
     46   };
     47 
     48   class FingerprintLessThan
     49       : public std::binary_function<Fingerprint, Fingerprint, bool> {
     50    public:
     51     bool operator() (const Fingerprint& lhs, const Fingerprint& rhs) const;
     52   };
     53 
     54   // Predicate functor used in maps when X509Certificate is used as the key.
     55   class LessThan
     56       : public std::binary_function<X509Certificate*, X509Certificate*, bool> {
     57    public:
     58     bool operator() (X509Certificate* lhs,  X509Certificate* rhs) const;
     59   };
     60 
     61   // A handle to the certificate object in the underlying crypto library.
     62   // We assume that OSCertHandle is a pointer type on all platforms and
     63   // NULL is an invalid OSCertHandle.
     64 #if defined(OS_WIN)
     65   typedef PCCERT_CONTEXT OSCertHandle;
     66 #elif defined(OS_MACOSX)
     67   typedef SecCertificateRef OSCertHandle;
     68 #elif defined(USE_NSS)
     69   typedef struct CERTCertificateStr* OSCertHandle;
     70 #else
     71   // TODO(ericroman): not implemented
     72   typedef void* OSCertHandle;
     73 #endif
     74 
     75   // Principal represent an X.509 principal.
     76   struct Principal {
     77     Principal() { }
     78     explicit Principal(const std::string& name) : common_name(name) { }
     79 
     80     // The different attributes for a principal.  They may be "".
     81     // Note that some of them can have several values.
     82 
     83     std::string common_name;
     84     std::string locality_name;
     85     std::string state_or_province_name;
     86     std::string country_name;
     87 
     88     std::vector<std::string> street_addresses;
     89     std::vector<std::string> organization_names;
     90     std::vector<std::string> organization_unit_names;
     91     std::vector<std::string> domain_components;
     92   };
     93 
     94   // This class is useful for maintaining policies about which certificates are
     95   // permitted or forbidden for a particular purpose.
     96   class Policy {
     97    public:
     98     // The judgments this policy can reach.
     99     enum Judgment {
    100       // We don't have policy information for this certificate.
    101       UNKNOWN,
    102 
    103       // This certificate is allowed.
    104       ALLOWED,
    105 
    106       // This certificate is denied.
    107       DENIED,
    108     };
    109 
    110     // Returns the judgment this policy makes about this certificate.
    111     Judgment Check(X509Certificate* cert) const;
    112 
    113     // Causes the policy to allow this certificate.
    114     void Allow(X509Certificate* cert);
    115 
    116     // Causes the policy to deny this certificate.
    117     void Deny(X509Certificate* cert);
    118 
    119     // Returns true if this policy has allowed at least one certificate.
    120     bool HasAllowedCert() const;
    121 
    122     // Returns true if this policy has denied at least one certificate.
    123     bool HasDeniedCert() const;
    124 
    125    private:
    126     // The set of fingerprints of allowed certificates.
    127     std::set<Fingerprint, FingerprintLessThan> allowed_;
    128 
    129     // The set of fingerprints of denied certificates.
    130     std::set<Fingerprint, FingerprintLessThan> denied_;
    131   };
    132 
    133   // Where the certificate comes from.  The enumeration constants are
    134   // listed in increasing order of preference.
    135   enum Source {
    136     SOURCE_UNUSED = 0,            // The source_ member is not used.
    137     SOURCE_LONE_CERT_IMPORT = 1,  // From importing a certificate without
    138                                   // its intermediate CA certificates.
    139     SOURCE_FROM_NETWORK = 2,      // From the network.
    140   };
    141 
    142   enum VerifyFlags {
    143     VERIFY_REV_CHECKING_ENABLED = 1 << 0,
    144     VERIFY_EV_CERT = 1 << 1,
    145   };
    146 
    147   // Create an X509Certificate from a handle to the certificate object
    148   // in the underlying crypto library. This is a transfer of ownership;
    149   // X509Certificate will properly dispose of |cert_handle| for you.
    150   // |source| specifies where |cert_handle| comes from.  Given two
    151   // certificate handles for the same certificate, our certificate cache
    152   // prefers the handle from the network because our HTTP cache isn't
    153   // caching the corresponding intermediate CA certificates yet
    154   // (http://crbug.com/7065).
    155   //
    156   // The returned pointer must be stored in a scoped_refptr<X509Certificate>.
    157   static X509Certificate* CreateFromHandle(OSCertHandle cert_handle,
    158                                            Source source);
    159 
    160   // Create an X509Certificate from the BER-encoded representation.
    161   // Returns NULL on failure.
    162   //
    163   // The returned pointer must be stored in a scoped_refptr<X509Certificate>.
    164   static X509Certificate* CreateFromBytes(const char* data, int length);
    165 
    166   // Create an X509Certificate from the representation stored in the given
    167   // pickle.  The data for this object is found relative to the given
    168   // pickle_iter, which should be passed to the pickle's various Read* methods.
    169   // Returns NULL on failure.
    170   //
    171   // The returned pointer must be stored in a scoped_refptr<X509Certificate>.
    172   static X509Certificate* CreateFromPickle(const Pickle& pickle,
    173                                            void** pickle_iter);
    174 
    175   // Creates a X509Certificate from the ground up.  Used by tests that simulate
    176   // SSL connections.
    177   X509Certificate(const std::string& subject, const std::string& issuer,
    178                   base::Time start_date, base::Time expiration_date);
    179 
    180   // Appends a representation of this object to the given pickle.
    181   void Persist(Pickle* pickle);
    182 
    183   // The subject of the certificate.  For HTTPS server certificates, this
    184   // represents the web server.  The common name of the subject should match
    185   // the host name of the web server.
    186   const Principal& subject() const { return subject_; }
    187 
    188   // The issuer of the certificate.
    189   const Principal& issuer() const { return issuer_; }
    190 
    191   // Time period during which the certificate is valid.  More precisely, this
    192   // certificate is invalid before the |valid_start| date and invalid after
    193   // the |valid_expiry| date.
    194   // If we were unable to parse either date from the certificate (or if the cert
    195   // lacks either date), the date will be null (i.e., is_null() will be true).
    196   const base::Time& valid_start() const { return valid_start_; }
    197   const base::Time& valid_expiry() const { return valid_expiry_; }
    198 
    199   // The fingerprint of this certificate.
    200   const Fingerprint& fingerprint() const { return fingerprint_; }
    201 
    202   // Gets the DNS names in the certificate.  Pursuant to RFC 2818, Section 3.1
    203   // Server Identity, if the certificate has a subjectAltName extension of
    204   // type dNSName, this method gets the DNS names in that extension.
    205   // Otherwise, it gets the common name in the subject field.
    206   void GetDNSNames(std::vector<std::string>* dns_names) const;
    207 
    208   // Convenience method that returns whether this certificate has expired as of
    209   // now.
    210   bool HasExpired() const;
    211 
    212 #if defined(OS_MACOSX) || defined(OS_WIN)
    213   // Adds an untrusted intermediate certificate that may be needed for
    214   // chain building.
    215   void AddIntermediateCertificate(OSCertHandle cert) {
    216     intermediate_ca_certs_.push_back(cert);
    217   }
    218 
    219   // Returns intermediate certificates added via AddIntermediateCertificate().
    220   // Ownership follows the "get" rule: it is the caller's responsibility to
    221   // retain the elements of the result.
    222   const std::vector<OSCertHandle>& GetIntermediateCertificates() const {
    223     return intermediate_ca_certs_;
    224   }
    225 #endif
    226 
    227   // Verifies the certificate against the given hostname.  Returns OK if
    228   // successful or an error code upon failure.
    229   //
    230   // The |*verify_result| structure, including the |verify_result->cert_status|
    231   // bitmask, is always filled out regardless of the return value.  If the
    232   // certificate has multiple errors, the corresponding status flags are set in
    233   // |verify_result->cert_status|, and the error code for the most serious
    234   // error is returned.
    235   //
    236   // |flags| is bitwise OR'd of VerifyFlags.
    237   // If VERIFY_REV_CHECKING_ENABLED is set in |flags|, certificate revocation
    238   // checking is performed.  If VERIFY_EV_CERT is set in |flags| too,
    239   // EV certificate verification is performed.
    240   int Verify(const std::string& hostname,
    241              int flags,
    242              CertVerifyResult* verify_result) const;
    243 
    244   OSCertHandle os_cert_handle() const { return cert_handle_; }
    245 
    246  private:
    247   friend class base::RefCountedThreadSafe<X509Certificate>;
    248   FRIEND_TEST(X509CertificateTest, Cache);
    249 
    250   // A cache of X509Certificate objects.
    251   class Cache {
    252    public:
    253     static Cache* GetInstance();
    254     void Insert(X509Certificate* cert);
    255     void Remove(X509Certificate* cert);
    256     X509Certificate* Find(const Fingerprint& fingerprint);
    257 
    258    private:
    259     typedef std::map<Fingerprint, X509Certificate*, FingerprintLessThan>
    260         CertMap;
    261 
    262     // Obtain an instance of X509Certificate::Cache via GetInstance().
    263     Cache() { }
    264     friend struct DefaultSingletonTraits<Cache>;
    265 
    266     // You must acquire this lock before using any private data of this object.
    267     // You must not block while holding this lock.
    268     Lock lock_;
    269 
    270     // The certificate cache.  You must acquire |lock_| before using |cache_|.
    271     CertMap cache_;
    272 
    273     DISALLOW_COPY_AND_ASSIGN(Cache);
    274   };
    275 
    276   // Construct an X509Certificate from a handle to the certificate object
    277   // in the underlying crypto library.
    278   X509Certificate(OSCertHandle cert_handle, Source source);
    279 
    280   ~X509Certificate();
    281 
    282   // Common object initialization code.  Called by the constructors only.
    283   void Initialize();
    284 
    285   bool VerifyEV() const;
    286 
    287   // Creates an OS certificate handle from the BER-encoded representation.
    288   // Returns NULL on failure.
    289   static OSCertHandle CreateOSCertHandleFromBytes(const char* data,
    290                                                   int length);
    291 
    292   // Frees an OS certificate handle.
    293   static void FreeOSCertHandle(OSCertHandle cert_handle);
    294 
    295   // Calculates the SHA-1 fingerprint of the certificate.  Returns an empty
    296   // (all zero) fingerprint on failure.
    297   static Fingerprint CalculateFingerprint(OSCertHandle cert_handle);
    298 
    299   // The subject of the certificate.
    300   Principal subject_;
    301 
    302   // The issuer of the certificate.
    303   Principal issuer_;
    304 
    305   // This certificate is not valid before |valid_start_|
    306   base::Time valid_start_;
    307 
    308   // This certificate is not valid after |valid_expiry_|
    309   base::Time valid_expiry_;
    310 
    311   // The fingerprint of this certificate.
    312   Fingerprint fingerprint_;
    313 
    314   // A handle to the certificate object in the underlying crypto library.
    315   OSCertHandle cert_handle_;
    316 
    317 #if defined(OS_MACOSX) || defined(OS_WIN)
    318   // Untrusted intermediate certificates associated with this certificate
    319   // that may be needed for chain building.
    320   std::vector<OSCertHandle> intermediate_ca_certs_;
    321 #endif
    322 
    323   // Where the certificate comes from.
    324   Source source_;
    325 
    326   DISALLOW_COPY_AND_ASSIGN(X509Certificate);
    327 };
    328 
    329 }  // namespace net
    330 
    331 #endif  // NET_BASE_X509_CERTIFICATE_H_
    332