• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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