summaryrefslogtreecommitdiff
path: root/chromium/third_party/libjingle/source/talk/base/sslstreamadapter.h
blob: 3a7797370c3c1152419b9101d6b193f28be6108a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
 * libjingle
 * Copyright 2004--2008, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products 
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_BASE_SSLSTREAMADAPTER_H_
#define TALK_BASE_SSLSTREAMADAPTER_H_

#include <string>
#include <vector>

#include "talk/base/stream.h"
#include "talk/base/sslidentity.h"

namespace talk_base {

// SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
// After SSL has been started, the stream will only open on successful
// SSL verification of certificates, and the communication is
// encrypted of course.
//
// This class was written with SSLAdapter as a starting point. It
// offers a similar interface, with two differences: there is no
// support for a restartable SSL connection, and this class has a
// peer-to-peer mode.
//
// The SSL library requires initialization and cleanup. Static method
// for doing this are in SSLAdapter. They should possibly be moved out
// to a neutral class.


enum SSLRole { SSL_CLIENT, SSL_SERVER };
enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS };

// Errors for Read -- in the high range so no conflict with OpenSSL.
enum { SSE_MSG_TRUNC = 0xff0001 };

class SSLStreamAdapter : public StreamAdapterInterface {
 public:
  // Instantiate an SSLStreamAdapter wrapping the given stream,
  // (using the selected implementation for the platform).
  // Caller is responsible for freeing the returned object.
  static SSLStreamAdapter* Create(StreamInterface* stream);

  explicit SSLStreamAdapter(StreamInterface* stream)
      : StreamAdapterInterface(stream), ignore_bad_cert_(false) { }

  void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
  bool ignore_bad_cert() const { return ignore_bad_cert_; }

  // Specify our SSL identity: key and certificate. Mostly this is
  // only used in the peer-to-peer mode (unless we actually want to
  // provide a client certificate to a server).
  // SSLStream takes ownership of the SSLIdentity object and will
  // free it when appropriate. Should be called no more than once on a
  // given SSLStream instance.
  virtual void SetIdentity(SSLIdentity* identity) = 0;

  // Call this to indicate that we are to play the server's role in
  // the peer-to-peer mode.
  // The default argument is for backward compatibility
  // TODO(ekr@rtfm.com): rename this SetRole to reflect its new function
  virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0;

  // Do DTLS or TLS
  virtual void SetMode(SSLMode mode) = 0;

  // The mode of operation is selected by calling either
  // StartSSLWithServer or StartSSLWithPeer.
  // Use of the stream prior to calling either of these functions will
  // pass data in clear text.
  // Calling one of these functions causes SSL negotiation to begin as
  // soon as possible: right away if the underlying wrapped stream is
  // already opened, or else as soon as it opens.
  //
  // These functions return a negative error code on failure.
  // Returning 0 means success so far, but negotiation is probably not
  // complete and will continue asynchronously.  In that case, the
  // exposed stream will open after successful negotiation and
  // verification, or an SE_CLOSE event will be raised if negotiation
  // fails.

  // StartSSLWithServer starts SSL negotiation with a server in
  // traditional mode. server_name specifies the expected server name
  // which the server's certificate needs to specify.
  virtual int StartSSLWithServer(const char* server_name) = 0;

  // StartSSLWithPeer starts negotiation in the special peer-to-peer
  // mode.
  // Generally, SetIdentity() and possibly SetServerRole() should have
  // been called before this.
  // SetPeerCertificate() or SetPeerCertificateDigest() must also be called.
  // It may be called after StartSSLWithPeer() but must be called before the
  // underlying stream opens.
  virtual int StartSSLWithPeer() = 0;

  // Specify the certificate that our peer is expected to use in
  // peer-to-peer mode. Only this certificate will be accepted during
  // SSL verification. The certificate is assumed to have been
  // obtained through some other secure channel (such as the XMPP
  // channel). (This could also specify the certificate authority that
  // will sign the peer's certificate.)
  // SSLStream takes ownership of the SSLCertificate object and will
  // free it when appropriate. Should be called no more than once on a
  // given SSLStream instance.
  virtual void SetPeerCertificate(SSLCertificate* cert) = 0;

  // Specify the digest of the certificate that our peer is expected to use in
  // peer-to-peer mode. Only this certificate will be accepted during
  // SSL verification. The certificate is assumed to have been
  // obtained through some other secure channel (such as the XMPP
  // channel). Unlike SetPeerCertificate(), this must specify the
  // terminal certificate, not just a CA.
  // SSLStream makes a copy of the digest value.
  virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
                                        const unsigned char* digest_val,
                                        size_t digest_len) = 0;

  // Retrieves the peer's X.509 certificate, if a certificate has been
  // provided by SetPeerCertificate or a connection has been established. If
  // a connection has been established, this returns the
  // certificate transmitted over SSL, including the entire chain.
  // The returned certificate is owned by the caller.
  virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;

  // Key Exporter interface from RFC 5705
  // Arguments are:
  // label               -- the exporter label.
  //                        part of the RFC defining each exporter
  //                        usage (IN)
  // context/context_len -- a context to bind to for this connection;
  //                        optional, can be NULL, 0 (IN)
  // use_context         -- whether to use the context value
  //                        (needed to distinguish no context from
  //                        zero-length ones).
  // result              -- where to put the computed value
  // result_len          -- the length of the computed value
  virtual bool ExportKeyingMaterial(const std::string& label,
                                    const uint8* context,
                                    size_t context_len,
                                    bool use_context,
                                    uint8* result,
                                    size_t result_len) {
    return false;  // Default is unsupported
  }


  // DTLS-SRTP interface
  virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers) {
    return false;
  }

  virtual bool GetDtlsSrtpCipher(std::string* cipher) {
    return false;
  }

  // Capabilities testing
  static bool HaveDtls();
  static bool HaveDtlsSrtp();
  static bool HaveExporter();

  // If true, the server certificate need not match the configured
  // server_name, and in fact missing certificate authority and other
  // verification errors are ignored.
  bool ignore_bad_cert_;
};

}  // namespace talk_base

#endif  // TALK_BASE_SSLSTREAMADAPTER_H_