Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 // Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
     12 
     13 #ifndef WEBRTC_BASE_SSLIDENTITY_H_
     14 #define WEBRTC_BASE_SSLIDENTITY_H_
     15 
     16 #include <algorithm>
     17 #include <string>
     18 #include <vector>
     19 
     20 #include "webrtc/base/buffer.h"
     21 #include "webrtc/base/messagedigest.h"
     22 #include "webrtc/base/timeutils.h"
     23 
     24 namespace rtc {
     25 
     26 // Forward declaration due to circular dependency with SSLCertificate.
     27 class SSLCertChain;
     28 
     29 // Abstract interface overridden by SSL library specific
     30 // implementations.
     31 
     32 // A somewhat opaque type used to encapsulate a certificate.
     33 // Wraps the SSL library's notion of a certificate, with reference counting.
     34 // The SSLCertificate object is pretty much immutable once created.
     35 // (The OpenSSL implementation only does reference counting and
     36 // possibly caching of intermediate results.)
     37 class SSLCertificate {
     38  public:
     39   // Parses and build a certificate from a PEM encoded string.
     40   // Returns NULL on failure.
     41   // The length of the string representation of the certificate is
     42   // stored in *pem_length if it is non-NULL, and only if
     43   // parsing was successful.
     44   // Caller is responsible for freeing the returned object.
     45   static SSLCertificate* FromPEMString(const std::string& pem_string);
     46   virtual ~SSLCertificate() {}
     47 
     48   // Returns a new SSLCertificate object instance wrapping the same
     49   // underlying certificate, including its chain if present.
     50   // Caller is responsible for freeing the returned object.
     51   virtual SSLCertificate* GetReference() const = 0;
     52 
     53   // Provides the cert chain, or returns false.  The caller owns the chain.
     54   // The chain includes a copy of each certificate, excluding the leaf.
     55   virtual bool GetChain(SSLCertChain** chain) const = 0;
     56 
     57   // Returns a PEM encoded string representation of the certificate.
     58   virtual std::string ToPEMString() const = 0;
     59 
     60   // Provides a DER encoded binary representation of the certificate.
     61   virtual void ToDER(Buffer* der_buffer) const = 0;
     62 
     63   // Gets the name of the digest algorithm that was used to compute this
     64   // certificate's signature.
     65   virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const = 0;
     66 
     67   // Compute the digest of the certificate given algorithm
     68   virtual bool ComputeDigest(const std::string& algorithm,
     69                              unsigned char* digest,
     70                              size_t size,
     71                              size_t* length) const = 0;
     72 
     73   // Returns the time in seconds relative to epoch, 1970-01-01T00:00:00Z (UTC),
     74   // or -1 if an expiration time could not be retrieved.
     75   virtual int64_t CertificateExpirationTime() const = 0;
     76 };
     77 
     78 // SSLCertChain is a simple wrapper for a vector of SSLCertificates. It serves
     79 // primarily to ensure proper memory management (especially deletion) of the
     80 // SSLCertificate pointers.
     81 class SSLCertChain {
     82  public:
     83   // These constructors copy the provided SSLCertificate(s), so the caller
     84   // retains ownership.
     85   explicit SSLCertChain(const std::vector<SSLCertificate*>& certs);
     86   explicit SSLCertChain(const SSLCertificate* cert);
     87   ~SSLCertChain();
     88 
     89   // Vector access methods.
     90   size_t GetSize() const { return certs_.size(); }
     91 
     92   // Returns a temporary reference, only valid until the chain is destroyed.
     93   const SSLCertificate& Get(size_t pos) const { return *(certs_[pos]); }
     94 
     95   // Returns a new SSLCertChain object instance wrapping the same underlying
     96   // certificate chain.  Caller is responsible for freeing the returned object.
     97   SSLCertChain* Copy() const {
     98     return new SSLCertChain(certs_);
     99   }
    100 
    101  private:
    102   // Helper function for duplicating a vector of certificates.
    103   static SSLCertificate* DupCert(const SSLCertificate* cert) {
    104     return cert->GetReference();
    105   }
    106 
    107   // Helper function for deleting a vector of certificates.
    108   static void DeleteCert(SSLCertificate* cert) { delete cert; }
    109 
    110   std::vector<SSLCertificate*> certs_;
    111 
    112   RTC_DISALLOW_COPY_AND_ASSIGN(SSLCertChain);
    113 };
    114 
    115 // KT_DEFAULT is currently an alias for KT_RSA.  This is likely to change.
    116 // KT_LAST is intended for vector declarations and loops over all key types;
    117 // it does not represent any key type in itself.
    118 // TODO(hbos,torbjorng): Don't change KT_DEFAULT without first updating
    119 // PeerConnectionFactory_nativeCreatePeerConnection's certificate generation
    120 // code.
    121 enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_RSA };
    122 
    123 static const int kRsaDefaultModSize = 1024;
    124 static const int kRsaDefaultExponent = 0x10001;  // = 2^16+1 = 65537
    125 static const int kRsaMinModSize = 1024;
    126 static const int kRsaMaxModSize = 8192;
    127 
    128 struct RSAParams {
    129   unsigned int mod_size;
    130   unsigned int pub_exp;
    131 };
    132 
    133 enum ECCurve { EC_NIST_P256, /* EC_FANCY, */ EC_LAST };
    134 
    135 class KeyParams {
    136  public:
    137   // Generate a KeyParams object from a simple KeyType, using default params.
    138   explicit KeyParams(KeyType key_type = KT_DEFAULT);
    139 
    140   // Generate a a KeyParams for RSA with explicit parameters.
    141   static KeyParams RSA(int mod_size = kRsaDefaultModSize,
    142                        int pub_exp = kRsaDefaultExponent);
    143 
    144   // Generate a a KeyParams for ECDSA specifying the curve.
    145   static KeyParams ECDSA(ECCurve curve = EC_NIST_P256);
    146 
    147   // Check validity of a KeyParams object. Since the factory functions have
    148   // no way of returning errors, this function can be called after creation
    149   // to make sure the parameters are OK.
    150   bool IsValid() const;
    151 
    152   RSAParams rsa_params() const;
    153 
    154   ECCurve ec_curve() const;
    155 
    156   KeyType type() const { return type_; }
    157 
    158  private:
    159   KeyType type_;
    160   union {
    161     RSAParams rsa;
    162     ECCurve curve;
    163   } params_;
    164 };
    165 
    166 // TODO(hbos): Remove once rtc::KeyType (to be modified) and
    167 // blink::WebRTCKeyType (to be landed) match. By using this function in Chromium
    168 // appropriately we can change KeyType enum -> class without breaking Chromium.
    169 KeyType IntKeyTypeFamilyToKeyType(int key_type_family);
    170 
    171 // Parameters for generating a certificate. If |common_name| is non-empty, it
    172 // will be used for the certificate's subject and issuer name, otherwise a
    173 // random string will be used.
    174 struct SSLIdentityParams {
    175   std::string common_name;
    176   time_t not_before;  // Absolute time since epoch in seconds.
    177   time_t not_after;   // Absolute time since epoch in seconds.
    178   KeyParams key_params;
    179 };
    180 
    181 // Our identity in an SSL negotiation: a keypair and certificate (both
    182 // with the same public key).
    183 // This too is pretty much immutable once created.
    184 class SSLIdentity {
    185  public:
    186   // Generates an identity (keypair and self-signed certificate). If
    187   // common_name is non-empty, it will be used for the certificate's
    188   // subject and issuer name, otherwise a random string will be used.
    189   // Returns NULL on failure.
    190   // Caller is responsible for freeing the returned object.
    191   static SSLIdentity* Generate(const std::string& common_name,
    192                                const KeyParams& key_param);
    193   static SSLIdentity* Generate(const std::string& common_name,
    194                                KeyType key_type) {
    195     return Generate(common_name, KeyParams(key_type));
    196   }
    197 
    198   // Generates an identity with the specified validity period.
    199   static SSLIdentity* GenerateForTest(const SSLIdentityParams& params);
    200 
    201   // Construct an identity from a private key and a certificate.
    202   static SSLIdentity* FromPEMStrings(const std::string& private_key,
    203                                      const std::string& certificate);
    204 
    205   virtual ~SSLIdentity() {}
    206 
    207   // Returns a new SSLIdentity object instance wrapping the same
    208   // identity information.
    209   // Caller is responsible for freeing the returned object.
    210   // TODO(hbos,torbjorng): Rename to a less confusing name.
    211   virtual SSLIdentity* GetReference() const = 0;
    212 
    213   // Returns a temporary reference to the certificate.
    214   virtual const SSLCertificate& certificate() const = 0;
    215 
    216   // Helpers for parsing converting between PEM and DER format.
    217   static bool PemToDer(const std::string& pem_type,
    218                        const std::string& pem_string,
    219                        std::string* der);
    220   static std::string DerToPem(const std::string& pem_type,
    221                               const unsigned char* data,
    222                               size_t length);
    223 };
    224 
    225 // Convert from ASN1 time as restricted by RFC 5280 to seconds from 1970-01-01
    226 // 00.00 ("epoch").  If the ASN1 time cannot be read, return -1.  The data at
    227 // |s| is not 0-terminated; its char count is defined by |length|.
    228 int64_t ASN1TimeToSec(const unsigned char* s, size_t length, bool long_format);
    229 
    230 extern const char kPemTypeCertificate[];
    231 extern const char kPemTypeRsaPrivateKey[];
    232 extern const char kPemTypeEcPrivateKey[];
    233 
    234 }  // namespace rtc
    235 
    236 #endif  // WEBRTC_BASE_SSLIDENTITY_H_
    237