GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — tls: add setKeyCert() to tls.Socket · nodejs/node@8660d48

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • doc/api
    • tls.md
  • lib
    • _tls_wrap.js
  • src/crypto
    • crypto_tls.cc
    • crypto_tls.h
  • test/parallel
    • test-tls-server-setkeycert.js
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎doc/api/tls.md‎

Copy file name to clipboardExpand all lines: doc/api/tls.md
+14Lines changed: 14 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,20 @@ When running as the server, the socket will be destroyed with an error after
15331533
For TLSv1.3, renegotiation cannot be initiated, it is not supported by the
15341534
protocol.
15351535

1536+
### `tlsSocket.setKeyCert(context)`
1537+
1538+
<!-- YAML
1539+
added: REPLACEME
1540+
-->
1541+
1542+
* `context` {Object|tls.SecureContext} An object containing at least `key` and
1543+
`cert` properties from the [`tls.createSecureContext()`][] `options`, or a
1544+
TLS context object created with [`tls.createSecureContext()`][] itself.
1545+
1546+
The `tlsSocket.setKeyCert()` method sets the private key and certificate to use
1547+
for the socket. This is mainly useful if you wish to select a server certificate
1548+
from a TLS server's `ALPNCallback`.
1549+
15361550
### `tlsSocket.setMaxSendFragment(size)`
15371551

15381552
<!-- YAML
Collapse file

‎lib/_tls_wrap.js‎

Copy file name to clipboardExpand all lines: lib/_tls_wrap.js
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,17 @@ TLSSocket.prototype.getX509Certificate = function() {
11511151
return cert ? new InternalX509Certificate(cert) : undefined;
11521152
};
11531153

1154+
TLSSocket.prototype.setKeyCert = function(context) {
1155+
if (this._handle) {
1156+
let secureContext;
1157+
if (context instanceof common.SecureContext)
1158+
secureContext = context;
1159+
else
1160+
secureContext = tls.createSecureContext(context);
1161+
this._handle.setKeyCert(secureContext.context);
1162+
}
1163+
};
1164+
11541165
// Proxy TLSSocket handle methods
11551166
function makeSocketMethodProxy(name) {
11561167
return function socketMethodProxy(...args) {
Collapse file

‎src/crypto/crypto_tls.cc‎

Copy file name to clipboardExpand all lines: src/crypto/crypto_tls.cc
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,33 @@ void TLSWrap::SetALPNProtocols(const FunctionCallbackInfo<Value>& args) {
15951595
}
15961596
}
15971597

1598+
void TLSWrap::SetKeyCert(const FunctionCallbackInfo<Value>& args) {
1599+
TLSWrap* w;
1600+
ASSIGN_OR_RETURN_UNWRAP(&w, args.This());
1601+
Environment* env = w->env();
1602+
1603+
if (w->is_client()) return;
1604+
1605+
if (args.Length() < 1 || !args[0]->IsObject())
1606+
return env->ThrowTypeError("Must give a SecureContext as first argument");
1607+
1608+
Local<Value> ctx = args[0];
1609+
if (UNLIKELY(ctx.IsEmpty())) return;
1610+
1611+
Local<FunctionTemplate> cons = env->secure_context_constructor_template();
1612+
if (cons->HasInstance(ctx)) {
1613+
SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
1614+
CHECK_NOT_NULL(sc);
1615+
if (!UseSNIContext(w->ssl_, BaseObjectPtr<SecureContext>(sc)) ||
1616+
!w->SetCACerts(sc)) {
1617+
unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1618+
return ThrowCryptoError(env, err, "SetKeyCert");
1619+
}
1620+
} else {
1621+
return env->ThrowTypeError("Must give a SecureContext as first argument");
1622+
}
1623+
}
1624+
15981625
void TLSWrap::GetPeerCertificate(const FunctionCallbackInfo<Value>& args) {
15991626
TLSWrap* w;
16001627
ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
@@ -2130,6 +2157,7 @@ void TLSWrap::Initialize(
21302157
SetProtoMethod(isolate, t, "renegotiate", Renegotiate);
21312158
SetProtoMethod(isolate, t, "requestOCSP", RequestOCSP);
21322159
SetProtoMethod(isolate, t, "setALPNProtocols", SetALPNProtocols);
2160+
SetProtoMethod(isolate, t, "setKeyCert", SetKeyCert);
21332161
SetProtoMethod(isolate, t, "setOCSPResponse", SetOCSPResponse);
21342162
SetProtoMethod(isolate, t, "setServername", SetServername);
21352163
SetProtoMethod(isolate, t, "setSession", SetSession);
Collapse file

‎src/crypto/crypto_tls.h‎

Copy file name to clipboardExpand all lines: src/crypto/crypto_tls.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ class TLSWrap : public AsyncWrap,
213213
static void Renegotiate(const v8::FunctionCallbackInfo<v8::Value>& args);
214214
static void RequestOCSP(const v8::FunctionCallbackInfo<v8::Value>& args);
215215
static void SetALPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args);
216+
static void SetKeyCert(const v8::FunctionCallbackInfo<v8::Value>& args);
216217
static void SetOCSPResponse(const v8::FunctionCallbackInfo<v8::Value>& args);
217218
static void SetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
218219
static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
Collapse file

‎test/parallel/test-tls-server-setkeycert.js‎

Copy file name to clipboard
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
const assert = require('assert');
8+
const { X509Certificate } = require('crypto');
9+
const tls = require('tls');
10+
const fixtures = require('../common/fixtures');
11+
12+
const altKeyCert = {
13+
key: fixtures.readKey('agent2-key.pem'),
14+
cert: fixtures.readKey('agent2-cert.pem'),
15+
minVersion: 'TLSv1.2',
16+
};
17+
18+
const altKeyCertVals = [
19+
altKeyCert,
20+
tls.createSecureContext(altKeyCert),
21+
];
22+
23+
(function next() {
24+
if (!altKeyCertVals.length)
25+
return;
26+
const altKeyCertVal = altKeyCertVals.shift();
27+
const options = {
28+
key: fixtures.readKey('agent1-key.pem'),
29+
cert: fixtures.readKey('agent1-cert.pem'),
30+
minVersion: 'TLSv1.3',
31+
ALPNCallback: common.mustCall(function({ servername, protocols }) {
32+
this.setKeyCert(altKeyCertVal);
33+
assert.deepStrictEqual(protocols, ['acme-tls/1']);
34+
return protocols[0];
35+
}),
36+
};
37+
38+
tls.createServer(options, (s) => s.end()).listen(0, function() {
39+
this.on('connection', common.mustCall((socket) => this.close()));
40+
41+
tls.connect({
42+
port: this.address().port,
43+
rejectUnauthorized: false,
44+
ALPNProtocols: ['acme-tls/1'],
45+
}, common.mustCall(function() {
46+
assert.strictEqual(this.getProtocol(), 'TLSv1.3');
47+
const altCert = new X509Certificate(altKeyCert.cert);
48+
assert.strictEqual(
49+
this.getPeerX509Certificate().raw.equals(altCert.raw),
50+
true
51+
);
52+
this.end();
53+
next();
54+
}));
55+
});
56+
})();

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.