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 "talk/base/sslstreamadapter.h" 33 #include "talk/base/opensslidentity.h" 34 35 typedef struct ssl_st SSL; 36 typedef struct ssl_ctx_st SSL_CTX; 37 typedef struct x509_store_ctx_st X509_STORE_CTX; 38 39 namespace talk_base { 40 41 // This class was written with OpenSSLAdapter (a socket adapter) as a 42 // starting point. It has similar structure and functionality, with 43 // the peer-to-peer mode added. 44 // 45 // Static methods to initialize and deinit the SSL library are in 46 // OpenSSLAdapter. This class also uses 47 // OpenSSLAdapter::custom_verify_callback_ (a static field). These 48 // should probably be moved out to a neutral class. 49 // 50 // In a few cases I have factored out some OpenSSLAdapter code into 51 // static methods so it can be reused from this class. Eventually that 52 // code should probably be moved to a common support 53 // class. Unfortunately there remain a few duplicated sections of 54 // code. I have not done more restructuring because I did not want to 55 // affect existing code that uses OpenSSLAdapter. 56 // 57 // This class does not support the SSL connection restart feature 58 // present in OpenSSLAdapter. I am not entirely sure how the feature 59 // is useful and I am not convinced that it works properly. 60 // 61 // This implementation is careful to disallow data exchange after an 62 // SSL error, and it has an explicit SSL_CLOSED state. It should not 63 // be possible to send any data in clear after one of the StartSSL 64 // methods has been called. 65 66 // Look in sslstreamadapter.h for documentation of the methods. 67 68 class OpenSSLIdentity; 69 70 /////////////////////////////////////////////////////////////////////////////// 71 72 class OpenSSLStreamAdapter : public SSLStreamAdapter { 73 public: 74 explicit OpenSSLStreamAdapter(StreamInterface* stream); 75 virtual ~OpenSSLStreamAdapter(); 76 77 virtual void SetIdentity(SSLIdentity* identity); 78 virtual void SetServerRole(); 79 virtual void SetPeerCertificate(SSLCertificate* cert); 80 81 virtual int StartSSLWithServer(const char* server_name); 82 virtual int StartSSLWithPeer(); 83 84 virtual StreamResult Read(void* data, size_t data_len, 85 size_t* read, int* error); 86 virtual StreamResult Write(const void* data, size_t data_len, 87 size_t* written, int* error); 88 virtual void Close(); 89 virtual StreamState GetState() const; 90 91 protected: 92 virtual void OnEvent(StreamInterface* stream, int events, int err); 93 94 private: 95 enum SSLState { 96 // Before calling one of the StartSSL methods, data flows 97 // in clear text. 98 SSL_NONE, 99 SSL_WAIT, // waiting for the stream to open to start SSL negotiation 100 SSL_CONNECTING, // SSL negotiation in progress 101 SSL_CONNECTED, // SSL stream successfully established 102 SSL_ERROR, // some SSL error occurred, stream is closed 103 SSL_CLOSED // Clean close 104 }; 105 enum SSLRole { 106 SSL_CLIENT, SSL_SERVER 107 }; 108 109 // The following three methods return 0 on success and a negative 110 // error code on failure. The error code may be from OpenSSL or -1 111 // on some other error cases, so it can't really be interpreted 112 // unfortunately. 113 114 // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, 115 // depending on whether the underlying stream is already open or 116 // not. 117 int StartSSL(); 118 // Prepare SSL library, state is SSL_CONNECTING. 119 int BeginSSL(); 120 // Perform SSL negotiation steps. 121 int ContinueSSL(); 122 123 // Error handler helper. signal is given as true for errors in 124 // asynchronous contexts (when an error method was not returned 125 // through some other method), and in that case an SE_CLOSE event is 126 // raised on the stream with the specified error. 127 // A 0 error means a graceful close, otherwise there is not really enough 128 // context to interpret the error code. 129 void Error(const char* context, int err, bool signal); 130 void Cleanup(); 131 132 // SSL library configuration 133 SSL_CTX* SetupSSLContext(); 134 // SSL verification check 135 bool SSLPostConnectionCheck(SSL* ssl, const char* server_name, 136 const X509* peer_cert); 137 // SSL certification verification error handler, called back from 138 // the openssl library. Returns an int interpreted as a boolean in 139 // the C style: zero means verification failure, non-zero means 140 // passed. 141 static int SSLVerifyCallback(int ok, X509_STORE_CTX* store); 142 143 144 SSLState state_; 145 SSLRole role_; 146 int ssl_error_code_; // valid when state_ == SSL_ERROR or SSL_CLOSED 147 // Whether the SSL negotiation is blocked on needing to read or 148 // write to the wrapped stream. 149 bool ssl_read_needs_write_; 150 bool ssl_write_needs_read_; 151 152 SSL* ssl_; 153 SSL_CTX* ssl_ctx_; 154 // in traditional mode, the server name that the server's certificate 155 // must specify. Empty in peer-to-peer mode. 156 // Our key and certificate, mostly useful in peer-to-peer mode. 157 scoped_ptr<OpenSSLIdentity> identity_; 158 std::string ssl_server_name_; 159 // In peer-to-peer mode, the certificate that the peer must 160 // present. Empty in traditional mode. 161 scoped_ptr<OpenSSLCertificate> peer_certificate_; 162 163 // OpenSSLAdapter::custom_verify_callback_ result 164 bool custom_verification_succeeded_; 165 }; 166 167 ///////////////////////////////////////////////////////////////////////////// 168 169 } // namespace talk_base 170 171 #endif // TALK_BASE_OPENSSLSTREAMADAPTER_H__ 172