1 #include "crypto/crypto_context.h"
2 #include "crypto/crypto_bio.h"
3 #include "crypto/crypto_common.h"
4 #include "crypto/crypto_util.h"
5 #include "base_object-inl.h"
6 #include "env-inl.h"
7 #include "memory_tracker-inl.h"
8 #include "node.h"
9 #include "node_buffer.h"
10 #include "node_options.h"
11 #include "util.h"
12 #include "v8.h"
13
14 #include <openssl/x509.h>
15 #include <openssl/pkcs12.h>
16 #include <openssl/rand.h>
17 #ifndef OPENSSL_NO_ENGINE
18 #include <openssl/engine.h>
19 #endif // !OPENSSL_NO_ENGINE
20
21 namespace node {
22
23 using v8::Array;
24 using v8::ArrayBufferView;
25 using v8::Boolean;
26 using v8::Context;
27 using v8::DontDelete;
28 using v8::Exception;
29 using v8::External;
30 using v8::FunctionCallbackInfo;
31 using v8::FunctionTemplate;
32 using v8::HandleScope;
33 using v8::Int32;
34 using v8::Integer;
35 using v8::Isolate;
36 using v8::Just;
37 using v8::Local;
38 using v8::Maybe;
39 using v8::Nothing;
40 using v8::Object;
41 using v8::PropertyAttribute;
42 using v8::ReadOnly;
43 using v8::Signature;
44 using v8::String;
45 using v8::Value;
46
47 namespace crypto {
48 static const char* const root_certs[] = {
49 #include "node_root_certs.h" // NOLINT(build/include_order)
50 };
51
52 static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
53
54 static bool extra_root_certs_loaded = false;
55
GetOrCreateRootCertStore()56 inline X509_STORE* GetOrCreateRootCertStore() {
57 // Guaranteed thread-safe by standard, just don't use -fno-threadsafe-statics.
58 static X509_STORE* store = NewRootCertStore();
59 return store;
60 }
61
62 // Takes a string or buffer and loads it into a BIO.
63 // Caller responsible for BIO_free_all-ing the returned object.
LoadBIO(Environment * env,Local<Value> v)64 BIOPointer LoadBIO(Environment* env, Local<Value> v) {
65 if (v->IsString() || v->IsArrayBufferView()) {
66 BIOPointer bio(BIO_new(BIO_s_secmem()));
67 if (!bio) return nullptr;
68 ByteSource bsrc = ByteSource::FromStringOrBuffer(env, v);
69 if (bsrc.size() > INT_MAX) return nullptr;
70 int written = BIO_write(bio.get(), bsrc.data<char>(), bsrc.size());
71 if (written < 0) return nullptr;
72 if (static_cast<size_t>(written) != bsrc.size()) return nullptr;
73 return bio;
74 }
75 return nullptr;
76 }
77
78 namespace {
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,X509Pointer && x,STACK_OF (X509)* extra_certs,X509Pointer * cert,X509Pointer * issuer_)79 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
80 X509Pointer&& x,
81 STACK_OF(X509)* extra_certs,
82 X509Pointer* cert,
83 X509Pointer* issuer_) {
84 CHECK(!*issuer_);
85 CHECK(!*cert);
86 X509* issuer = nullptr;
87
88 int ret = SSL_CTX_use_certificate(ctx, x.get());
89
90 if (ret) {
91 // If we could set up our certificate, now proceed to
92 // the CA certificates.
93 SSL_CTX_clear_extra_chain_certs(ctx);
94
95 for (int i = 0; i < sk_X509_num(extra_certs); i++) {
96 X509* ca = sk_X509_value(extra_certs, i);
97
98 // NOTE: Increments reference count on `ca`
99 if (!SSL_CTX_add1_chain_cert(ctx, ca)) {
100 ret = 0;
101 issuer = nullptr;
102 break;
103 }
104 // Note that we must not free r if it was successfully
105 // added to the chain (while we must free the main
106 // certificate, since its reference count is increased
107 // by SSL_CTX_use_certificate).
108
109 // Find issuer
110 if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
111 continue;
112
113 issuer = ca;
114 }
115 }
116
117 // Try getting issuer from a cert store
118 if (ret) {
119 if (issuer == nullptr) {
120 // TODO(tniessen): SSL_CTX_get_issuer does not allow the caller to
121 // distinguish between a failed operation and an empty result. Fix that
122 // and then handle the potential error properly here (set ret to 0).
123 *issuer_ = SSL_CTX_get_issuer(ctx, x.get());
124 // NOTE: get_cert_store doesn't increment reference count,
125 // no need to free `store`
126 } else {
127 // Increment issuer reference count
128 issuer_->reset(X509_dup(issuer));
129 if (!*issuer_) {
130 ret = 0;
131 }
132 }
133 }
134
135 if (ret && x != nullptr) {
136 cert->reset(X509_dup(x.get()));
137 if (!*cert)
138 ret = 0;
139 }
140 return ret;
141 }
142
143 // Read a file that contains our certificate in "PEM" format,
144 // possibly followed by a sequence of CA certificates that should be
145 // sent to the peer in the Certificate message.
146 //
147 // Taken from OpenSSL - edited for style.
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,BIOPointer && in,X509Pointer * cert,X509Pointer * issuer)148 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
149 BIOPointer&& in,
150 X509Pointer* cert,
151 X509Pointer* issuer) {
152 // Just to ensure that `ERR_peek_last_error` below will return only errors
153 // that we are interested in
154 ERR_clear_error();
155
156 X509Pointer x(
157 PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
158
159 if (!x)
160 return 0;
161
162 unsigned long err = 0; // NOLINT(runtime/int)
163
164 StackOfX509 extra_certs(sk_X509_new_null());
165 if (!extra_certs)
166 return 0;
167
168 while (X509Pointer extra {PEM_read_bio_X509(in.get(),
169 nullptr,
170 NoPasswordCallback,
171 nullptr)}) {
172 if (sk_X509_push(extra_certs.get(), extra.get())) {
173 extra.release();
174 continue;
175 }
176
177 return 0;
178 }
179
180 // When the while loop ends, it's usually just EOF.
181 err = ERR_peek_last_error();
182 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
183 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
184 ERR_clear_error();
185 } else {
186 // some real error
187 return 0;
188 }
189
190 return SSL_CTX_use_certificate_chain(ctx,
191 std::move(x),
192 extra_certs.get(),
193 cert,
194 issuer);
195 }
196
197 } // namespace
198
NewRootCertStore()199 X509_STORE* NewRootCertStore() {
200 static std::vector<X509*> root_certs_vector;
201 static Mutex root_certs_vector_mutex;
202 Mutex::ScopedLock lock(root_certs_vector_mutex);
203
204 if (root_certs_vector.empty() &&
205 per_process::cli_options->ssl_openssl_cert_store == false) {
206 for (size_t i = 0; i < arraysize(root_certs); i++) {
207 X509* x509 =
208 PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
209 strlen(root_certs[i])).get(),
210 nullptr, // no re-use of X509 structure
211 NoPasswordCallback,
212 nullptr); // no callback data
213
214 // Parse errors from the built-in roots are fatal.
215 CHECK_NOT_NULL(x509);
216
217 root_certs_vector.push_back(x509);
218 }
219 }
220
221 X509_STORE* store = X509_STORE_new();
222 if (*system_cert_path != '\0') {
223 ERR_set_mark();
224 X509_STORE_load_locations(store, system_cert_path, nullptr);
225 ERR_pop_to_mark();
226 }
227
228 Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
229 if (per_process::cli_options->ssl_openssl_cert_store) {
230 X509_STORE_set_default_paths(store);
231 } else {
232 for (X509* cert : root_certs_vector) {
233 X509_up_ref(cert);
234 X509_STORE_add_cert(store, cert);
235 }
236 }
237
238 return store;
239 }
240
GetRootCertificates(const FunctionCallbackInfo<Value> & args)241 void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
242 Environment* env = Environment::GetCurrent(args);
243 Local<Value> result[arraysize(root_certs)];
244
245 for (size_t i = 0; i < arraysize(root_certs); i++) {
246 if (!String::NewFromOneByte(
247 env->isolate(),
248 reinterpret_cast<const uint8_t*>(root_certs[i]))
249 .ToLocal(&result[i])) {
250 return;
251 }
252 }
253
254 args.GetReturnValue().Set(
255 Array::New(env->isolate(), result, arraysize(root_certs)));
256 }
257
HasInstance(Environment * env,const Local<Value> & value)258 bool SecureContext::HasInstance(Environment* env, const Local<Value>& value) {
259 return GetConstructorTemplate(env)->HasInstance(value);
260 }
261
GetConstructorTemplate(Environment * env)262 Local<FunctionTemplate> SecureContext::GetConstructorTemplate(
263 Environment* env) {
264 Local<FunctionTemplate> tmpl = env->secure_context_constructor_template();
265 if (tmpl.IsEmpty()) {
266 Isolate* isolate = env->isolate();
267 tmpl = NewFunctionTemplate(isolate, New);
268 tmpl->InstanceTemplate()->SetInternalFieldCount(
269 SecureContext::kInternalFieldCount);
270 tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
271 tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
272
273 SetProtoMethod(isolate, tmpl, "init", Init);
274 SetProtoMethod(isolate, tmpl, "setKey", SetKey);
275 SetProtoMethod(isolate, tmpl, "setCert", SetCert);
276 SetProtoMethod(isolate, tmpl, "addCACert", AddCACert);
277 SetProtoMethod(isolate, tmpl, "addCRL", AddCRL);
278 SetProtoMethod(isolate, tmpl, "addRootCerts", AddRootCerts);
279 SetProtoMethod(isolate, tmpl, "setCipherSuites", SetCipherSuites);
280 SetProtoMethod(isolate, tmpl, "setCiphers", SetCiphers);
281 SetProtoMethod(isolate, tmpl, "setSigalgs", SetSigalgs);
282 SetProtoMethod(isolate, tmpl, "setECDHCurve", SetECDHCurve);
283 SetProtoMethod(isolate, tmpl, "setDHParam", SetDHParam);
284 SetProtoMethod(isolate, tmpl, "setMaxProto", SetMaxProto);
285 SetProtoMethod(isolate, tmpl, "setMinProto", SetMinProto);
286 SetProtoMethod(isolate, tmpl, "getMaxProto", GetMaxProto);
287 SetProtoMethod(isolate, tmpl, "getMinProto", GetMinProto);
288 SetProtoMethod(isolate, tmpl, "setOptions", SetOptions);
289 SetProtoMethod(isolate, tmpl, "setSessionIdContext", SetSessionIdContext);
290 SetProtoMethod(isolate, tmpl, "setSessionTimeout", SetSessionTimeout);
291 SetProtoMethod(isolate, tmpl, "close", Close);
292 SetProtoMethod(isolate, tmpl, "loadPKCS12", LoadPKCS12);
293 SetProtoMethod(isolate, tmpl, "setTicketKeys", SetTicketKeys);
294 SetProtoMethod(
295 isolate, tmpl, "enableTicketKeyCallback", EnableTicketKeyCallback);
296
297 SetProtoMethodNoSideEffect(isolate, tmpl, "getTicketKeys", GetTicketKeys);
298 SetProtoMethodNoSideEffect(
299 isolate, tmpl, "getCertificate", GetCertificate<true>);
300 SetProtoMethodNoSideEffect(
301 isolate, tmpl, "getIssuer", GetCertificate<false>);
302
303 #ifndef OPENSSL_NO_ENGINE
304 SetProtoMethod(isolate, tmpl, "setEngineKey", SetEngineKey);
305 SetProtoMethod(isolate, tmpl, "setClientCertEngine", SetClientCertEngine);
306 #endif // !OPENSSL_NO_ENGINE
307
308 #define SET_INTEGER_CONSTANTS(name, value) \
309 tmpl->Set(FIXED_ONE_BYTE_STRING(isolate, name), \
310 Integer::NewFromUnsigned(isolate, value));
311 SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
312 SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
313 SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
314 SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
315 SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex);
316 #undef SET_INTEGER_CONSTANTS
317
318 Local<FunctionTemplate> ctx_getter_templ = FunctionTemplate::New(
319 isolate, CtxGetter, Local<Value>(), Signature::New(isolate, tmpl));
320
321 tmpl->PrototypeTemplate()->SetAccessorProperty(
322 FIXED_ONE_BYTE_STRING(isolate, "_external"),
323 ctx_getter_templ,
324 Local<FunctionTemplate>(),
325 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
326
327 env->set_secure_context_constructor_template(tmpl);
328 }
329 return tmpl;
330 }
331
Initialize(Environment * env,Local<Object> target)332 void SecureContext::Initialize(Environment* env, Local<Object> target) {
333 Local<Context> context = env->context();
334 SetConstructorFunction(context,
335 target,
336 "SecureContext",
337 GetConstructorTemplate(env),
338 SetConstructorFunctionFlag::NONE);
339
340 SetMethodNoSideEffect(
341 context, target, "getRootCertificates", GetRootCertificates);
342 // Exposed for testing purposes only.
343 SetMethodNoSideEffect(context,
344 target,
345 "isExtraRootCertsFileLoaded",
346 IsExtraRootCertsFileLoaded);
347 }
348
RegisterExternalReferences(ExternalReferenceRegistry * registry)349 void SecureContext::RegisterExternalReferences(
350 ExternalReferenceRegistry* registry) {
351 registry->Register(New);
352 registry->Register(Init);
353 registry->Register(SetKey);
354 registry->Register(SetCert);
355 registry->Register(AddCACert);
356 registry->Register(AddCRL);
357 registry->Register(AddRootCerts);
358 registry->Register(SetCipherSuites);
359 registry->Register(SetCiphers);
360 registry->Register(SetSigalgs);
361 registry->Register(SetECDHCurve);
362 registry->Register(SetDHParam);
363 registry->Register(SetMaxProto);
364 registry->Register(SetMinProto);
365 registry->Register(GetMaxProto);
366 registry->Register(GetMinProto);
367 registry->Register(SetOptions);
368 registry->Register(SetSessionIdContext);
369 registry->Register(SetSessionTimeout);
370 registry->Register(Close);
371 registry->Register(LoadPKCS12);
372 registry->Register(SetTicketKeys);
373 registry->Register(EnableTicketKeyCallback);
374 registry->Register(GetTicketKeys);
375 registry->Register(GetCertificate<true>);
376 registry->Register(GetCertificate<false>);
377
378 #ifndef OPENSSL_NO_ENGINE
379 registry->Register(SetEngineKey);
380 registry->Register(SetClientCertEngine);
381 #endif // !OPENSSL_NO_ENGINE
382
383 registry->Register(CtxGetter);
384
385 registry->Register(GetRootCertificates);
386 registry->Register(IsExtraRootCertsFileLoaded);
387 }
388
Create(Environment * env)389 SecureContext* SecureContext::Create(Environment* env) {
390 Local<Object> obj;
391 if (!GetConstructorTemplate(env)
392 ->InstanceTemplate()
393 ->NewInstance(env->context()).ToLocal(&obj)) {
394 return nullptr;
395 }
396
397 return new SecureContext(env, obj);
398 }
399
SecureContext(Environment * env,Local<Object> wrap)400 SecureContext::SecureContext(Environment* env, Local<Object> wrap)
401 : BaseObject(env, wrap) {
402 MakeWeak();
403 env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
404 }
405
Reset()406 inline void SecureContext::Reset() {
407 if (ctx_ != nullptr) {
408 env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
409 }
410 ctx_.reset();
411 cert_.reset();
412 issuer_.reset();
413 }
414
~SecureContext()415 SecureContext::~SecureContext() {
416 Reset();
417 }
418
New(const FunctionCallbackInfo<Value> & args)419 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
420 Environment* env = Environment::GetCurrent(args);
421 new SecureContext(env, args.This());
422 }
423
Init(const FunctionCallbackInfo<Value> & args)424 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
425 SecureContext* sc;
426 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
427 Environment* env = sc->env();
428
429 CHECK_EQ(args.Length(), 3);
430 CHECK(args[1]->IsInt32());
431 CHECK(args[2]->IsInt32());
432
433 int min_version = args[1].As<Int32>()->Value();
434 int max_version = args[2].As<Int32>()->Value();
435 const SSL_METHOD* method = TLS_method();
436
437 if (max_version == 0)
438 max_version = kMaxSupportedVersion;
439
440 if (args[0]->IsString()) {
441 Utf8Value sslmethod(env->isolate(), args[0]);
442
443 // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
444 // are still accepted. They are OpenSSL's way of saying that all known
445 // protocols below TLS 1.3 are supported unless explicitly disabled (which
446 // we do below for SSLv2 and SSLv3.)
447 if (sslmethod == "SSLv2_method" ||
448 sslmethod == "SSLv2_server_method" ||
449 sslmethod == "SSLv2_client_method") {
450 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
451 return;
452 } else if (sslmethod == "SSLv3_method" ||
453 sslmethod == "SSLv3_server_method" ||
454 sslmethod == "SSLv3_client_method") {
455 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled");
456 return;
457 } else if (sslmethod == "SSLv23_method") {
458 max_version = TLS1_2_VERSION;
459 } else if (sslmethod == "SSLv23_server_method") {
460 max_version = TLS1_2_VERSION;
461 method = TLS_server_method();
462 } else if (sslmethod == "SSLv23_client_method") {
463 max_version = TLS1_2_VERSION;
464 method = TLS_client_method();
465 } else if (sslmethod == "TLS_method") {
466 min_version = 0;
467 max_version = kMaxSupportedVersion;
468 } else if (sslmethod == "TLS_server_method") {
469 min_version = 0;
470 max_version = kMaxSupportedVersion;
471 method = TLS_server_method();
472 } else if (sslmethod == "TLS_client_method") {
473 min_version = 0;
474 max_version = kMaxSupportedVersion;
475 method = TLS_client_method();
476 } else if (sslmethod == "TLSv1_method") {
477 min_version = TLS1_VERSION;
478 max_version = TLS1_VERSION;
479 } else if (sslmethod == "TLSv1_server_method") {
480 min_version = TLS1_VERSION;
481 max_version = TLS1_VERSION;
482 method = TLS_server_method();
483 } else if (sslmethod == "TLSv1_client_method") {
484 min_version = TLS1_VERSION;
485 max_version = TLS1_VERSION;
486 method = TLS_client_method();
487 } else if (sslmethod == "TLSv1_1_method") {
488 min_version = TLS1_1_VERSION;
489 max_version = TLS1_1_VERSION;
490 } else if (sslmethod == "TLSv1_1_server_method") {
491 min_version = TLS1_1_VERSION;
492 max_version = TLS1_1_VERSION;
493 method = TLS_server_method();
494 } else if (sslmethod == "TLSv1_1_client_method") {
495 min_version = TLS1_1_VERSION;
496 max_version = TLS1_1_VERSION;
497 method = TLS_client_method();
498 } else if (sslmethod == "TLSv1_2_method") {
499 min_version = TLS1_2_VERSION;
500 max_version = TLS1_2_VERSION;
501 } else if (sslmethod == "TLSv1_2_server_method") {
502 min_version = TLS1_2_VERSION;
503 max_version = TLS1_2_VERSION;
504 method = TLS_server_method();
505 } else if (sslmethod == "TLSv1_2_client_method") {
506 min_version = TLS1_2_VERSION;
507 max_version = TLS1_2_VERSION;
508 method = TLS_client_method();
509 } else {
510 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(
511 env, "Unknown method: %s", *sslmethod);
512 return;
513 }
514 }
515
516 sc->ctx_.reset(SSL_CTX_new(method));
517 if (!sc->ctx_) {
518 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new");
519 }
520 SSL_CTX_set_app_data(sc->ctx_.get(), sc);
521
522 // Disable SSLv2 in the case when method == TLS_method() and the
523 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
524 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
525 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
526 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2);
527 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3);
528 #if OPENSSL_VERSION_MAJOR >= 3
529 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_ALLOW_CLIENT_RENEGOTIATION);
530 #endif
531
532 // Enable automatic cert chaining. This is enabled by default in OpenSSL, but
533 // disabled by default in BoringSSL. Enable it explicitly to make the
534 // behavior match when Node is built with BoringSSL.
535 SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
536
537 // SSL session cache configuration
538 SSL_CTX_set_session_cache_mode(sc->ctx_.get(),
539 SSL_SESS_CACHE_CLIENT |
540 SSL_SESS_CACHE_SERVER |
541 SSL_SESS_CACHE_NO_INTERNAL |
542 SSL_SESS_CACHE_NO_AUTO_CLEAR);
543
544 SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
545 SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
546
547 // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
548 // exposed in the public API. To retain compatibility, install a callback
549 // which restores the old algorithm.
550 if (CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)).is_err() ||
551 CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)).is_err() ||
552 CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)).is_err()) {
553 return THROW_ERR_CRYPTO_OPERATION_FAILED(
554 env, "Error generating ticket keys");
555 }
556 SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
557 }
558
CreateSSL()559 SSLPointer SecureContext::CreateSSL() {
560 return SSLPointer(SSL_new(ctx_.get()));
561 }
562
SetNewSessionCallback(NewSessionCb cb)563 void SecureContext::SetNewSessionCallback(NewSessionCb cb) {
564 SSL_CTX_sess_set_new_cb(ctx_.get(), cb);
565 }
566
SetGetSessionCallback(GetSessionCb cb)567 void SecureContext::SetGetSessionCallback(GetSessionCb cb) {
568 SSL_CTX_sess_set_get_cb(ctx_.get(), cb);
569 }
570
SetSelectSNIContextCallback(SelectSNIContextCb cb)571 void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) {
572 SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb);
573 }
574
SetKeylogCallback(KeylogCb cb)575 void SecureContext::SetKeylogCallback(KeylogCb cb) {
576 SSL_CTX_set_keylog_callback(ctx_.get(), cb);
577 }
578
UseKey(Environment * env,std::shared_ptr<KeyObjectData> key)579 Maybe<bool> SecureContext::UseKey(Environment* env,
580 std::shared_ptr<KeyObjectData> key) {
581 if (key->GetKeyType() != KeyType::kKeyTypePrivate) {
582 THROW_ERR_CRYPTO_INVALID_KEYTYPE(env);
583 return Nothing<bool>();
584 }
585
586 ClearErrorOnReturn clear_error_on_return;
587 if (!SSL_CTX_use_PrivateKey(ctx_.get(), key->GetAsymmetricKey().get())) {
588 ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
589 return Nothing<bool>();
590 }
591
592 return Just(true);
593 }
594
SetKey(const FunctionCallbackInfo<Value> & args)595 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
596 Environment* env = Environment::GetCurrent(args);
597
598 SecureContext* sc;
599 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
600
601 CHECK_GE(args.Length(), 1); // Private key argument is mandatory
602
603 BIOPointer bio(LoadBIO(env, args[0]));
604 if (!bio)
605 return;
606
607 ByteSource passphrase;
608 if (args[1]->IsString())
609 passphrase = ByteSource::FromString(env, args[1].As<String>());
610 // This redirection is necessary because the PasswordCallback expects a
611 // pointer to a pointer to the passphrase ByteSource to allow passing in
612 // const ByteSources.
613 const ByteSource* pass_ptr = &passphrase;
614
615 EVPKeyPointer key(
616 PEM_read_bio_PrivateKey(bio.get(),
617 nullptr,
618 PasswordCallback,
619 &pass_ptr));
620
621 if (!key)
622 return ThrowCryptoError(env, ERR_get_error(), "PEM_read_bio_PrivateKey");
623
624 if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
625 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
626 }
627
SetSigalgs(const FunctionCallbackInfo<Value> & args)628 void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
629 SecureContext* sc;
630 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
631 Environment* env = sc->env();
632 ClearErrorOnReturn clear_error_on_return;
633
634 CHECK_EQ(args.Length(), 1);
635 CHECK(args[0]->IsString());
636
637 const Utf8Value sigalgs(env->isolate(), args[0]);
638
639 if (!SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs))
640 return ThrowCryptoError(env, ERR_get_error());
641 }
642
643 #ifndef OPENSSL_NO_ENGINE
SetEngineKey(const FunctionCallbackInfo<Value> & args)644 void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
645 Environment* env = Environment::GetCurrent(args);
646
647 SecureContext* sc;
648 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
649
650 CHECK_EQ(args.Length(), 2);
651
652 CryptoErrorStore errors;
653 Utf8Value engine_id(env->isolate(), args[1]);
654 EnginePointer engine = LoadEngineById(*engine_id, &errors);
655 if (!engine) {
656 Local<Value> exception;
657 if (errors.ToException(env).ToLocal(&exception))
658 env->isolate()->ThrowException(exception);
659 return;
660 }
661
662 if (!ENGINE_init(engine.get())) {
663 return THROW_ERR_CRYPTO_OPERATION_FAILED(
664 env, "Failure to initialize engine");
665 }
666
667 engine.finish_on_exit = true;
668
669 Utf8Value key_name(env->isolate(), args[0]);
670 EVPKeyPointer key(ENGINE_load_private_key(engine.get(), *key_name,
671 nullptr, nullptr));
672
673 if (!key)
674 return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
675
676 if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
677 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
678
679 sc->private_key_engine_ = std::move(engine);
680 }
681 #endif // !OPENSSL_NO_ENGINE
682
AddCert(Environment * env,BIOPointer && bio)683 Maybe<bool> SecureContext::AddCert(Environment* env, BIOPointer&& bio) {
684 ClearErrorOnReturn clear_error_on_return;
685 if (!bio) return Just(false);
686 cert_.reset();
687 issuer_.reset();
688
689 // The SSL_CTX_use_certificate_chain call here is not from openssl, this is
690 // the method implemented elsewhere in this file. The naming is a bit
691 // confusing, unfortunately.
692 if (SSL_CTX_use_certificate_chain(
693 ctx_.get(), std::move(bio), &cert_, &issuer_) == 0) {
694 ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_certificate_chain");
695 return Nothing<bool>();
696 }
697 return Just(true);
698 }
699
SetCert(const FunctionCallbackInfo<Value> & args)700 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
701 Environment* env = Environment::GetCurrent(args);
702
703 SecureContext* sc;
704 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
705
706 CHECK_GE(args.Length(), 1); // Certificate argument is mandatory
707
708 BIOPointer bio(LoadBIO(env, args[0]));
709 USE(sc->AddCert(env, std::move(bio)));
710 }
711
SetCACert(const BIOPointer & bio)712 void SecureContext::SetCACert(const BIOPointer& bio) {
713 ClearErrorOnReturn clear_error_on_return;
714 if (!bio) return;
715 X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get());
716 while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509_AUX(
717 bio.get(), nullptr, NoPasswordCallback, nullptr))) {
718 if (cert_store == GetOrCreateRootCertStore()) {
719 cert_store = NewRootCertStore();
720 SSL_CTX_set_cert_store(ctx_.get(), cert_store);
721 }
722 CHECK_EQ(1, X509_STORE_add_cert(cert_store, x509.get()));
723 CHECK_EQ(1, SSL_CTX_add_client_CA(ctx_.get(), x509.get()));
724 }
725 }
726
AddCACert(const FunctionCallbackInfo<Value> & args)727 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
728 Environment* env = Environment::GetCurrent(args);
729
730 SecureContext* sc;
731 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
732
733 CHECK_GE(args.Length(), 1); // CA certificate argument is mandatory
734
735 BIOPointer bio(LoadBIO(env, args[0]));
736 sc->SetCACert(bio);
737 }
738
SetCRL(Environment * env,const BIOPointer & bio)739 Maybe<bool> SecureContext::SetCRL(Environment* env, const BIOPointer& bio) {
740 ClearErrorOnReturn clear_error_on_return;
741 if (!bio) return Just(false);
742
743 DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
744 PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
745
746 if (!crl) {
747 THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to parse CRL");
748 return Nothing<bool>();
749 }
750
751 X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get());
752 if (cert_store == GetOrCreateRootCertStore()) {
753 cert_store = NewRootCertStore();
754 SSL_CTX_set_cert_store(ctx_.get(), cert_store);
755 }
756
757 CHECK_EQ(1, X509_STORE_add_crl(cert_store, crl.get()));
758 CHECK_EQ(1,
759 X509_STORE_set_flags(
760 cert_store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL));
761 return Just(true);
762 }
763
AddCRL(const FunctionCallbackInfo<Value> & args)764 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
765 Environment* env = Environment::GetCurrent(args);
766
767 SecureContext* sc;
768 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
769
770 CHECK_GE(args.Length(), 1); // CRL argument is mandatory
771
772 BIOPointer bio(LoadBIO(env, args[0]));
773 USE(sc->SetCRL(env, bio));
774 }
775
SetRootCerts()776 void SecureContext::SetRootCerts() {
777 ClearErrorOnReturn clear_error_on_return;
778 auto store = GetOrCreateRootCertStore();
779
780 // Increment reference count so global store is not deleted along with CTX.
781 X509_STORE_up_ref(store);
782 SSL_CTX_set_cert_store(ctx_.get(), store);
783 }
784
AddRootCerts(const FunctionCallbackInfo<Value> & args)785 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
786 SecureContext* sc;
787 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
788 sc->SetRootCerts();
789 }
790
SetCipherSuites(const FunctionCallbackInfo<Value> & args)791 void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
792 // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
793 #ifndef OPENSSL_IS_BORINGSSL
794 SecureContext* sc;
795 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
796 Environment* env = sc->env();
797 ClearErrorOnReturn clear_error_on_return;
798
799 CHECK_EQ(args.Length(), 1);
800 CHECK(args[0]->IsString());
801
802 const Utf8Value ciphers(env->isolate(), args[0]);
803 if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
804 return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
805 #endif
806 }
807
SetCiphers(const FunctionCallbackInfo<Value> & args)808 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
809 SecureContext* sc;
810 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
811 Environment* env = sc->env();
812 ClearErrorOnReturn clear_error_on_return;
813
814 CHECK_EQ(args.Length(), 1);
815 CHECK(args[0]->IsString());
816
817 Utf8Value ciphers(env->isolate(), args[0]);
818 if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
819 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
820
821 if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
822 // TLS1.2 ciphers were deliberately cleared, so don't consider
823 // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
824 // works). If the user actually sets a value (like "no-such-cipher"), then
825 // that's actually an error.
826 return;
827 }
828 return ThrowCryptoError(env, err, "Failed to set ciphers");
829 }
830 }
831
SetECDHCurve(const FunctionCallbackInfo<Value> & args)832 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
833 SecureContext* sc;
834 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
835 Environment* env = sc->env();
836
837 CHECK_GE(args.Length(), 1); // ECDH curve name argument is mandatory
838 CHECK(args[0]->IsString());
839
840 Utf8Value curve(env->isolate(), args[0]);
841
842 if (curve != "auto" && !SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve)) {
843 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set ECDH curve");
844 }
845 }
846
SetDHParam(const FunctionCallbackInfo<Value> & args)847 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
848 SecureContext* sc;
849 ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
850 Environment* env = sc->env();
851 ClearErrorOnReturn clear_error_on_return;
852
853 CHECK_GE(args.Length(), 1); // DH argument is mandatory
854
855 // If the user specified "auto" for dhparams, the JavaScript layer will pass
856 // true to this function instead of the original string. Any other string
857 // value will be interpreted as custom DH parameters below.
858 if (args[0]->IsTrue()) {
859 CHECK(SSL_CTX_set_dh_auto(sc->ctx_.get(), true));
860 return;
861 }
862
863 DHPointer dh;
864 {
865 BIOPointer bio(LoadBIO(env, args[0]));
866 if (!bio)
867 return;
868
869 dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
870 }
871
872 // Invalid dhparam is silently discarded and DHE is no longer used.
873 // TODO(tniessen): don't silently discard invalid dhparam.
874 if (!dh)
875 return;
876
877 const BIGNUM* p;
878 DH_get0_pqg(dh.get(), &p, nullptr, nullptr);
879 const int size = BN_num_bits(p);
880 if (size < 1024) {
881 return THROW_ERR_INVALID_ARG_VALUE(
882 env, "DH parameter is less than 1024 bits");
883 } else if (size < 2048) {
884 args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(
885 env->isolate(), "DH parameter is less than 2048 bits"));
886 }
887
888 if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) {
889 return THROW_ERR_CRYPTO_OPERATION_FAILED(
890 env, "Error setting temp DH parameter");
891 }
892 }
893
SetMinProto(const FunctionCallbackInfo<Value> & args)894 void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
895 SecureContext* sc;
896 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
897
898 CHECK_EQ(args.Length(), 1);
899 CHECK(args[0]->IsInt32());
900
901 int version = args[0].As<Int32>()->Value();
902
903 CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
904 }
905
SetMaxProto(const FunctionCallbackInfo<Value> & args)906 void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
907 SecureContext* sc;
908 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
909
910 CHECK_EQ(args.Length(), 1);
911 CHECK(args[0]->IsInt32());
912
913 int version = args[0].As<Int32>()->Value();
914
915 CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
916 }
917
GetMinProto(const FunctionCallbackInfo<Value> & args)918 void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
919 SecureContext* sc;
920 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
921
922 CHECK_EQ(args.Length(), 0);
923
924 long version = // NOLINT(runtime/int)
925 SSL_CTX_get_min_proto_version(sc->ctx_.get());
926 args.GetReturnValue().Set(static_cast<uint32_t>(version));
927 }
928
GetMaxProto(const FunctionCallbackInfo<Value> & args)929 void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
930 SecureContext* sc;
931 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
932
933 CHECK_EQ(args.Length(), 0);
934
935 long version = // NOLINT(runtime/int)
936 SSL_CTX_get_max_proto_version(sc->ctx_.get());
937 args.GetReturnValue().Set(static_cast<uint32_t>(version));
938 }
939
SetOptions(const FunctionCallbackInfo<Value> & args)940 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
941 Environment* env = Environment::GetCurrent(args);
942 SecureContext* sc;
943 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
944
945 CHECK_GE(args.Length(), 1);
946 CHECK(args[0]->IsNumber());
947
948 int64_t val = args[0]->IntegerValue(env->context()).FromMaybe(0);
949
950 SSL_CTX_set_options(sc->ctx_.get(),
951 static_cast<long>(val)); // NOLINT(runtime/int)
952 }
953
SetSessionIdContext(const FunctionCallbackInfo<Value> & args)954 void SecureContext::SetSessionIdContext(
955 const FunctionCallbackInfo<Value>& args) {
956 SecureContext* sc;
957 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
958 Environment* env = sc->env();
959
960 CHECK_GE(args.Length(), 1);
961 CHECK(args[0]->IsString());
962
963 const Utf8Value sessionIdContext(env->isolate(), args[0]);
964 const unsigned char* sid_ctx =
965 reinterpret_cast<const unsigned char*>(*sessionIdContext);
966 unsigned int sid_ctx_len = sessionIdContext.length();
967
968 if (SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len) == 1)
969 return;
970
971 BUF_MEM* mem;
972 Local<String> message;
973
974 BIOPointer bio(BIO_new(BIO_s_mem()));
975 if (!bio) {
976 message = FIXED_ONE_BYTE_STRING(env->isolate(),
977 "SSL_CTX_set_session_id_context error");
978 } else {
979 ERR_print_errors(bio.get());
980 BIO_get_mem_ptr(bio.get(), &mem);
981 message = OneByteString(env->isolate(), mem->data, mem->length);
982 }
983
984 env->isolate()->ThrowException(Exception::TypeError(message));
985 }
986
SetSessionTimeout(const FunctionCallbackInfo<Value> & args)987 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
988 SecureContext* sc;
989 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
990
991 CHECK_GE(args.Length(), 1);
992 CHECK(args[0]->IsInt32());
993
994 int32_t sessionTimeout = args[0].As<Int32>()->Value();
995 SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout);
996 }
997
Close(const FunctionCallbackInfo<Value> & args)998 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
999 SecureContext* sc;
1000 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1001 sc->Reset();
1002 }
1003
1004 // Takes .pfx or .p12 and password in string or buffer format
LoadPKCS12(const FunctionCallbackInfo<Value> & args)1005 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
1006 Environment* env = Environment::GetCurrent(args);
1007
1008 std::vector<char> pass;
1009 bool ret = false;
1010
1011 SecureContext* sc;
1012 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1013 ClearErrorOnReturn clear_error_on_return;
1014
1015 if (args.Length() < 1) {
1016 return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory");
1017 }
1018
1019 BIOPointer in(LoadBIO(env, args[0]));
1020 if (!in) {
1021 return THROW_ERR_CRYPTO_OPERATION_FAILED(
1022 env, "Unable to load PFX certificate");
1023 }
1024
1025 if (args.Length() >= 2) {
1026 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase");
1027 Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>();
1028 size_t passlen = abv->ByteLength();
1029 pass.resize(passlen + 1);
1030 abv->CopyContents(pass.data(), passlen);
1031 pass[passlen] = '\0';
1032 }
1033
1034 // Free previous certs
1035 sc->issuer_.reset();
1036 sc->cert_.reset();
1037
1038 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1039
1040 DeleteFnPtr<PKCS12, PKCS12_free> p12;
1041 EVPKeyPointer pkey;
1042 X509Pointer cert;
1043 StackOfX509 extra_certs;
1044
1045 PKCS12* p12_ptr = nullptr;
1046 EVP_PKEY* pkey_ptr = nullptr;
1047 X509* cert_ptr = nullptr;
1048 STACK_OF(X509)* extra_certs_ptr = nullptr;
1049 if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
1050 (p12.reset(p12_ptr), true) && // Move ownership to the smart pointer.
1051 PKCS12_parse(p12.get(), pass.data(),
1052 &pkey_ptr,
1053 &cert_ptr,
1054 &extra_certs_ptr) &&
1055 (pkey.reset(pkey_ptr), cert.reset(cert_ptr),
1056 extra_certs.reset(extra_certs_ptr), true) && // Move ownership.
1057 SSL_CTX_use_certificate_chain(sc->ctx_.get(),
1058 std::move(cert),
1059 extra_certs.get(),
1060 &sc->cert_,
1061 &sc->issuer_) &&
1062 SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
1063 // Add CA certs too
1064 for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
1065 X509* ca = sk_X509_value(extra_certs.get(), i);
1066
1067 if (cert_store == GetOrCreateRootCertStore()) {
1068 cert_store = NewRootCertStore();
1069 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1070 }
1071 X509_STORE_add_cert(cert_store, ca);
1072 SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
1073 }
1074 ret = true;
1075 }
1076
1077 if (!ret) {
1078 // TODO(@jasnell): Should this use ThrowCryptoError?
1079 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1080 const char* str = ERR_reason_error_string(err);
1081 str = str != nullptr ? str : "Unknown error";
1082
1083 return env->ThrowError(str);
1084 }
1085 }
1086
1087 #ifndef OPENSSL_NO_ENGINE
SetClientCertEngine(const FunctionCallbackInfo<Value> & args)1088 void SecureContext::SetClientCertEngine(
1089 const FunctionCallbackInfo<Value>& args) {
1090 Environment* env = Environment::GetCurrent(args);
1091 CHECK_EQ(args.Length(), 1);
1092 CHECK(args[0]->IsString());
1093
1094 SecureContext* sc;
1095 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1096
1097 MarkPopErrorOnReturn mark_pop_error_on_return;
1098
1099 // SSL_CTX_set_client_cert_engine does not itself support multiple
1100 // calls by cleaning up before overwriting the client_cert_engine
1101 // internal context variable.
1102 // Instead of trying to fix up this problem we in turn also do not
1103 // support multiple calls to SetClientCertEngine.
1104 CHECK(!sc->client_cert_engine_provided_);
1105
1106 CryptoErrorStore errors;
1107 const Utf8Value engine_id(env->isolate(), args[0]);
1108 EnginePointer engine = LoadEngineById(*engine_id, &errors);
1109 if (!engine) {
1110 Local<Value> exception;
1111 if (errors.ToException(env).ToLocal(&exception))
1112 env->isolate()->ThrowException(exception);
1113 return;
1114 }
1115
1116 // Note that this takes another reference to `engine`.
1117 if (!SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get()))
1118 return ThrowCryptoError(env, ERR_get_error());
1119 sc->client_cert_engine_provided_ = true;
1120 }
1121 #endif // !OPENSSL_NO_ENGINE
1122
GetTicketKeys(const FunctionCallbackInfo<Value> & args)1123 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1124 SecureContext* wrap;
1125 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1126
1127 Local<Object> buff;
1128 if (!Buffer::New(wrap->env(), 48).ToLocal(&buff))
1129 return;
1130
1131 memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
1132 memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
1133 memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
1134
1135 args.GetReturnValue().Set(buff);
1136 }
1137
SetTicketKeys(const FunctionCallbackInfo<Value> & args)1138 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1139 SecureContext* wrap;
1140 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1141
1142 CHECK_GE(args.Length(), 1); // Ticket keys argument is mandatory
1143 CHECK(args[0]->IsArrayBufferView());
1144 ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
1145
1146 CHECK_EQ(buf.length(), 48);
1147
1148 memcpy(wrap->ticket_key_name_, buf.data(), 16);
1149 memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16);
1150 memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16);
1151
1152 args.GetReturnValue().Set(true);
1153 }
1154
1155 // Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
1156 // the regression test in test/parallel/test-https-resume-after-renew.js.
EnableTicketKeyCallback(const FunctionCallbackInfo<Value> & args)1157 void SecureContext::EnableTicketKeyCallback(
1158 const FunctionCallbackInfo<Value>& args) {
1159 SecureContext* wrap;
1160 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1161
1162 SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
1163 }
1164
TicketKeyCallback(SSL * ssl,unsigned char * name,unsigned char * iv,EVP_CIPHER_CTX * ectx,HMAC_CTX * hctx,int enc)1165 int SecureContext::TicketKeyCallback(SSL* ssl,
1166 unsigned char* name,
1167 unsigned char* iv,
1168 EVP_CIPHER_CTX* ectx,
1169 HMAC_CTX* hctx,
1170 int enc) {
1171 static const int kTicketPartSize = 16;
1172
1173 SecureContext* sc = static_cast<SecureContext*>(
1174 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1175
1176 Environment* env = sc->env();
1177 HandleScope handle_scope(env->isolate());
1178 Context::Scope context_scope(env->context());
1179
1180 Local<Value> argv[3];
1181
1182 if (!Buffer::Copy(
1183 env,
1184 reinterpret_cast<char*>(name),
1185 kTicketPartSize).ToLocal(&argv[0]) ||
1186 !Buffer::Copy(
1187 env,
1188 reinterpret_cast<char*>(iv),
1189 kTicketPartSize).ToLocal(&argv[1])) {
1190 return -1;
1191 }
1192
1193 argv[2] = Boolean::New(env->isolate(), enc != 0);
1194
1195 Local<Value> ret;
1196 if (!node::MakeCallback(
1197 env->isolate(),
1198 sc->object(),
1199 env->ticketkeycallback_string(),
1200 arraysize(argv),
1201 argv,
1202 {0, 0}).ToLocal(&ret) ||
1203 !ret->IsArray()) {
1204 return -1;
1205 }
1206 Local<Array> arr = ret.As<Array>();
1207
1208 Local<Value> val;
1209 if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) ||
1210 !val->IsInt32()) {
1211 return -1;
1212 }
1213
1214 int r = val.As<Int32>()->Value();
1215 if (r < 0)
1216 return r;
1217
1218 Local<Value> hmac;
1219 Local<Value> aes;
1220
1221 if (!arr->Get(env->context(), kTicketKeyHMACIndex).ToLocal(&hmac) ||
1222 !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) ||
1223 Buffer::Length(aes) != kTicketPartSize) {
1224 return -1;
1225 }
1226
1227 if (enc) {
1228 Local<Value> name_val;
1229 Local<Value> iv_val;
1230 if (!arr->Get(env->context(), kTicketKeyNameIndex).ToLocal(&name_val) ||
1231 !arr->Get(env->context(), kTicketKeyIVIndex).ToLocal(&iv_val) ||
1232 Buffer::Length(name_val) != kTicketPartSize ||
1233 Buffer::Length(iv_val) != kTicketPartSize) {
1234 return -1;
1235 }
1236
1237 name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1238 iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1239 }
1240
1241 ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1242 HMAC_Init_ex(hctx,
1243 hmac_buf.data(),
1244 hmac_buf.length(),
1245 EVP_sha256(),
1246 nullptr);
1247
1248 ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1249 if (enc) {
1250 EVP_EncryptInit_ex(ectx,
1251 EVP_aes_128_cbc(),
1252 nullptr,
1253 aes_key.data(),
1254 iv);
1255 } else {
1256 EVP_DecryptInit_ex(ectx,
1257 EVP_aes_128_cbc(),
1258 nullptr,
1259 aes_key.data(),
1260 iv);
1261 }
1262
1263 return r;
1264 }
1265
TicketCompatibilityCallback(SSL * ssl,unsigned char * name,unsigned char * iv,EVP_CIPHER_CTX * ectx,HMAC_CTX * hctx,int enc)1266 int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1267 unsigned char* name,
1268 unsigned char* iv,
1269 EVP_CIPHER_CTX* ectx,
1270 HMAC_CTX* hctx,
1271 int enc) {
1272 SecureContext* sc = static_cast<SecureContext*>(
1273 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1274
1275 if (enc) {
1276 memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1277 if (CSPRNG(iv, 16).is_err() ||
1278 EVP_EncryptInit_ex(
1279 ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, iv) <= 0 ||
1280 HMAC_Init_ex(hctx,
1281 sc->ticket_key_hmac_,
1282 sizeof(sc->ticket_key_hmac_),
1283 EVP_sha256(),
1284 nullptr) <= 0) {
1285 return -1;
1286 }
1287 return 1;
1288 }
1289
1290 if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1291 // The ticket key name does not match. Discard the ticket.
1292 return 0;
1293 }
1294
1295 if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1296 iv) <= 0 ||
1297 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1298 EVP_sha256(), nullptr) <= 0) {
1299 return -1;
1300 }
1301 return 1;
1302 }
1303
CtxGetter(const FunctionCallbackInfo<Value> & info)1304 void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1305 SecureContext* sc;
1306 ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1307 Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1308 info.GetReturnValue().Set(ext);
1309 }
1310
1311 template <bool primary>
GetCertificate(const FunctionCallbackInfo<Value> & args)1312 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1313 SecureContext* wrap;
1314 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1315 Environment* env = wrap->env();
1316 X509* cert;
1317
1318 if (primary)
1319 cert = wrap->cert_.get();
1320 else
1321 cert = wrap->issuer_.get();
1322 if (cert == nullptr)
1323 return args.GetReturnValue().SetNull();
1324
1325 int size = i2d_X509(cert, nullptr);
1326 Local<Object> buff;
1327 if (!Buffer::New(env, size).ToLocal(&buff))
1328 return;
1329 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1330 Buffer::Data(buff));
1331 i2d_X509(cert, &serialized);
1332
1333 args.GetReturnValue().Set(buff);
1334 }
1335
1336 namespace {
AddCertsFromFile(X509_STORE * store,const char * file)1337 unsigned long AddCertsFromFile( // NOLINT(runtime/int)
1338 X509_STORE* store,
1339 const char* file) {
1340 ERR_clear_error();
1341 MarkPopErrorOnReturn mark_pop_error_on_return;
1342
1343 BIOPointer bio(BIO_new_file(file, "r"));
1344 if (!bio)
1345 return ERR_get_error();
1346
1347 while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509(
1348 bio.get(), nullptr, NoPasswordCallback, nullptr))) {
1349 X509_STORE_add_cert(store, x509.get());
1350 }
1351
1352 unsigned long err = ERR_peek_error(); // NOLINT(runtime/int)
1353 // Ignore error if its EOF/no start line found.
1354 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1355 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1356 return 0;
1357 }
1358
1359 return err;
1360 }
1361 } // namespace
1362
1363 // UseExtraCaCerts is called only once at the start of the Node.js process.
UseExtraCaCerts(const std::string & file)1364 void UseExtraCaCerts(const std::string& file) {
1365 if (file.empty()) return;
1366 ClearErrorOnReturn clear_error_on_return;
1367 X509_STORE* store = GetOrCreateRootCertStore();
1368 if (auto err = AddCertsFromFile(store, file.c_str())) {
1369 char buf[256];
1370 ERR_error_string_n(err, buf, sizeof(buf));
1371 fprintf(stderr,
1372 "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1373 file.c_str(),
1374 buf);
1375 } else {
1376 extra_root_certs_loaded = true;
1377 }
1378 }
1379
1380 // Exposed to JavaScript strictly for testing purposes.
IsExtraRootCertsFileLoaded(const FunctionCallbackInfo<Value> & args)1381 void IsExtraRootCertsFileLoaded(
1382 const FunctionCallbackInfo<Value>& args) {
1383 return args.GetReturnValue().Set(extra_root_certs_loaded);
1384 }
1385
1386 } // namespace crypto
1387 } // namespace node
1388