15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/*
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2008, Google Inc.
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
559a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org * Redistribution and use in source and binary forms, with or without
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met:
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
859a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer.
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer in the documentation
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     and/or other materials provided with the distribution.
1359a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org *  3. The name of the author may not be used to endorse or promote products
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     derived from this software without specific prior written permission.
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
1759a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
1959a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2359a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2459a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef TALK_BASE_SSLSTREAMADAPTERHELPER_H_
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define TALK_BASE_SSLSTREAMADAPTERHELPER_H_
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <string>
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <vector>
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/buffer.h"
355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/stream.h"
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/sslidentity.h"
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/sslstreamadapter.h"
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace talk_base {
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// SSLStreamAdapterHelper : A stream adapter which implements much
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// of the logic that is common between the known implementations
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// (NSS and OpenSSL)
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass SSLStreamAdapterHelper : public SSLStreamAdapter {
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  explicit SSLStreamAdapterHelper(StreamInterface* stream)
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : SSLStreamAdapter(stream),
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        state_(SSL_NONE),
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        role_(SSL_CLIENT),
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        ssl_error_code_(0),  // Not meaningful yet
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        ssl_mode_(SSL_MODE_TLS) {}
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Overrides of SSLStreamAdapter
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetIdentity(SSLIdentity* identity);
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetServerRole(SSLRole role = SSL_SERVER);
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetMode(SSLMode mode);
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual int StartSSLWithServer(const char* server_name);
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual int StartSSLWithPeer();
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetPeerCertificate(SSLCertificate* cert);
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                        const unsigned char* digest_val,
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                        size_t digest_len);
6659a1e5569576b61b7ae1f0d7fe72c958c940e156wu@webrtc.org  virtual bool GetPeerCertificate(SSLCertificate** cert) const;
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual StreamState GetState() const;
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void Close();
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Internal helper methods
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // The following method returns 0 on success and a negative
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // error code on failure. The error code may be either -1 or
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // from the impl on some other error cases, so it can't really be
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // interpreted unfortunately.
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Perform SSL negotiation steps.
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int ContinueSSL();
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Error handler helper. signal is given as true for errors in
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // asynchronous contexts (when an error code was not returned
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // through some other method), and in that case an SE_CLOSE event is
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // raised on the stream with the specified error.
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // A 0 error means a graceful close, otherwise there is not really enough
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // context to interpret the error code.
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void Error(const char* context, int err, bool signal);
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Must be implemented by descendents
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual int BeginSSL() = 0;
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void Cleanup() = 0;
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual bool GetDigestLength(const std::string &algorithm,
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               std::size_t *length) = 0;
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  enum SSLState {
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Before calling one of the StartSSL methods, data flows
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // in clear text.
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SSL_NONE,
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SSL_WAIT,  // waiting for the stream to open to start SSL negotiation
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SSL_CONNECTING,  // SSL negotiation in progress
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SSL_CONNECTED,  // SSL stream successfully established
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SSL_ERROR,  // some SSL error occurred, stream is closed
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SSL_CLOSED  // Clean close
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  };
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // MSG_MAX is the maximum generic stream message number.
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  enum { MSG_DTLS_TIMEOUT = MSG_MAX + 1 };
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SSLState state_;
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SSLRole role_;
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int ssl_error_code_;  // valid when state_ == SSL_ERROR
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Our key and certificate, mostly useful in peer-to-peer mode.
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  scoped_ptr<SSLIdentity> identity_;
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // in traditional mode, the server name that the server's certificate
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // must specify. Empty in peer-to-peer mode.
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string ssl_server_name_;
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // In peer-to-peer mode, the certificate that the peer must
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // present. Empty in traditional mode.
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  scoped_ptr<SSLCertificate> peer_certificate_;
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // In peer-to-peer mode, the digest of the certificate that
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // the peer must present.
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  Buffer peer_certificate_digest_value_;
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string peer_certificate_digest_algorithm_;
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Do DTLS or not
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SSLMode ssl_mode_;
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private:
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT,
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // depending on whether the underlying stream is already open or
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // not. Returns 0 on success and a negative value on error.
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int StartSSL();
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}  // namespace talk_base
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // TALK_BASE_SSLSTREAMADAPTERHELPER_H_
139