@@ -59,6 +59,8 @@ module.exports = class MessageIO extends EventEmitter {
59
59
this . _packetSize = _packetSize ;
60
60
this . debug = debug ;
61
61
62
+ this . tlsNegotiationComplete = false ;
63
+
62
64
this . packetStream = new ReadablePacketStream ( ) ;
63
65
this . packetStream . on ( 'data' , ( packet ) => {
64
66
this . logPacket ( 'Received' , packet ) ;
@@ -84,47 +86,36 @@ module.exports = class MessageIO extends EventEmitter {
84
86
startTls ( credentialsDetails , hostname , trustServerCertificate ) {
85
87
const credentials = tls . createSecureContext ? tls . createSecureContext ( credentialsDetails ) : crypto . createCredentials ( credentialsDetails ) ;
86
88
87
- this . securePair = this . createSecurePair ( credentials ) ;
88
- this . tlsNegotiationComplete = false ;
89
-
90
- this . securePair . cleartext . on ( 'secure' , ( ) => {
91
- const cipher = this . securePair . cleartext . getCipher ( ) ;
92
-
93
- if ( ! trustServerCertificate ) {
94
- let verifyError = this . securePair . ssl . verifyError ( ) ;
95
-
96
- // Verify that server's identity matches it's certificate's names
97
- if ( ! verifyError ) {
98
- verifyError = tls . checkServerIdentity ( hostname , this . securePair . cleartext . getPeerCertificate ( ) ) ;
99
- }
89
+ const duplexpair = new DuplexPair ( ) ;
90
+ const securePair = this . securePair = {
91
+ cleartext : tls . connect ( {
92
+ socket : duplexpair . socket1 ,
93
+ secureContext : credentials ,
94
+ rejectUnauthorized : ! trustServerCertificate
95
+ } ) ,
96
+ encrypted : duplexpair . socket2
97
+ } ;
100
98
101
- if ( verifyError ) {
102
- this . securePair . destroy ( ) ;
103
- this . socket . destroy ( verifyError ) ;
104
- return ;
105
- }
99
+ // If an error happens in the TLS layer, there is nothing we can do about it.
100
+ // Forward the error to the socket so the connection gets properly cleaned up.
101
+ securePair . cleartext . on ( 'error' , ( err ) => {
102
+ // Streams in node.js versions before 8.0.0 don't support `.destroy`
103
+ if ( typeof securePair . encrypted . destroy === 'function' ) {
104
+ securePair . encrypted . destroy ( ) ;
106
105
}
106
+ this . socket . destroy ( err ) ;
107
+ } ) ;
107
108
109
+ securePair . cleartext . on ( 'secureConnect' , ( ) => {
110
+ const cipher = securePair . cleartext . getCipher ( ) ;
108
111
this . debug . log ( 'TLS negotiated (' + cipher . name + ', ' + cipher . version + ')' ) ;
109
- this . emit ( 'secure' , this . securePair . cleartext ) ;
112
+ this . emit ( 'secure' , securePair . cleartext ) ;
110
113
this . encryptAllFutureTraffic ( ) ;
111
114
} ) ;
112
115
113
- this . securePair . encrypted . on ( 'data' , ( data ) => {
116
+ securePair . encrypted . on ( 'data' , ( data ) => {
114
117
this . sendMessage ( TYPE . PRELOGIN , data ) ;
115
118
} ) ;
116
-
117
- // If an error happens in the TLS layer, there is nothing we can do about it.
118
- // Forward the error to the socket so the connection gets properly cleaned up.
119
- this . securePair . cleartext . on ( 'error' , ( err ) => {
120
- this . socket . destroy ( err ) ;
121
- } ) ;
122
-
123
- // On Node >= 0.12, the encrypted stream automatically starts spewing out
124
- // data once we attach a `data` listener. But on Node <= 0.10.x, this is not
125
- // the case. We need to kick the cleartext stream once to get the
126
- // encrypted end of the secure pair to emit the TLS handshake data.
127
- this . securePair . cleartext . write ( '' ) ;
128
119
}
129
120
130
121
encryptAllFutureTraffic ( ) {
@@ -195,15 +186,4 @@ module.exports = class MessageIO extends EventEmitter {
195
186
resume ( ) {
196
187
this . packetStream . resume ( ) ;
197
188
}
198
-
199
- createSecurePair ( credentials ) {
200
- const duplexpair = new DuplexPair ( ) ;
201
- return {
202
- cleartext : new tls . TLSSocket ( duplexpair . socket1 , {
203
- secureContext : credentials ,
204
- rejectUnauthorized : false
205
- } ) ,
206
- encrypted : duplexpair . socket2
207
- } ;
208
- }
209
189
} ;
0 commit comments