1 /* 2 * libjingle 3 * Copyright 2004--2008, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_BASE_OPENSSLSTREAMADAPTER_H__ 29 #define TALK_BASE_OPENSSLSTREAMADAPTER_H__ 30 31 #include <string> 32 #include <vector> 33 34 #include "talk/base/buffer.h" 35 #include "talk/base/sslstreamadapter.h" 36 #include "talk/base/opensslidentity.h" 37 38 typedef struct ssl_st SSL; 39 typedef struct ssl_ctx_st SSL_CTX; 40 typedef struct x509_store_ctx_st X509_STORE_CTX; 41 42 namespace talk_base { 43 44 // This class was written with OpenSSLAdapter (a socket adapter) as a 45 // starting point. It has similar structure and functionality, with 46 // the peer-to-peer mode added. 47 // 48 // Static methods to initialize and deinit the SSL library are in 49 // OpenSSLAdapter. This class also uses 50 // OpenSSLAdapter::custom_verify_callback_ (a static field). These 51 // should probably be moved out to a neutral class. 52 // 53 // In a few cases I have factored out some OpenSSLAdapter code into 54 // static methods so it can be reused from this class. Eventually that 55 // code should probably be moved to a common support 56 // class. Unfortunately there remain a few duplicated sections of 57 // code. I have not done more restructuring because I did not want to 58 // affect existing code that uses OpenSSLAdapter. 59 // 60 // This class does not support the SSL connection restart feature 61 // present in OpenSSLAdapter. I am not entirely sure how the feature 62 // is useful and I am not convinced that it works properly. 63 // 64 // This implementation is careful to disallow data exchange after an 65 // SSL error, and it has an explicit SSL_CLOSED state. It should not 66 // be possible to send any data in clear after one of the StartSSL 67 // methods has been called. 68 69 // Look in sslstreamadapter.h for documentation of the methods. 70 71 class OpenSSLIdentity; 72 73 /////////////////////////////////////////////////////////////////////////////// 74 75 class OpenSSLStreamAdapter : public SSLStreamAdapter { 76 public: 77 explicit OpenSSLStreamAdapter(StreamInterface* stream); 78 virtual ~OpenSSLStreamAdapter(); 79 80 virtual void SetIdentity(SSLIdentity* identity); 81 82 // Default argument is for compatibility 83 virtual void SetServerRole(SSLRole role = SSL_SERVER); 84 virtual void SetPeerCertificate(SSLCertificate* cert); 85 virtual bool SetPeerCertificateDigest(const std::string& digest_alg, 86 const unsigned char* digest_val, 87 size_t digest_len); 88 89 virtual bool GetPeerCertificate(SSLCertificate** cert) const; 90 91 virtual int StartSSLWithServer(const char* server_name); 92 virtual int StartSSLWithPeer(); 93 virtual void SetMode(SSLMode mode); 94 95 virtual StreamResult Read(void* data, size_t data_len, 96 size_t* read, int* error); 97 virtual StreamResult Write(const void* data, size_t data_len, 98 size_t* written, int* error); 99 virtual void Close(); 100 virtual StreamState GetState() const; 101 102 // Key Extractor interface 103 virtual bool ExportKeyingMaterial(const std::string& label, 104 const uint8* context, 105 size_t context_len, 106 bool use_context, 107 uint8* result, 108 size_t result_len); 109 110 111 // DTLS-SRTP interface 112 virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers); 113 virtual bool GetDtlsSrtpCipher(std::string* cipher); 114 115 // Capabilities interfaces 116 static bool HaveDtls(); 117 static bool HaveDtlsSrtp(); 118 static bool HaveExporter(); 119 120 protected: 121 virtual void OnEvent(StreamInterface* stream, int events, int err); 122 123 private: 124 enum SSLState { 125 // Before calling one of the StartSSL methods, data flows 126 // in clear text. 127 SSL_NONE, 128 SSL_WAIT, // waiting for the stream to open to start SSL negotiation 129 SSL_CONNECTING, // SSL negotiation in progress 130 SSL_CONNECTED, // SSL stream successfully established 131 SSL_ERROR, // some SSL error occurred, stream is closed 132 SSL_CLOSED // Clean close 133 }; 134 135 enum { MSG_TIMEOUT = MSG_MAX+1}; 136 137 // The following three methods return 0 on success and a negative 138 // error code on failure. The error code may be from OpenSSL or -1 139 // on some other error cases, so it can't really be interpreted 140 // unfortunately. 141 142 // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, 143 // depending on whether the underlying stream is already open or 144 // not. 145 int StartSSL(); 146 // Prepare SSL library, state is SSL_CONNECTING. 147 int BeginSSL(); 148 // Perform SSL negotiation steps. 149 int ContinueSSL(); 150 151 // Error handler helper. signal is given as true for errors in 152 // asynchronous contexts (when an error method was not returned 153 // through some other method), and in that case an SE_CLOSE event is 154 // raised on the stream with the specified error. 155 // A 0 error means a graceful close, otherwise there is not really enough 156 // context to interpret the error code. 157 void Error(const char* context, int err, bool signal); 158 void Cleanup(); 159 160 // Override MessageHandler 161 virtual void OnMessage(Message* msg); 162 163 // Flush the input buffers by reading left bytes (for DTLS) 164 void FlushInput(unsigned int left); 165 166 // SSL library configuration 167 SSL_CTX* SetupSSLContext(); 168 // SSL verification check 169 bool SSLPostConnectionCheck(SSL* ssl, const char* server_name, 170 const X509* peer_cert, 171 const std::string& peer_digest); 172 // SSL certification verification error handler, called back from 173 // the openssl library. Returns an int interpreted as a boolean in 174 // the C style: zero means verification failure, non-zero means 175 // passed. 176 static int SSLVerifyCallback(int ok, X509_STORE_CTX* store); 177 178 179 SSLState state_; 180 SSLRole role_; 181 int ssl_error_code_; // valid when state_ == SSL_ERROR or SSL_CLOSED 182 // Whether the SSL negotiation is blocked on needing to read or 183 // write to the wrapped stream. 184 bool ssl_read_needs_write_; 185 bool ssl_write_needs_read_; 186 187 SSL* ssl_; 188 SSL_CTX* ssl_ctx_; 189 190 // Our key and certificate, mostly useful in peer-to-peer mode. 191 scoped_ptr<OpenSSLIdentity> identity_; 192 // in traditional mode, the server name that the server's certificate 193 // must specify. Empty in peer-to-peer mode. 194 std::string ssl_server_name_; 195 // The certificate that the peer must present or did present. Initially 196 // null in traditional mode, until the connection is established. 197 scoped_ptr<OpenSSLCertificate> peer_certificate_; 198 // In peer-to-peer mode, the digest of the certificate that 199 // the peer must present. 200 Buffer peer_certificate_digest_value_; 201 std::string peer_certificate_digest_algorithm_; 202 203 // OpenSSLAdapter::custom_verify_callback_ result 204 bool custom_verification_succeeded_; 205 206 // The DtlsSrtp ciphers 207 std::string srtp_ciphers_; 208 209 // Do DTLS or not 210 SSLMode ssl_mode_; 211 }; 212 213 ///////////////////////////////////////////////////////////////////////////// 214 215 } // namespace talk_base 216 217 #endif // TALK_BASE_OPENSSLSTREAMADAPTER_H__ 218