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 #ifndef WEBRTC_BASE_OPENSSLIDENTITY_H_
12 #define WEBRTC_BASE_OPENSSLIDENTITY_H_
13 
14 #include <openssl/evp.h>
15 #include <openssl/x509.h>
16 
17 #include <memory>
18 #include <string>
19 
20 #include "webrtc/base/checks.h"
21 #include "webrtc/base/common.h"
22 #include "webrtc/base/constructormagic.h"
23 #include "webrtc/base/sslidentity.h"
24 
25 typedef struct ssl_ctx_st SSL_CTX;
26 
27 namespace rtc {
28 
29 // OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object,
30 // which is reference counted inside the OpenSSL library.
31 class OpenSSLKeyPair {
32  public:
OpenSSLKeyPair(EVP_PKEY * pkey)33   explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) {
34     RTC_DCHECK(pkey_ != NULL);
35   }
36 
37   static OpenSSLKeyPair* Generate(const KeyParams& key_params);
38   // Constructs a key pair from the private key PEM string. This must not result
39   // in missing public key parameters. Returns null on error.
40   static OpenSSLKeyPair* FromPrivateKeyPEMString(
41       const std::string& pem_string);
42 
43   virtual ~OpenSSLKeyPair();
44 
45   virtual OpenSSLKeyPair* GetReference();
46 
pkey()47   EVP_PKEY* pkey() const { return pkey_; }
48   std::string PrivateKeyToPEMString() const;
49   std::string PublicKeyToPEMString() const;
50   bool operator==(const OpenSSLKeyPair& other) const;
51   bool operator!=(const OpenSSLKeyPair& other) const;
52 
53  private:
54   void AddReference();
55 
56   EVP_PKEY* pkey_;
57 
58   RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyPair);
59 };
60 
61 // OpenSSLCertificate encapsulates an OpenSSL X509* certificate object,
62 // which is also reference counted inside the OpenSSL library.
63 class OpenSSLCertificate : public SSLCertificate {
64  public:
65   // Caller retains ownership of the X509 object.
OpenSSLCertificate(X509 * x509)66   explicit OpenSSLCertificate(X509* x509) : x509_(x509) {
67     AddReference();
68   }
69 
70   static OpenSSLCertificate* Generate(OpenSSLKeyPair* key_pair,
71                                       const SSLIdentityParams& params);
72   static OpenSSLCertificate* FromPEMString(const std::string& pem_string);
73 
74   ~OpenSSLCertificate() override;
75 
76   OpenSSLCertificate* GetReference() const override;
77 
x509()78   X509* x509() const { return x509_; }
79 
80   std::string ToPEMString() const override;
81   void ToDER(Buffer* der_buffer) const override;
82   bool operator==(const OpenSSLCertificate& other) const;
83   bool operator!=(const OpenSSLCertificate& other) const;
84 
85   // Compute the digest of the certificate given algorithm
86   bool ComputeDigest(const std::string& algorithm,
87                      unsigned char* digest,
88                      size_t size,
89                      size_t* length) const override;
90 
91   // Compute the digest of a certificate as an X509 *
92   static bool ComputeDigest(const X509* x509,
93                             const std::string& algorithm,
94                             unsigned char* digest,
95                             size_t size,
96                             size_t* length);
97 
98   bool GetSignatureDigestAlgorithm(std::string* algorithm) const override;
99   std::unique_ptr<SSLCertChain> GetChain() const override;
100 
101   int64_t CertificateExpirationTime() const override;
102 
103  private:
104   void AddReference() const;
105 
106   X509* x509_;
107 
108   RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLCertificate);
109 };
110 
111 // Holds a keypair and certificate together, and a method to generate
112 // them consistently.
113 class OpenSSLIdentity : public SSLIdentity {
114  public:
115   static OpenSSLIdentity* GenerateWithExpiration(const std::string& common_name,
116                                                  const KeyParams& key_params,
117                                                  time_t certificate_lifetime);
118   static OpenSSLIdentity* GenerateForTest(const SSLIdentityParams& params);
119   static SSLIdentity* FromPEMStrings(const std::string& private_key,
120                                      const std::string& certificate);
121   ~OpenSSLIdentity() override;
122 
123   const OpenSSLCertificate& certificate() const override;
124   OpenSSLIdentity* GetReference() const override;
125 
126   // Configure an SSL context object to use our key and certificate.
127   bool ConfigureIdentity(SSL_CTX* ctx);
128 
129   std::string PrivateKeyToPEMString() const override;
130   std::string PublicKeyToPEMString() const override;
131   bool operator==(const OpenSSLIdentity& other) const;
132   bool operator!=(const OpenSSLIdentity& other) const;
133 
134  private:
135   OpenSSLIdentity(OpenSSLKeyPair* key_pair, OpenSSLCertificate* certificate);
136 
137   static OpenSSLIdentity* GenerateInternal(const SSLIdentityParams& params);
138 
139   std::unique_ptr<OpenSSLKeyPair> key_pair_;
140   std::unique_ptr<OpenSSLCertificate> certificate_;
141 
142   RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLIdentity);
143 };
144 
145 
146 }  // namespace rtc
147 
148 #endif  // WEBRTC_BASE_OPENSSLIDENTITY_H_
149