Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit 5d2aef1

Browse files
committed
crypto: move createCredentials to tls
Move `createCredentials` to `tls` module and rename it to `createSecureContext`. Make it use default values from `tls` module: `DEFAULT_CIPHERS` and `DEFAULT_ECDH_CURVE`. fix #7249
1 parent b55c9d6 commit 5d2aef1

17 files changed

Lines changed: 222 additions & 163 deletions

doc/api/tls.markdown

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ automatically set as a listener for the [secureConnection][] event. The
197197
supports SNI TLS extension. Two argument will be passed to it: `servername`,
198198
and `cb`. `SNICallback` should invoke `cb(null, ctx)`, where `ctx` is a
199199
SecureContext instance.
200-
(You can use `crypto.createCredentials(...).context` to get proper
200+
(You can use `tls.createSecureContext(...)` to get proper
201201
SecureContext). If `SNICallback` wasn't provided - default callback with
202202
high-level API will be used (see below).
203203

@@ -391,8 +391,8 @@ Construct a new TLSSocket object from existing TCP socket.
391391

392392
`options` is an object that might contain following properties:
393393

394-
- `credentials`: An optional credentials object from
395-
`crypto.createCredentials( ... )`
394+
- `secureContext`: An optional TLS context object from
395+
`tls.createSecureContext( ... )`
396396

397397
- `isServer`: If true - TLS socket will be instantiated in server-mode
398398

@@ -408,7 +408,7 @@ Construct a new TLSSocket object from existing TCP socket.
408408

409409
- `session`: Optional, a `Buffer` instance, containing TLS session
410410

411-
## tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
411+
## tls.createSecurePair([context], [isServer], [requestCert], [rejectUnauthorized])
412412

413413
Stability: 0 - Deprecated. Use tls.TLSSocket instead.
414414

@@ -417,7 +417,7 @@ encrypted data, and one reads/writes cleartext data.
417417
Generally the encrypted one is piped to/from an incoming encrypted data stream,
418418
and the cleartext one is used as a replacement for the initial encrypted stream.
419419

420-
- `credentials`: A credentials object from crypto.createCredentials( ... )
420+
- `credentials`: A secure context object from tls.createSecureContext( ... )
421421

422422
- `isServer`: A boolean indicating whether this tls connection should be
423423
opened as a server or a client.
@@ -532,10 +532,10 @@ Returns the bound address, the address family name and port of the
532532
server as reported by the operating system. See [net.Server.address()][] for
533533
more information.
534534

535-
### server.addContext(hostname, credentials)
535+
### server.addContext(hostname, context)
536536

537537
Add secure context that will be used if client request's SNI hostname is
538-
matching passed `hostname` (wildcards can be used). `credentials` can contain
538+
matching passed `hostname` (wildcards can be used). `context` can contain
539539
`key`, `cert` and `ca`.
540540

541541
### server.maxConnections

lib/_tls_common.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var util = require('util');
23+
var tls = require('tls');
24+
25+
// Lazily loaded
26+
var crypto = null;
27+
28+
var binding = process.binding('crypto');
29+
var NativeSecureContext = binding.SecureContext;
30+
31+
function SecureContext(secureProtocol, flags, context) {
32+
if (!(this instanceof SecureContext)) {
33+
return new SecureContext(secureProtocol, flags, context);
34+
}
35+
36+
if (context) {
37+
this.context = context;
38+
} else {
39+
this.context = new NativeSecureContext();
40+
41+
if (secureProtocol) {
42+
this.context.init(secureProtocol);
43+
} else {
44+
this.context.init();
45+
}
46+
}
47+
48+
if (flags) this.context.setOptions(flags);
49+
}
50+
51+
exports.SecureContext = SecureContext;
52+
53+
54+
exports.createSecureContext = function createSecureContext(options, context) {
55+
if (!options) options = {};
56+
57+
var c = new SecureContext(options.secureProtocol,
58+
options.secureOptions,
59+
context);
60+
61+
if (context) return c;
62+
63+
if (options.key) {
64+
if (options.passphrase) {
65+
c.context.setKey(options.key, options.passphrase);
66+
} else {
67+
c.context.setKey(options.key);
68+
}
69+
}
70+
71+
if (options.cert) c.context.setCert(options.cert);
72+
73+
if (options.ciphers)
74+
c.context.setCiphers(options.ciphers);
75+
else
76+
c.context.setCiphers(tls.DEFAULT_CIPHERS);
77+
78+
if (util.isUndefined(options.ecdhCurve))
79+
c.context.setECDHCurve(tls.DEFAULT_ECDH_CURVE);
80+
else if (options.ecdhCurve)
81+
c.context.setECDHCurve(options.ecdhCurve);
82+
83+
if (options.ca) {
84+
if (util.isArray(options.ca)) {
85+
for (var i = 0, len = options.ca.length; i < len; i++) {
86+
c.context.addCACert(options.ca[i]);
87+
}
88+
} else {
89+
c.context.addCACert(options.ca);
90+
}
91+
} else {
92+
c.context.addRootCerts();
93+
}
94+
95+
if (options.crl) {
96+
if (util.isArray(options.crl)) {
97+
for (var i = 0, len = options.crl.length; i < len; i++) {
98+
c.context.addCRL(options.crl[i]);
99+
}
100+
} else {
101+
c.context.addCRL(options.crl);
102+
}
103+
}
104+
105+
if (options.sessionIdContext) {
106+
c.context.setSessionIdContext(options.sessionIdContext);
107+
}
108+
109+
if (options.pfx) {
110+
var pfx = options.pfx;
111+
var passphrase = options.passphrase;
112+
113+
if (!crypto)
114+
crypto = require('crypto');
115+
116+
pfx = crypto._toBuf(pfx);
117+
if (passphrase)
118+
passphrase = crypto._toBuf(passphrase);
119+
120+
if (passphrase) {
121+
c.context.loadPKCS12(pfx, passphrase);
122+
} else {
123+
c.context.loadPKCS12(pfx);
124+
}
125+
}
126+
127+
return c;
128+
};

lib/_tls_legacy.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,10 @@ function onnewsessiondone() {
681681
* Provides a pair of streams to do encrypted communication.
682682
*/
683683

684-
function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
684+
function SecurePair(context, isServer, requestCert, rejectUnauthorized,
685685
options) {
686686
if (!(this instanceof SecurePair)) {
687-
return new SecurePair(credentials,
687+
return new SecurePair(context,
688688
isServer,
689689
requestCert,
690690
rejectUnauthorized,
@@ -705,10 +705,10 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
705705
this._doneFlag = false;
706706
this._destroying = false;
707707

708-
if (!credentials) {
709-
this.credentials = crypto.createCredentials();
708+
if (!context) {
709+
this.credentials = tls.createSecureContext();
710710
} else {
711-
this.credentials = credentials;
711+
this.credentials = context;
712712
}
713713

714714
if (!this._isServer) {
@@ -774,11 +774,11 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
774774
util.inherits(SecurePair, events.EventEmitter);
775775

776776

777-
exports.createSecurePair = function(credentials,
777+
exports.createSecurePair = function(context,
778778
isServer,
779779
requestCert,
780780
rejectUnauthorized) {
781-
var pair = new SecurePair(credentials,
781+
var pair = new SecurePair(context,
782782
isServer,
783783
requestCert,
784784
rejectUnauthorized);

lib/_tls_wrap.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,9 @@ function onclienthello(hello) {
123123
if (err)
124124
return self.destroy(err);
125125

126+
// TODO(indutny): eventually disallow raw `SecureContext`
126127
if (context)
127-
self.ssl.sni_context = context;
128+
self.ssl.sni_context = context.context || context;
128129

129130
self.ssl.endParser();
130131
}
@@ -226,8 +227,10 @@ TLSSocket.prototype._init = function(socket) {
226227
var options = this._tlsOptions;
227228

228229
// Wrap socket's handle
229-
var credentials = options.credentials || crypto.createCredentials();
230-
this.ssl = tls_wrap.wrap(this._handle, credentials.context, options.isServer);
230+
var context = options.secureContext ||
231+
options.credentials ||
232+
tls.createSecureContext();
233+
this.ssl = tls_wrap.wrap(this._handle, context.context, options.isServer);
231234
this.server = options.server || null;
232235

233236
// For clients, we will always have either a given ca list or be using
@@ -530,15 +533,14 @@ function Server(/* [options], listener */) {
530533
// Handle option defaults:
531534
this.setOptions(options);
532535

533-
var sharedCreds = crypto.createCredentials({
536+
var sharedCreds = tls.createSecureContext({
534537
pfx: self.pfx,
535538
key: self.key,
536539
passphrase: self.passphrase,
537540
cert: self.cert,
538541
ca: self.ca,
539-
ciphers: self.ciphers || tls.DEFAULT_CIPHERS,
540-
ecdhCurve: util.isUndefined(self.ecdhCurve) ?
541-
tls.DEFAULT_ECDH_CURVE : self.ecdhCurve,
542+
ciphers: self.ciphers,
543+
ecdhCurve: self.ecdhCurve,
542544
secureProtocol: self.secureProtocol,
543545
secureOptions: self.secureOptions,
544546
crl: self.crl,
@@ -563,7 +565,7 @@ function Server(/* [options], listener */) {
563565
// constructor call
564566
net.Server.call(this, function(raw_socket) {
565567
var socket = new TLSSocket(raw_socket, {
566-
credentials: sharedCreds,
568+
secureContext: sharedCreds,
567569
isServer: true,
568570
server: self,
569571
requestCert: self.requestCert,
@@ -674,7 +676,7 @@ Server.prototype.setOptions = function(options) {
674676
};
675677

676678
// SNI Contexts High-Level API
677-
Server.prototype.addContext = function(servername, credentials) {
679+
Server.prototype.addContext = function(servername, context) {
678680
if (!servername) {
679681
throw 'Servername is required parameter for Server.addContext';
680682
}
@@ -683,7 +685,7 @@ Server.prototype.addContext = function(servername, credentials) {
683685
servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
684686
.replace(/\*/g, '[^\.]*') +
685687
'$');
686-
this._contexts.push([re, crypto.createCredentials(credentials).context]);
688+
this._contexts.push([re, tls.createSecureContext(context).context]);
687689
};
688690

689691
function SNICallback(servername, callback) {
@@ -728,12 +730,12 @@ function normalizeConnectArgs(listArgs) {
728730
return (cb) ? [options, cb] : [options];
729731
}
730732

731-
function legacyConnect(hostname, options, NPN, credentials) {
733+
function legacyConnect(hostname, options, NPN, context) {
732734
assert(options.socket);
733735
if (!tls_legacy)
734736
tls_legacy = require('_tls_legacy');
735737

736-
var pair = tls_legacy.createSecurePair(credentials,
738+
var pair = tls_legacy.createSecurePair(context,
737739
false,
738740
true,
739741
!!options.rejectUnauthorized,
@@ -765,7 +767,7 @@ exports.connect = function(/* [port, host], options, cb */) {
765767
options.host ||
766768
options.socket && options.socket._host,
767769
NPN = {},
768-
credentials = crypto.createCredentials(options);
770+
context = tls.createSecureContext(options);
769771
tls.convertNPNProtocols(options.NPNProtocols, NPN);
770772

771773
// Wrapping TLS socket inside another TLS socket was requested -
@@ -776,12 +778,12 @@ exports.connect = function(/* [port, host], options, cb */) {
776778
if (options.socket instanceof TLSSocket) {
777779
debug('legacy connect');
778780
legacy = true;
779-
socket = legacyConnect(hostname, options, NPN, credentials);
781+
socket = legacyConnect(hostname, options, NPN, context);
780782
result = socket.cleartext;
781783
} else {
782784
legacy = false;
783785
socket = new TLSSocket(options.socket, {
784-
credentials: credentials,
786+
secureContext: context,
785787
isServer: false,
786788
requestCert: true,
787789
rejectUnauthorized: options.rejectUnauthorized,

0 commit comments

Comments
 (0)