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// SecureTunnelSessionClient and SecureTunnelSession.
29// SecureTunnelSessionClient extends TunnelSessionClient to exchange
30// certificates as part of the session description.
31// SecureTunnelSession is a TunnelSession that wraps the underlying
32// tunnel stream into an SSLStreamAdapter.
33
34#ifndef TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
35#define TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
36
37#include <string>
38
39#include "talk/base/sslidentity.h"
40#include "talk/base/sslstreamadapter.h"
41#include "talk/session/tunnel/tunnelsessionclient.h"
42
43namespace cricket {
44
45class SecureTunnelSession;  // below
46
47// SecureTunnelSessionClient
48
49// This TunnelSessionClient establishes secure tunnels protected by
50// SSL/TLS. The PseudoTcpChannel stream is wrapped with an
51// SSLStreamAdapter. An SSLIdentity must be set or generated.
52//
53// The TunnelContentDescription is extended to include the client and
54// server certificates. The initiator acts as the client. The session
55// initiate stanza carries a description that contains the client's
56// certificate, and the session accept response's description has the
57// server certificate added to it.
58
59class SecureTunnelSessionClient : public TunnelSessionClient {
60 public:
61  // The jid is used as the name for sessions for outgoing tunnels.
62  // manager is the SessionManager to which we register this client
63  // and its sessions.
64  SecureTunnelSessionClient(const buzz::Jid& jid, SessionManager* manager);
65
66  // Configures this client to use a preexisting SSLIdentity.
67  // The client takes ownership of the identity object.
68  // Use either SetIdentity or GenerateIdentity, and only once.
69  void SetIdentity(talk_base::SSLIdentity* identity);
70
71  // Generates an identity from nothing.
72  // Returns true if generation was successful.
73  // Use either SetIdentity or GenerateIdentity, and only once.
74  bool GenerateIdentity();
75
76  // Returns our identity for SSL purposes, as either set by
77  // SetIdentity() or generated by GenerateIdentity(). Call this
78  // method only after our identity has been successfully established
79  // by one of those methods.
80  talk_base::SSLIdentity& GetIdentity() const;
81
82  // Inherited methods
83  virtual void OnIncomingTunnel(const buzz::Jid& jid, Session *session);
84  virtual bool ParseContent(SignalingProtocol protocol,
85                            const buzz::XmlElement* elem,
86                            ContentDescription** content,
87                            ParseError* error);
88  virtual bool WriteContent(SignalingProtocol protocol,
89                            const ContentDescription* content,
90                            buzz::XmlElement** elem,
91                            WriteError* error);
92  virtual SessionDescription* CreateOffer(
93      const buzz::Jid &jid, const std::string &description);
94  virtual SessionDescription* CreateAnswer(
95      const SessionDescription* offer);
96
97 protected:
98  virtual TunnelSession* MakeTunnelSession(
99      Session* session, talk_base::Thread* stream_thread,
100      TunnelSessionRole role);
101
102 private:
103  // Our identity (key and certificate) for SSL purposes. The
104  // certificate part will be communicated within the session
105  // description. The identity will be passed to the SSLStreamAdapter
106  // and used for SSL authentication.
107  talk_base::scoped_ptr<talk_base::SSLIdentity> identity_;
108
109  DISALLOW_EVIL_CONSTRUCTORS(SecureTunnelSessionClient);
110};
111
112// SecureTunnelSession:
113// A TunnelSession represents one session for one client. It
114// provides the actual tunnel stream and handles state changes.
115// A SecureTunnelSession is a TunnelSession that wraps the underlying
116// tunnel stream into an SSLStreamAdapter.
117
118class SecureTunnelSession : public TunnelSession {
119 public:
120  // This TunnelSession will tie together the given client and session.
121  // stream_thread is passed to the PseudoTCPChannel: it's the thread
122  // designated to interact with the tunnel stream.
123  // role is either INITIATOR or RESPONDER, depending on who is
124  // initiating the session.
125  SecureTunnelSession(SecureTunnelSessionClient* client, Session* session,
126                      talk_base::Thread* stream_thread,
127                      TunnelSessionRole role);
128
129  // Returns the stream that implements the actual P2P tunnel.
130  // This may be called only once. Caller is responsible for freeing
131  // the returned object.
132  virtual talk_base::StreamInterface* GetStream();
133
134 protected:
135  // Inherited method: callback on accepting a session.
136  virtual void OnAccept();
137
138  // Helper method for GetStream() that Instantiates the
139  // SSLStreamAdapter to wrap the PseudoTcpChannel's stream, and
140  // configures it with our identity and role.
141  talk_base::StreamInterface* MakeSecureStream(
142      talk_base::StreamInterface* stream);
143
144  // Our role in requesting the tunnel: INITIATOR or
145  // RESPONDER. Translates to our role in SSL negotiation:
146  // respectively client or server. Also indicates which slot of the
147  // SecureTunnelContentDescription our cert goes into: client-cert or
148  // server-cert respectively.
149  TunnelSessionRole role_;
150
151  // This is the stream representing the usable tunnel endpoint.  It's
152  // a StreamReference wrapping the SSLStreamAdapter instance, which
153  // further wraps a PseudoTcpChannel::InternalStream. The
154  // StreamReference is because in the case of CreateTunnel(), the
155  // stream endpoint is returned early, but we need to keep a handle
156  // on it so we can setup the peer certificate when we receive it
157  // later.
158  talk_base::scoped_ptr<talk_base::StreamReference> ssl_stream_reference_;
159
160  DISALLOW_EVIL_CONSTRUCTORS(SecureTunnelSession);
161};
162
163}  // namespace cricket
164
165#endif  // TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
166