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 bool SetPeerCertificateDigest(const std::string& digest_alg, 85 const unsigned char* digest_val, 86 size_t digest_len); 87 88 virtual bool GetPeerCertificate(SSLCertificate** cert) const; 89 90 virtual int StartSSLWithServer(const char* server_name); 91 virtual int StartSSLWithPeer(); 92 virtual void SetMode(SSLMode mode); 93 94 virtual StreamResult Read(void* data, size_t data_len, 95 size_t* read, int* error); 96 virtual StreamResult Write(const void* data, size_t data_len, 97 size_t* written, int* error); 98 virtual void Close(); 99 virtual StreamState GetState() const; 100 101 // Key Extractor interface 102 virtual bool ExportKeyingMaterial(const std::string& label, 103 const uint8* context, 104 size_t context_len, 105 bool use_context, 106 uint8* result, 107 size_t result_len); 108 109 110 // DTLS-SRTP interface 111 virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers); 112 virtual bool GetDtlsSrtpCipher(std::string* cipher); 113 114 // Capabilities interfaces 115 static bool HaveDtls(); 116 static bool HaveDtlsSrtp(); 117 static bool HaveExporter(); 118 119 protected: 120 virtual void OnEvent(StreamInterface* stream, int events, int err); 121 122 private: 123 enum SSLState { 124 // Before calling one of the StartSSL methods, data flows 125 // in clear text. 126 SSL_NONE, 127 SSL_WAIT, // waiting for the stream to open to start SSL negotiation 128 SSL_CONNECTING, // SSL negotiation in progress 129 SSL_CONNECTED, // SSL stream successfully established 130 SSL_ERROR, // some SSL error occurred, stream is closed 131 SSL_CLOSED // Clean close 132 }; 133 134 enum { MSG_TIMEOUT = MSG_MAX+1}; 135 136 // The following three methods return 0 on success and a negative 137 // error code on failure. The error code may be from OpenSSL or -1 138 // on some other error cases, so it can't really be interpreted 139 // unfortunately. 140 141 // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, 142 // depending on whether the underlying stream is already open or 143 // not. 144 int StartSSL(); 145 // Prepare SSL library, state is SSL_CONNECTING. 146 int BeginSSL(); 147 // Perform SSL negotiation steps. 148 int ContinueSSL(); 149 150 // Error handler helper. signal is given as true for errors in 151 // asynchronous contexts (when an error method was not returned 152 // through some other method), and in that case an SE_CLOSE event is 153 // raised on the stream with the specified error. 154 // A 0 error means a graceful close, otherwise there is not really enough 155 // context to interpret the error code. 156 void Error(const char* context, int err, bool signal); 157 void Cleanup(); 158 159 // Override MessageHandler 160 virtual void OnMessage(Message* msg); 161 162 // Flush the input buffers by reading left bytes (for DTLS) 163 void FlushInput(unsigned int left); 164 165 // SSL library configuration 166 SSL_CTX* SetupSSLContext(); 167 // SSL verification check 168 bool SSLPostConnectionCheck(SSL* ssl, const char* server_name, 169 const X509* peer_cert, 170 const std::string& peer_digest); 171 // SSL certification verification error handler, called back from 172 // the openssl library. Returns an int interpreted as a boolean in 173 // the C style: zero means verification failure, non-zero means 174 // passed. 175 static int SSLVerifyCallback(int ok, X509_STORE_CTX* store); 176 177 SSLState state_; 178 SSLRole role_; 179 int ssl_error_code_; // valid when state_ == SSL_ERROR or SSL_CLOSED 180 // Whether the SSL negotiation is blocked on needing to read or 181 // write to the wrapped stream. 182 bool ssl_read_needs_write_; 183 bool ssl_write_needs_read_; 184 185 SSL* ssl_; 186 SSL_CTX* ssl_ctx_; 187 188 // Our key and certificate, mostly useful in peer-to-peer mode. 189 scoped_ptr<OpenSSLIdentity> identity_; 190 // in traditional mode, the server name that the server's certificate 191 // must specify. Empty in peer-to-peer mode. 192 std::string ssl_server_name_; 193 // The certificate that the peer must present or did present. Initially 194 // null in traditional mode, until the connection is established. 195 scoped_ptr<OpenSSLCertificate> peer_certificate_; 196 // In peer-to-peer mode, the digest of the certificate that 197 // the peer must present. 198 Buffer peer_certificate_digest_value_; 199 std::string peer_certificate_digest_algorithm_; 200 201 // OpenSSLAdapter::custom_verify_callback_ result 202 bool custom_verification_succeeded_; 203 204 // The DtlsSrtp ciphers 205 std::string srtp_ciphers_; 206 207 // Do DTLS or not 208 SSLMode ssl_mode_; 209 }; 210 211 ///////////////////////////////////////////////////////////////////////////// 212 213 } // namespace talk_base 214 215 #endif // TALK_BASE_OPENSSLSTREAMADAPTER_H__ 216