| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | 
							- /**
 
-  * Socket wrapping functions for TLS.
 
-  *
 
-  * @author Dave Longley
 
-  *
 
-  * Copyright (c) 2009-2012 Digital Bazaar, Inc.
 
-  */
 
- var forge = require('./forge');
 
- require('./tls');
 
- /**
 
-  * Wraps a forge.net socket with a TLS layer.
 
-  *
 
-  * @param options:
 
-  *   sessionId: a session ID to reuse, null for a new connection if no session
 
-  *     cache is provided or it is empty.
 
-  *   caStore: an array of certificates to trust.
 
-  *   sessionCache: a session cache to use.
 
-  *   cipherSuites: an optional array of cipher suites to use, see
 
-  *     tls.CipherSuites.
 
-  *   socket: the socket to wrap.
 
-  *   virtualHost: the virtual server name to use in a TLS SNI extension.
 
-  *   verify: a handler used to custom verify certificates in the chain.
 
-  *   getCertificate: an optional callback used to get a certificate.
 
-  *   getPrivateKey: an optional callback used to get a private key.
 
-  *   getSignature: an optional callback used to get a signature.
 
-  *   deflate: function(inBytes) if provided, will deflate TLS records using
 
-  *     the deflate algorithm if the server supports it.
 
-  *   inflate: function(inBytes) if provided, will inflate TLS records using
 
-  *     the deflate algorithm if the server supports it.
 
-  *
 
-  * @return the TLS-wrapped socket.
 
-  */
 
- forge.tls.wrapSocket = function(options) {
 
-   // get raw socket
 
-   var socket = options.socket;
 
-   // create TLS socket
 
-   var tlsSocket = {
 
-     id: socket.id,
 
-     // set handlers
 
-     connected: socket.connected || function(e) {},
 
-     closed: socket.closed || function(e) {},
 
-     data: socket.data || function(e) {},
 
-     error: socket.error || function(e) {}
 
-   };
 
-   // create TLS connection
 
-   var c = forge.tls.createConnection({
 
-     server: false,
 
-     sessionId: options.sessionId || null,
 
-     caStore: options.caStore || [],
 
-     sessionCache: options.sessionCache || null,
 
-     cipherSuites: options.cipherSuites || null,
 
-     virtualHost: options.virtualHost,
 
-     verify: options.verify,
 
-     getCertificate: options.getCertificate,
 
-     getPrivateKey: options.getPrivateKey,
 
-     getSignature: options.getSignature,
 
-     deflate: options.deflate,
 
-     inflate: options.inflate,
 
-     connected: function(c) {
 
-       // first handshake complete, call handler
 
-       if(c.handshakes === 1) {
 
-         tlsSocket.connected({
 
-           id: socket.id,
 
-           type: 'connect',
 
-           bytesAvailable: c.data.length()
 
-         });
 
-       }
 
-     },
 
-     tlsDataReady: function(c) {
 
-       // send TLS data over socket
 
-       return socket.send(c.tlsData.getBytes());
 
-     },
 
-     dataReady: function(c) {
 
-       // indicate application data is ready
 
-       tlsSocket.data({
 
-         id: socket.id,
 
-         type: 'socketData',
 
-         bytesAvailable: c.data.length()
 
-       });
 
-     },
 
-     closed: function(c) {
 
-       // close socket
 
-       socket.close();
 
-     },
 
-     error: function(c, e) {
 
-       // send error, close socket
 
-       tlsSocket.error({
 
-         id: socket.id,
 
-         type: 'tlsError',
 
-         message: e.message,
 
-         bytesAvailable: 0,
 
-         error: e
 
-       });
 
-       socket.close();
 
-     }
 
-   });
 
-   // handle doing handshake after connecting
 
-   socket.connected = function(e) {
 
-     c.handshake(options.sessionId);
 
-   };
 
-   // handle closing TLS connection
 
-   socket.closed = function(e) {
 
-     if(c.open && c.handshaking) {
 
-       // error
 
-       tlsSocket.error({
 
-         id: socket.id,
 
-         type: 'ioError',
 
-         message: 'Connection closed during handshake.',
 
-         bytesAvailable: 0
 
-       });
 
-     }
 
-     c.close();
 
-     // call socket handler
 
-     tlsSocket.closed({
 
-       id: socket.id,
 
-       type: 'close',
 
-       bytesAvailable: 0
 
-     });
 
-   };
 
-   // handle error on socket
 
-   socket.error = function(e) {
 
-     // error
 
-     tlsSocket.error({
 
-       id: socket.id,
 
-       type: e.type,
 
-       message: e.message,
 
-       bytesAvailable: 0
 
-     });
 
-     c.close();
 
-   };
 
-   // handle receiving raw TLS data from socket
 
-   var _requiredBytes = 0;
 
-   socket.data = function(e) {
 
-     // drop data if connection not open
 
-     if(!c.open) {
 
-       socket.receive(e.bytesAvailable);
 
-     } else {
 
-       // only receive if there are enough bytes available to
 
-       // process a record
 
-       if(e.bytesAvailable >= _requiredBytes) {
 
-         var count = Math.max(e.bytesAvailable, _requiredBytes);
 
-         var data = socket.receive(count);
 
-         if(data !== null) {
 
-           _requiredBytes = c.process(data);
 
-         }
 
-       }
 
-     }
 
-   };
 
-   /**
 
-    * Destroys this socket.
 
-    */
 
-   tlsSocket.destroy = function() {
 
-     socket.destroy();
 
-   };
 
-   /**
 
-    * Sets this socket's TLS session cache. This should be called before
 
-    * the socket is connected or after it is closed.
 
-    *
 
-    * The cache is an object mapping session IDs to internal opaque state.
 
-    * An application might need to change the cache used by a particular
 
-    * tlsSocket between connections if it accesses multiple TLS hosts.
 
-    *
 
-    * @param cache the session cache to use.
 
-    */
 
-   tlsSocket.setSessionCache = function(cache) {
 
-     c.sessionCache = tls.createSessionCache(cache);
 
-   };
 
-   /**
 
-    * Connects this socket.
 
-    *
 
-    * @param options:
 
-    *           host: the host to connect to.
 
-    *           port: the port to connect to.
 
-    *           policyPort: the policy port to use (if non-default), 0 to
 
-    *              use the flash default.
 
-    *           policyUrl: the policy file URL to use (instead of port).
 
-    */
 
-   tlsSocket.connect = function(options) {
 
-     socket.connect(options);
 
-   };
 
-   /**
 
-    * Closes this socket.
 
-    */
 
-   tlsSocket.close = function() {
 
-     c.close();
 
-   };
 
-   /**
 
-    * Determines if the socket is connected or not.
 
-    *
 
-    * @return true if connected, false if not.
 
-    */
 
-   tlsSocket.isConnected = function() {
 
-     return c.isConnected && socket.isConnected();
 
-   };
 
-   /**
 
-    * Writes bytes to this socket.
 
-    *
 
-    * @param bytes the bytes (as a string) to write.
 
-    *
 
-    * @return true on success, false on failure.
 
-    */
 
-   tlsSocket.send = function(bytes) {
 
-     return c.prepare(bytes);
 
-   };
 
-   /**
 
-    * Reads bytes from this socket (non-blocking). Fewer than the number of
 
-    * bytes requested may be read if enough bytes are not available.
 
-    *
 
-    * This method should be called from the data handler if there are enough
 
-    * bytes available. To see how many bytes are available, check the
 
-    * 'bytesAvailable' property on the event in the data handler or call the
 
-    * bytesAvailable() function on the socket. If the browser is msie, then the
 
-    * bytesAvailable() function should be used to avoid race conditions.
 
-    * Otherwise, using the property on the data handler's event may be quicker.
 
-    *
 
-    * @param count the maximum number of bytes to read.
 
-    *
 
-    * @return the bytes read (as a string) or null on error.
 
-    */
 
-   tlsSocket.receive = function(count) {
 
-     return c.data.getBytes(count);
 
-   };
 
-   /**
 
-    * Gets the number of bytes available for receiving on the socket.
 
-    *
 
-    * @return the number of bytes available for receiving.
 
-    */
 
-   tlsSocket.bytesAvailable = function() {
 
-     return c.data.length();
 
-   };
 
-   return tlsSocket;
 
- };
 
 
  |