source: trip-planner-front/node_modules/node-forge/lib/tlssocket.js

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/**
2 * Socket wrapping functions for TLS.
3 *
4 * @author Dave Longley
5 *
6 * Copyright (c) 2009-2012 Digital Bazaar, Inc.
7 */
8var forge = require('./forge');
9require('./tls');
10
11/**
12 * Wraps a forge.net socket with a TLS layer.
13 *
14 * @param options:
15 * sessionId: a session ID to reuse, null for a new connection if no session
16 * cache is provided or it is empty.
17 * caStore: an array of certificates to trust.
18 * sessionCache: a session cache to use.
19 * cipherSuites: an optional array of cipher suites to use, see
20 * tls.CipherSuites.
21 * socket: the socket to wrap.
22 * virtualHost: the virtual server name to use in a TLS SNI extension.
23 * verify: a handler used to custom verify certificates in the chain.
24 * getCertificate: an optional callback used to get a certificate.
25 * getPrivateKey: an optional callback used to get a private key.
26 * getSignature: an optional callback used to get a signature.
27 * deflate: function(inBytes) if provided, will deflate TLS records using
28 * the deflate algorithm if the server supports it.
29 * inflate: function(inBytes) if provided, will inflate TLS records using
30 * the deflate algorithm if the server supports it.
31 *
32 * @return the TLS-wrapped socket.
33 */
34forge.tls.wrapSocket = function(options) {
35 // get raw socket
36 var socket = options.socket;
37
38 // create TLS socket
39 var tlsSocket = {
40 id: socket.id,
41 // set handlers
42 connected: socket.connected || function(e) {},
43 closed: socket.closed || function(e) {},
44 data: socket.data || function(e) {},
45 error: socket.error || function(e) {}
46 };
47
48 // create TLS connection
49 var c = forge.tls.createConnection({
50 server: false,
51 sessionId: options.sessionId || null,
52 caStore: options.caStore || [],
53 sessionCache: options.sessionCache || null,
54 cipherSuites: options.cipherSuites || null,
55 virtualHost: options.virtualHost,
56 verify: options.verify,
57 getCertificate: options.getCertificate,
58 getPrivateKey: options.getPrivateKey,
59 getSignature: options.getSignature,
60 deflate: options.deflate,
61 inflate: options.inflate,
62 connected: function(c) {
63 // first handshake complete, call handler
64 if(c.handshakes === 1) {
65 tlsSocket.connected({
66 id: socket.id,
67 type: 'connect',
68 bytesAvailable: c.data.length()
69 });
70 }
71 },
72 tlsDataReady: function(c) {
73 // send TLS data over socket
74 return socket.send(c.tlsData.getBytes());
75 },
76 dataReady: function(c) {
77 // indicate application data is ready
78 tlsSocket.data({
79 id: socket.id,
80 type: 'socketData',
81 bytesAvailable: c.data.length()
82 });
83 },
84 closed: function(c) {
85 // close socket
86 socket.close();
87 },
88 error: function(c, e) {
89 // send error, close socket
90 tlsSocket.error({
91 id: socket.id,
92 type: 'tlsError',
93 message: e.message,
94 bytesAvailable: 0,
95 error: e
96 });
97 socket.close();
98 }
99 });
100
101 // handle doing handshake after connecting
102 socket.connected = function(e) {
103 c.handshake(options.sessionId);
104 };
105
106 // handle closing TLS connection
107 socket.closed = function(e) {
108 if(c.open && c.handshaking) {
109 // error
110 tlsSocket.error({
111 id: socket.id,
112 type: 'ioError',
113 message: 'Connection closed during handshake.',
114 bytesAvailable: 0
115 });
116 }
117 c.close();
118
119 // call socket handler
120 tlsSocket.closed({
121 id: socket.id,
122 type: 'close',
123 bytesAvailable: 0
124 });
125 };
126
127 // handle error on socket
128 socket.error = function(e) {
129 // error
130 tlsSocket.error({
131 id: socket.id,
132 type: e.type,
133 message: e.message,
134 bytesAvailable: 0
135 });
136 c.close();
137 };
138
139 // handle receiving raw TLS data from socket
140 var _requiredBytes = 0;
141 socket.data = function(e) {
142 // drop data if connection not open
143 if(!c.open) {
144 socket.receive(e.bytesAvailable);
145 } else {
146 // only receive if there are enough bytes available to
147 // process a record
148 if(e.bytesAvailable >= _requiredBytes) {
149 var count = Math.max(e.bytesAvailable, _requiredBytes);
150 var data = socket.receive(count);
151 if(data !== null) {
152 _requiredBytes = c.process(data);
153 }
154 }
155 }
156 };
157
158 /**
159 * Destroys this socket.
160 */
161 tlsSocket.destroy = function() {
162 socket.destroy();
163 };
164
165 /**
166 * Sets this socket's TLS session cache. This should be called before
167 * the socket is connected or after it is closed.
168 *
169 * The cache is an object mapping session IDs to internal opaque state.
170 * An application might need to change the cache used by a particular
171 * tlsSocket between connections if it accesses multiple TLS hosts.
172 *
173 * @param cache the session cache to use.
174 */
175 tlsSocket.setSessionCache = function(cache) {
176 c.sessionCache = tls.createSessionCache(cache);
177 };
178
179 /**
180 * Connects this socket.
181 *
182 * @param options:
183 * host: the host to connect to.
184 * port: the port to connect to.
185 * policyPort: the policy port to use (if non-default), 0 to
186 * use the flash default.
187 * policyUrl: the policy file URL to use (instead of port).
188 */
189 tlsSocket.connect = function(options) {
190 socket.connect(options);
191 };
192
193 /**
194 * Closes this socket.
195 */
196 tlsSocket.close = function() {
197 c.close();
198 };
199
200 /**
201 * Determines if the socket is connected or not.
202 *
203 * @return true if connected, false if not.
204 */
205 tlsSocket.isConnected = function() {
206 return c.isConnected && socket.isConnected();
207 };
208
209 /**
210 * Writes bytes to this socket.
211 *
212 * @param bytes the bytes (as a string) to write.
213 *
214 * @return true on success, false on failure.
215 */
216 tlsSocket.send = function(bytes) {
217 return c.prepare(bytes);
218 };
219
220 /**
221 * Reads bytes from this socket (non-blocking). Fewer than the number of
222 * bytes requested may be read if enough bytes are not available.
223 *
224 * This method should be called from the data handler if there are enough
225 * bytes available. To see how many bytes are available, check the
226 * 'bytesAvailable' property on the event in the data handler or call the
227 * bytesAvailable() function on the socket. If the browser is msie, then the
228 * bytesAvailable() function should be used to avoid race conditions.
229 * Otherwise, using the property on the data handler's event may be quicker.
230 *
231 * @param count the maximum number of bytes to read.
232 *
233 * @return the bytes read (as a string) or null on error.
234 */
235 tlsSocket.receive = function(count) {
236 return c.data.getBytes(count);
237 };
238
239 /**
240 * Gets the number of bytes available for receiving on the socket.
241 *
242 * @return the number of bytes available for receiving.
243 */
244 tlsSocket.bytesAvailable = function() {
245 return c.data.length();
246 };
247
248 return tlsSocket;
249};
Note: See TracBrowser for help on using the repository browser.