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
21namespace node {
22
23using v8::Array;
24using v8::ArrayBufferView;
25using v8::Boolean;
26using v8::Context;
27using v8::DontDelete;
28using v8::Exception;
29using v8::External;
30using v8::FunctionCallbackInfo;
31using v8::FunctionTemplate;
32using v8::HandleScope;
33using v8::Int32;
34using v8::Integer;
35using v8::Isolate;
36using v8::Just;
37using v8::Local;
38using v8::Maybe;
39using v8::Nothing;
40using v8::Object;
41using v8::PropertyAttribute;
42using v8::ReadOnly;
43using v8::Signature;
44using v8::String;
45using v8::Value;
46
47namespace crypto {
48static const char* const root_certs[] = {
49#include "node_root_certs.h"  // NOLINT(build/include_order)
50};
51
52static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
53
54static bool extra_root_certs_loaded = false;
55
56inline 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.
64BIOPointer 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
78namespace {
79int 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.
148int 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
199X509_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
241void 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
258bool SecureContext::HasInstance(Environment* env, const Local<Value>& value) {
259  return GetConstructorTemplate(env)->HasInstance(value);
260}
261
262Local<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
332void 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
349void 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
389SecureContext* 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
400SecureContext::SecureContext(Environment* env, Local<Object> wrap)
401    : BaseObject(env, wrap) {
402  MakeWeak();
403  env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
404}
405
406inline void SecureContext::Reset() {
407  if (ctx_ != nullptr) {
408    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
409  }
410  ctx_.reset();
411  cert_.reset();
412  issuer_.reset();
413}
414
415SecureContext::~SecureContext() {
416  Reset();
417}
418
419void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
420  Environment* env = Environment::GetCurrent(args);
421  new SecureContext(env, args.This());
422}
423
424void 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
559SSLPointer SecureContext::CreateSSL() {
560  return SSLPointer(SSL_new(ctx_.get()));
561}
562
563void SecureContext::SetNewSessionCallback(NewSessionCb cb) {
564  SSL_CTX_sess_set_new_cb(ctx_.get(), cb);
565}
566
567void SecureContext::SetGetSessionCallback(GetSessionCb cb) {
568  SSL_CTX_sess_set_get_cb(ctx_.get(), cb);
569}
570
571void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) {
572  SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb);
573}
574
575void SecureContext::SetKeylogCallback(KeylogCb cb) {
576  SSL_CTX_set_keylog_callback(ctx_.get(), cb);
577}
578
579Maybe<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
595void 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
628void 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
644void 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
683Maybe<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
700void 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
712void 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
727void 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
739Maybe<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
764void 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
776void 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
785void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
786  SecureContext* sc;
787  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
788  sc->SetRootCerts();
789}
790
791void 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
808void 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
832void 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
847void 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
894void 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
906void 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
918void 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
929void 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
940void 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
954void 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
987void 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
998void 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
1005void 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
1088void 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
1123void 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
1138void 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.
1157void 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
1165int 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
1266int 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
1304void 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
1311template <bool primary>
1312void 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
1336namespace {
1337unsigned 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.
1364void 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.
1381void IsExtraRootCertsFileLoaded(
1382    const FunctionCallbackInfo<Value>& args) {
1383  return args.GetReturnValue().Set(extra_root_certs_loaded);
1384}
1385
1386}  // namespace crypto
1387}  // namespace node
1388