GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_context.cc Lines: 599 714 83.9 %
Date: 2022-12-31 04:22:30 Branches: 289 476 60.7 %

Line Branch Exec Source
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::Context;
26
using v8::DontDelete;
27
using v8::Exception;
28
using v8::External;
29
using v8::FunctionCallbackInfo;
30
using v8::FunctionTemplate;
31
using v8::HandleScope;
32
using v8::Int32;
33
using v8::Integer;
34
using v8::Isolate;
35
using v8::Local;
36
using v8::Object;
37
using v8::PropertyAttribute;
38
using v8::ReadOnly;
39
using v8::Signature;
40
using v8::String;
41
using v8::Value;
42
43
namespace crypto {
44
static const char* const root_certs[] = {
45
#include "node_root_certs.h"  // NOLINT(build/include_order)
46
};
47
48
static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
49
50
static bool extra_root_certs_loaded = false;
51
52
2831
inline X509_STORE* GetOrCreateRootCertStore() {
53
  // Guaranteed thread-safe by standard, just don't use -fno-threadsafe-statics.
54

2831
  static X509_STORE* store = NewRootCertStore();
55
2831
  return store;
56
}
57
58
// Takes a string or buffer and loads it into a BIO.
59
// Caller responsible for BIO_free_all-ing the returned object.
60
2571
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
61
5142
  HandleScope scope(env->isolate());
62
63
5142
  if (v->IsString()) {
64
2962
    Utf8Value s(env->isolate(), v);
65
1481
    return NodeBIO::NewFixed(*s, s.length());
66
  }
67
68
1090
  if (v->IsArrayBufferView()) {
69
1090
    ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
70
1090
    return NodeBIO::NewFixed(buf.data(), buf.length());
71
  }
72
73
  return nullptr;
74
}
75
76
namespace {
77
954
int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
78
                                  X509Pointer&& x,
79
                                  STACK_OF(X509)* extra_certs,
80
                                  X509Pointer* cert,
81
                                  X509Pointer* issuer_) {
82
954
  CHECK(!*issuer_);
83
954
  CHECK(!*cert);
84
954
  X509* issuer = nullptr;
85
86
954
  int ret = SSL_CTX_use_certificate(ctx, x.get());
87
88
954
  if (ret) {
89
    // If we could set up our certificate, now proceed to
90
    // the CA certificates.
91
954
    SSL_CTX_clear_extra_chain_certs(ctx);
92
93
1380
    for (int i = 0; i < sk_X509_num(extra_certs); i++) {
94
426
      X509* ca = sk_X509_value(extra_certs, i);
95
96
      // NOTE: Increments reference count on `ca`
97
426
      if (!SSL_CTX_add1_chain_cert(ctx, ca)) {
98
        ret = 0;
99
        issuer = nullptr;
100
        break;
101
      }
102
      // Note that we must not free r if it was successfully
103
      // added to the chain (while we must free the main
104
      // certificate, since its reference count is increased
105
      // by SSL_CTX_use_certificate).
106
107
      // Find issuer
108

426
      if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
109
4
        continue;
110
111
422
      issuer = ca;
112
    }
113
  }
114
115
  // Try getting issuer from a cert store
116
954
  if (ret) {
117
954
    if (issuer == nullptr) {
118
      // TODO(tniessen): SSL_CTX_get_issuer does not allow the caller to
119
      // distinguish between a failed operation and an empty result. Fix that
120
      // and then handle the potential error properly here (set ret to 0).
121
532
      *issuer_ = SSL_CTX_get_issuer(ctx, x.get());
122
      // NOTE: get_cert_store doesn't increment reference count,
123
      // no need to free `store`
124
    } else {
125
      // Increment issuer reference count
126
422
      issuer_->reset(X509_dup(issuer));
127
422
      if (!*issuer_) {
128
        ret = 0;
129
      }
130
    }
131
  }
132
133

954
  if (ret && x != nullptr) {
134
954
    cert->reset(X509_dup(x.get()));
135
954
    if (!*cert)
136
      ret = 0;
137
  }
138
954
  return ret;
139
}
140
141
// Read a file that contains our certificate in "PEM" format,
142
// possibly followed by a sequence of CA certificates that should be
143
// sent to the peer in the Certificate message.
144
//
145
// Taken from OpenSSL - edited for style.
146
942
int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
147
                                  BIOPointer&& in,
148
                                  X509Pointer* cert,
149
                                  X509Pointer* issuer) {
150
  // Just to ensure that `ERR_peek_last_error` below will return only errors
151
  // that we are interested in
152
942
  ERR_clear_error();
153
154
  X509Pointer x(
155
1884
      PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
156
157
942
  if (!x)
158
    return 0;
159
160
942
  unsigned long err = 0;  // NOLINT(runtime/int)
161
162
1884
  StackOfX509 extra_certs(sk_X509_new_null());
163
942
  if (!extra_certs)
164
    return 0;
165
166
  while (X509Pointer extra {PEM_read_bio_X509(in.get(),
167
                                    nullptr,
168
                                    NoPasswordCallback,
169
1359
                                    nullptr)}) {
170
417
    if (sk_X509_push(extra_certs.get(), extra.get())) {
171
417
      extra.release();
172
417
      continue;
173
    }
174
175
    return 0;
176
417
  }
177
178
  // When the while loop ends, it's usually just EOF.
179
942
  err = ERR_peek_last_error();
180

1884
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
181
942
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
182
942
    ERR_clear_error();
183
  } else {
184
    // some real error
185
    return 0;
186
  }
187
188
1884
  return SSL_CTX_use_certificate_chain(ctx,
189
942
                                       std::move(x),
190
                                       extra_certs.get(),
191
                                       cert,
192
942
                                       issuer);
193
}
194
195
}  // namespace
196
197
295
X509_STORE* NewRootCertStore() {
198

295
  static std::vector<X509*> root_certs_vector;
199

295
  static Mutex root_certs_vector_mutex;
200
590
  Mutex::ScopedLock lock(root_certs_vector_mutex);
201
202

583
  if (root_certs_vector.empty() &&
203
288
      per_process::cli_options->ssl_openssl_cert_store == false) {
204
40467
    for (size_t i = 0; i < arraysize(root_certs); i++) {
205
      X509* x509 =
206
40180
          PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
207
40180
                                              strlen(root_certs[i])).get(),
208
                            nullptr,   // no re-use of X509 structure
209
                            NoPasswordCallback,
210
40180
                            nullptr);  // no callback data
211
212
      // Parse errors from the built-in roots are fatal.
213
40180
      CHECK_NOT_NULL(x509);
214
215
40180
      root_certs_vector.push_back(x509);
216
    }
217
  }
218
219
295
  X509_STORE* store = X509_STORE_new();
220
295
  if (*system_cert_path != '\0') {
221
    ERR_set_mark();
222
    X509_STORE_load_locations(store, system_cert_path, nullptr);
223
    ERR_pop_to_mark();
224
  }
225
226
295
  Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
227
295
  if (per_process::cli_options->ssl_openssl_cert_store) {
228
1
    X509_STORE_set_default_paths(store);
229
  } else {
230
41454
    for (X509* cert : root_certs_vector) {
231
41160
      X509_up_ref(cert);
232
41160
      X509_STORE_add_cert(store, cert);
233
    }
234
  }
235
236
295
  return store;
237
}
238
239
226
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
240
226
  Environment* env = Environment::GetCurrent(args);
241
31866
  Local<Value> result[arraysize(root_certs)];
242
243
31866
  for (size_t i = 0; i < arraysize(root_certs); i++) {
244
31640
    if (!String::NewFromOneByte(
245
            env->isolate(),
246
31640
            reinterpret_cast<const uint8_t*>(root_certs[i]))
247
63280
            .ToLocal(&result[i])) {
248
      return;
249
    }
250
  }
251
252
452
  args.GetReturnValue().Set(
253
      Array::New(env->isolate(), result, arraysize(root_certs)));
254
}
255
256
bool SecureContext::HasInstance(Environment* env, const Local<Value>& value) {
257
  return GetConstructorTemplate(env)->HasInstance(value);
258
}
259
260
5065
Local<FunctionTemplate> SecureContext::GetConstructorTemplate(
261
    Environment* env) {
262
5065
  Local<FunctionTemplate> tmpl = env->secure_context_constructor_template();
263
5065
  if (tmpl.IsEmpty()) {
264
5065
    Isolate* isolate = env->isolate();
265
5065
    tmpl = NewFunctionTemplate(isolate, New);
266
10130
    tmpl->InstanceTemplate()->SetInternalFieldCount(
267
        SecureContext::kInternalFieldCount);
268
5065
    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
269
5065
    tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
270
271
5065
    SetProtoMethod(isolate, tmpl, "init", Init);
272
5065
    SetProtoMethod(isolate, tmpl, "setKey", SetKey);
273
5065
    SetProtoMethod(isolate, tmpl, "setCert", SetCert);
274
5065
    SetProtoMethod(isolate, tmpl, "addCACert", AddCACert);
275
5065
    SetProtoMethod(isolate, tmpl, "addCRL", AddCRL);
276
5065
    SetProtoMethod(isolate, tmpl, "addRootCerts", AddRootCerts);
277
5065
    SetProtoMethod(isolate, tmpl, "setCipherSuites", SetCipherSuites);
278
5065
    SetProtoMethod(isolate, tmpl, "setCiphers", SetCiphers);
279
5065
    SetProtoMethod(isolate, tmpl, "setSigalgs", SetSigalgs);
280
5065
    SetProtoMethod(isolate, tmpl, "setECDHCurve", SetECDHCurve);
281
5065
    SetProtoMethod(isolate, tmpl, "setDHParam", SetDHParam);
282
5065
    SetProtoMethod(isolate, tmpl, "setMaxProto", SetMaxProto);
283
5065
    SetProtoMethod(isolate, tmpl, "setMinProto", SetMinProto);
284
5065
    SetProtoMethod(isolate, tmpl, "getMaxProto", GetMaxProto);
285
5065
    SetProtoMethod(isolate, tmpl, "getMinProto", GetMinProto);
286
5065
    SetProtoMethod(isolate, tmpl, "setOptions", SetOptions);
287
5065
    SetProtoMethod(isolate, tmpl, "setSessionIdContext", SetSessionIdContext);
288
5065
    SetProtoMethod(isolate, tmpl, "setSessionTimeout", SetSessionTimeout);
289
5065
    SetProtoMethod(isolate, tmpl, "close", Close);
290
5065
    SetProtoMethod(isolate, tmpl, "loadPKCS12", LoadPKCS12);
291
5065
    SetProtoMethod(isolate, tmpl, "setTicketKeys", SetTicketKeys);
292
5065
    SetProtoMethod(
293
        isolate, tmpl, "enableTicketKeyCallback", EnableTicketKeyCallback);
294
295
5065
    SetProtoMethodNoSideEffect(isolate, tmpl, "getTicketKeys", GetTicketKeys);
296
5065
    SetProtoMethodNoSideEffect(
297
        isolate, tmpl, "getCertificate", GetCertificate<true>);
298
5065
    SetProtoMethodNoSideEffect(
299
        isolate, tmpl, "getIssuer", GetCertificate<false>);
300
301
#ifndef OPENSSL_NO_ENGINE
302
5065
    SetProtoMethod(isolate, tmpl, "setEngineKey", SetEngineKey);
303
5065
    SetProtoMethod(isolate, tmpl, "setClientCertEngine", SetClientCertEngine);
304
#endif  // !OPENSSL_NO_ENGINE
305
306
#define SET_INTEGER_CONSTANTS(name, value)                                     \
307
  tmpl->Set(FIXED_ONE_BYTE_STRING(isolate, name),                              \
308
            Integer::NewFromUnsigned(isolate, value));
309
15195
    SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
310
15195
    SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
311
15195
    SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
312
15195
    SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
313
15195
    SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex);
314
  #undef SET_INTEGER_CONSTANTS
315
316
    Local<FunctionTemplate> ctx_getter_templ = FunctionTemplate::New(
317
5065
        isolate, CtxGetter, Local<Value>(), Signature::New(isolate, tmpl));
318
319
20260
    tmpl->PrototypeTemplate()->SetAccessorProperty(
320
        FIXED_ONE_BYTE_STRING(isolate, "_external"),
321
        ctx_getter_templ,
322
        Local<FunctionTemplate>(),
323
        static_cast<PropertyAttribute>(ReadOnly | DontDelete));
324
325
5065
    env->set_secure_context_constructor_template(tmpl);
326
  }
327
5065
  return tmpl;
328
}
329
330
5065
void SecureContext::Initialize(Environment* env, Local<Object> target) {
331
5065
  Local<Context> context = env->context();
332
5065
  SetConstructorFunction(context,
333
                         target,
334
                         "SecureContext",
335
                         GetConstructorTemplate(env),
336
                         SetConstructorFunctionFlag::NONE);
337
338
5065
  SetMethodNoSideEffect(
339
      context, target, "getRootCertificates", GetRootCertificates);
340
  // Exposed for testing purposes only.
341
5065
  SetMethodNoSideEffect(context,
342
                        target,
343
                        "isExtraRootCertsFileLoaded",
344
                        IsExtraRootCertsFileLoaded);
345
5065
}
346
347
5718
void SecureContext::RegisterExternalReferences(
348
    ExternalReferenceRegistry* registry) {
349
5718
  registry->Register(New);
350
5718
  registry->Register(Init);
351
5718
  registry->Register(SetKey);
352
5718
  registry->Register(SetCert);
353
5718
  registry->Register(AddCACert);
354
5718
  registry->Register(AddCRL);
355
5718
  registry->Register(AddRootCerts);
356
5718
  registry->Register(SetCipherSuites);
357
5718
  registry->Register(SetCiphers);
358
5718
  registry->Register(SetSigalgs);
359
5718
  registry->Register(SetECDHCurve);
360
5718
  registry->Register(SetDHParam);
361
5718
  registry->Register(SetMaxProto);
362
5718
  registry->Register(SetMinProto);
363
5718
  registry->Register(GetMaxProto);
364
5718
  registry->Register(GetMinProto);
365
5718
  registry->Register(SetOptions);
366
5718
  registry->Register(SetSessionIdContext);
367
5718
  registry->Register(SetSessionTimeout);
368
5718
  registry->Register(Close);
369
5718
  registry->Register(LoadPKCS12);
370
5718
  registry->Register(SetTicketKeys);
371
5718
  registry->Register(EnableTicketKeyCallback);
372
5718
  registry->Register(GetTicketKeys);
373
5718
  registry->Register(GetCertificate<true>);
374
5718
  registry->Register(GetCertificate<false>);
375
376
#ifndef OPENSSL_NO_ENGINE
377
5718
  registry->Register(SetEngineKey);
378
5718
  registry->Register(SetClientCertEngine);
379
#endif  // !OPENSSL_NO_ENGINE
380
381
5718
  registry->Register(CtxGetter);
382
383
5718
  registry->Register(GetRootCertificates);
384
5718
  registry->Register(IsExtraRootCertsFileLoaded);
385
5718
}
386
387
SecureContext* SecureContext::Create(Environment* env) {
388
  Local<Object> obj;
389
  if (!GetConstructorTemplate(env)
390
          ->InstanceTemplate()
391
          ->NewInstance(env->context()).ToLocal(&obj)) {
392
    return nullptr;
393
  }
394
395
  return new SecureContext(env, obj);
396
}
397
398
2511
SecureContext::SecureContext(Environment* env, Local<Object> wrap)
399
2511
    : BaseObject(env, wrap) {
400
2511
  MakeWeak();
401
2511
  env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
402
2511
}
403
404
2502
inline void SecureContext::Reset() {
405
2502
  if (ctx_ != nullptr) {
406
2444
    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
407
  }
408
2502
  ctx_.reset();
409
2502
  cert_.reset();
410
2502
  issuer_.reset();
411
2502
}
412
413
10008
SecureContext::~SecureContext() {
414
5004
  Reset();
415
10008
}
416
417
2511
void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
418
2511
  Environment* env = Environment::GetCurrent(args);
419
2511
  new SecureContext(env, args.This());
420
2511
}
421
422
2509
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
423
  SecureContext* sc;
424
2565
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
425
2509
  Environment* env = sc->env();
426
427
2509
  CHECK_EQ(args.Length(), 3);
428
2509
  CHECK(args[1]->IsInt32());
429
2509
  CHECK(args[2]->IsInt32());
430
431
5018
  int min_version = args[1].As<Int32>()->Value();
432
5018
  int max_version = args[2].As<Int32>()->Value();
433
2509
  const SSL_METHOD* method = TLS_method();
434
435
2509
  if (max_version == 0)
436
    max_version = kMaxSupportedVersion;
437
438
5018
  if (args[0]->IsString()) {
439
371
    Utf8Value sslmethod(env->isolate(), args[0]);
440
441
    // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
442
    // are still accepted.  They are OpenSSL's way of saying that all known
443
    // protocols below TLS 1.3 are supported unless explicitly disabled (which
444
    // we do below for SSLv2 and SSLv3.)
445
727
    if (sslmethod == "SSLv2_method" ||
446

727
        sslmethod == "SSLv2_server_method" ||
447
355
        sslmethod == "SSLv2_client_method") {
448
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
449
17
      return;
450
693
    } else if (sslmethod == "SSLv3_method" ||
451

693
               sslmethod == "SSLv3_server_method" ||
452
338
               sslmethod == "SSLv3_client_method") {
453
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled");
454
17
      return;
455
337
    } else if (sslmethod == "SSLv23_method") {
456
36
      max_version = TLS1_2_VERSION;
457
301
    } else if (sslmethod == "SSLv23_server_method") {
458
1
      max_version = TLS1_2_VERSION;
459
1
      method = TLS_server_method();
460
300
    } else if (sslmethod == "SSLv23_client_method") {
461
1
      max_version = TLS1_2_VERSION;
462
1
      method = TLS_client_method();
463
299
    } else if (sslmethod == "TLS_method") {
464
53
      min_version = 0;
465
53
      max_version = kMaxSupportedVersion;
466
246
    } else if (sslmethod == "TLS_server_method") {
467
      min_version = 0;
468
      max_version = kMaxSupportedVersion;
469
      method = TLS_server_method();
470
246
    } else if (sslmethod == "TLS_client_method") {
471
      min_version = 0;
472
      max_version = kMaxSupportedVersion;
473
      method = TLS_client_method();
474
246
    } else if (sslmethod == "TLSv1_method") {
475
71
      min_version = TLS1_VERSION;
476
71
      max_version = TLS1_VERSION;
477
175
    } else if (sslmethod == "TLSv1_server_method") {
478
1
      min_version = TLS1_VERSION;
479
1
      max_version = TLS1_VERSION;
480
1
      method = TLS_server_method();
481
174
    } else if (sslmethod == "TLSv1_client_method") {
482
1
      min_version = TLS1_VERSION;
483
1
      max_version = TLS1_VERSION;
484
1
      method = TLS_client_method();
485
173
    } else if (sslmethod == "TLSv1_1_method") {
486
71
      min_version = TLS1_1_VERSION;
487
71
      max_version = TLS1_1_VERSION;
488
102
    } else if (sslmethod == "TLSv1_1_server_method") {
489
1
      min_version = TLS1_1_VERSION;
490
1
      max_version = TLS1_1_VERSION;
491
1
      method = TLS_server_method();
492
101
    } else if (sslmethod == "TLSv1_1_client_method") {
493
1
      min_version = TLS1_1_VERSION;
494
1
      max_version = TLS1_1_VERSION;
495
1
      method = TLS_client_method();
496
100
    } else if (sslmethod == "TLSv1_2_method") {
497
75
      min_version = TLS1_2_VERSION;
498
75
      max_version = TLS1_2_VERSION;
499
25
    } else if (sslmethod == "TLSv1_2_server_method") {
500
2
      min_version = TLS1_2_VERSION;
501
2
      max_version = TLS1_2_VERSION;
502
2
      method = TLS_server_method();
503
23
    } else if (sslmethod == "TLSv1_2_client_method") {
504
1
      min_version = TLS1_2_VERSION;
505
1
      max_version = TLS1_2_VERSION;
506
1
      method = TLS_client_method();
507
    } else {
508
22
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(
509
22
          env, "Unknown method: %s", *sslmethod);
510
22
      return;
511
    }
512
  }
513
514
2453
  sc->ctx_.reset(SSL_CTX_new(method));
515
2453
  if (!sc->ctx_) {
516
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new");
517
  }
518
2453
  SSL_CTX_set_app_data(sc->ctx_.get(), sc);
519
520
  // Disable SSLv2 in the case when method == TLS_method() and the
521
  // cipher list contains SSLv2 ciphers (not the default, should be rare.)
522
  // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
523
  // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
524
2453
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2);
525
2453
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3);
526
#if OPENSSL_VERSION_MAJOR >= 3
527
2453
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_ALLOW_CLIENT_RENEGOTIATION);
528
#endif
529
530
  // Enable automatic cert chaining. This is enabled by default in OpenSSL, but
531
  // disabled by default in BoringSSL. Enable it explicitly to make the
532
  // behavior match when Node is built with BoringSSL.
533
2453
  SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
534
535
  // SSL session cache configuration
536
2453
  SSL_CTX_set_session_cache_mode(sc->ctx_.get(),
537
                                 SSL_SESS_CACHE_CLIENT |
538
                                 SSL_SESS_CACHE_SERVER |
539
                                 SSL_SESS_CACHE_NO_INTERNAL |
540
                                 SSL_SESS_CACHE_NO_AUTO_CLEAR);
541
542
2453
  SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
543
2453
  SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
544
545
  // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
546
  // exposed in the public API. To retain compatibility, install a callback
547
  // which restores the old algorithm.
548
4906
  if (CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)).is_err() ||
549

4906
      CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)).is_err() ||
550
4906
      CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)).is_err()) {
551
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
552
        env, "Error generating ticket keys");
553
  }
554
2453
  SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
555
}
556
557
12405
SSLPointer SecureContext::CreateSSL() {
558
12405
  return SSLPointer(SSL_new(ctx_.get()));
559
}
560
561
12405
void SecureContext::SetNewSessionCallback(NewSessionCb cb) {
562
12405
  SSL_CTX_sess_set_new_cb(ctx_.get(), cb);
563
12405
}
564
565
12405
void SecureContext::SetGetSessionCallback(GetSessionCb cb) {
566
12405
  SSL_CTX_sess_set_get_cb(ctx_.get(), cb);
567
12405
}
568
569
953
void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) {
570
953
  SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb);
571
953
}
572
573
8
void SecureContext::SetKeylogCallback(KeylogCb cb) {
574
8
  SSL_CTX_set_keylog_callback(ctx_.get(), cb);
575
8
}
576
577
924
void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
578
924
  Environment* env = Environment::GetCurrent(args);
579
580
  SecureContext* sc;
581
932
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
582
583
924
  CHECK_GE(args.Length(), 1);  // Private key argument is mandatory
584
585
924
  BIOPointer bio(LoadBIO(env, args[0]));
586
924
  if (!bio)
587
    return;
588
589
924
  ByteSource passphrase;
590
1848
  if (args[1]->IsString())
591
48
    passphrase = ByteSource::FromString(env, args[1].As<String>());
592
  // This redirection is necessary because the PasswordCallback expects a
593
  // pointer to a pointer to the passphrase ByteSource to allow passing in
594
  // const ByteSources.
595
924
  const ByteSource* pass_ptr = &passphrase;
596
597
  EVPKeyPointer key(
598
      PEM_read_bio_PrivateKey(bio.get(),
599
                              nullptr,
600
                              PasswordCallback,
601
924
                              &pass_ptr));
602
603
924
  if (!key)
604
7
    return ThrowCryptoError(env, ERR_get_error(), "PEM_read_bio_PrivateKey");
605
606
917
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
607
1
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
608
}
609
610
8
void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
611
  SecureContext* sc;
612
8
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
613
8
  Environment* env = sc->env();
614
  ClearErrorOnReturn clear_error_on_return;
615
616
8
  CHECK_EQ(args.Length(), 1);
617
16
  CHECK(args[0]->IsString());
618
619
8
  const Utf8Value sigalgs(env->isolate(), args[0]);
620
621
8
  if (!SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs))
622
    return ThrowCryptoError(env, ERR_get_error());
623
}
624
625
#ifndef OPENSSL_NO_ENGINE
626
void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
627
  Environment* env = Environment::GetCurrent(args);
628
629
  SecureContext* sc;
630
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
631
632
  CHECK_EQ(args.Length(), 2);
633
634
  CryptoErrorStore errors;
635
  Utf8Value engine_id(env->isolate(), args[1]);
636
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
637
  if (!engine) {
638
    Local<Value> exception;
639
    if (errors.ToException(env).ToLocal(&exception))
640
      env->isolate()->ThrowException(exception);
641
    return;
642
  }
643
644
  if (!ENGINE_init(engine.get())) {
645
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
646
        env, "Failure to initialize engine");
647
  }
648
649
  engine.finish_on_exit = true;
650
651
  Utf8Value key_name(env->isolate(), args[0]);
652
  EVPKeyPointer key(ENGINE_load_private_key(engine.get(), *key_name,
653
                                            nullptr, nullptr));
654
655
  if (!key)
656
    return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
657
658
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
659
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
660
661
  sc->private_key_engine_ = std::move(engine);
662
}
663
#endif  // !OPENSSL_NO_ENGINE
664
665
942
void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
666
942
  Environment* env = Environment::GetCurrent(args);
667
668
  SecureContext* sc;
669
942
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
670
671
942
  CHECK_GE(args.Length(), 1);  // Certificate argument is mandator
672
673
942
  BIOPointer bio(LoadBIO(env, args[0]));
674
942
  if (!bio)
675
    return;
676
677
942
  sc->cert_.reset();
678
942
  sc->issuer_.reset();
679
680
942
  if (!SSL_CTX_use_certificate_chain(
681
942
          sc->ctx_.get(),
682
942
          std::move(bio),
683
942
          &sc->cert_,
684
942
          &sc->issuer_)) {
685
    return ThrowCryptoError(
686
        env,
687
        ERR_get_error(),
688
        "SSL_CTX_use_certificate_chain");
689
  }
690
}
691
692
625
void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
693
625
  Environment* env = Environment::GetCurrent(args);
694
695
  SecureContext* sc;
696
625
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
697
  ClearErrorOnReturn clear_error_on_return;
698
699
625
  CHECK_GE(args.Length(), 1);  // CA certificate argument is mandatory
700
701
625
  BIOPointer bio(LoadBIO(env, args[0]));
702
625
  if (!bio)
703
    return;
704
705
625
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
706
  while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509_AUX(
707
1594
             bio.get(), nullptr, NoPasswordCallback, nullptr))) {
708
969
    if (cert_store == GetOrCreateRootCertStore()) {
709
1
      cert_store = NewRootCertStore();
710
1
      SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
711
    }
712
969
    X509_STORE_add_cert(cert_store, x509.get());
713
969
    SSL_CTX_add_client_CA(sc->ctx_.get(), x509.get());
714
969
  }
715
}
716
717
2
void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
718
2
  Environment* env = Environment::GetCurrent(args);
719
720
  SecureContext* sc;
721
3
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
722
723
2
  CHECK_GE(args.Length(), 1);  // CRL argument is mandatory
724
725
  ClearErrorOnReturn clear_error_on_return;
726
727
2
  BIOPointer bio(LoadBIO(env, args[0]));
728
2
  if (!bio)
729
    return;
730
731
  DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
732
2
      PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
733
734
2
  if (!crl)
735
1
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to parse CRL");
736
737
1
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
738
1
  if (cert_store == GetOrCreateRootCertStore()) {
739
    cert_store = NewRootCertStore();
740
    SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
741
  }
742
743
1
  X509_STORE_add_crl(cert_store, crl.get());
744
1
  X509_STORE_set_flags(cert_store,
745
                       X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
746
}
747
748
1848
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
749
  SecureContext* sc;
750
1848
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
751
1848
  ClearErrorOnReturn clear_error_on_return;
752
1848
  X509_STORE* store = GetOrCreateRootCertStore();
753
  // Increment reference count so global store is not deleted along with CTX.
754
1848
  X509_STORE_up_ref(store);
755
1848
  SSL_CTX_set_cert_store(sc->ctx_.get(), store);
756
}
757
758
1915
void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
759
  // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
760
#ifndef OPENSSL_IS_BORINGSSL
761
  SecureContext* sc;
762
1916
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
763
1915
  Environment* env = sc->env();
764
  ClearErrorOnReturn clear_error_on_return;
765
766
1915
  CHECK_EQ(args.Length(), 1);
767
3830
  CHECK(args[0]->IsString());
768
769
1915
  const Utf8Value ciphers(env->isolate(), args[0]);
770
1915
  if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
771
1
    return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
772
#endif
773
}
774
775
2379
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
776
  SecureContext* sc;
777
2394
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
778
2379
  Environment* env = sc->env();
779
  ClearErrorOnReturn clear_error_on_return;
780
781
2379
  CHECK_EQ(args.Length(), 1);
782
4758
  CHECK(args[0]->IsString());
783
784
2379
  Utf8Value ciphers(env->isolate(), args[0]);
785
2379
  if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
786
15
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
787
788

15
    if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
789
      // TLS1.2 ciphers were deliberately cleared, so don't consider
790
      // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
791
      // works). If the user actually sets a value (like "no-such-cipher"), then
792
      // that's actually an error.
793
11
      return;
794
    }
795
4
    return ThrowCryptoError(env, err, "Failed to set ciphers");
796
  }
797
}
798
799
2371
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
800
  SecureContext* sc;
801
2374
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
802
2371
  Environment* env = sc->env();
803
804
2371
  CHECK_GE(args.Length(), 1);  // ECDH curve name argument is mandatory
805
4742
  CHECK(args[0]->IsString());
806
807
2371
  Utf8Value curve(env->isolate(), args[0]);
808
809

2381
  if (strcmp(*curve, "auto") != 0 &&
810
10
      !SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve)) {
811
3
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set ECDH curve");
812
  }
813
}
814
815
10
void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
816
  SecureContext* sc;
817
13
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
818
10
  Environment* env = sc->env();
819
  ClearErrorOnReturn clear_error_on_return;
820
821
10
  CHECK_GE(args.Length(), 1);  // DH argument is mandatory
822
823
10
  DHPointer dh;
824
  {
825
10
    BIOPointer bio(LoadBIO(env, args[0]));
826
10
    if (!bio)
827
      return;
828
829
10
    dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
830
  }
831
832
  // Invalid dhparam is silently discarded and DHE is no longer used.
833
10
  if (!dh)
834
1
    return;
835
836
  const BIGNUM* p;
837
9
  DH_get0_pqg(dh.get(), &p, nullptr, nullptr);
838
9
  const int size = BN_num_bits(p);
839
9
  if (size < 1024) {
840
2
    return THROW_ERR_INVALID_ARG_VALUE(
841
2
        env, "DH parameter is less than 1024 bits");
842
7
  } else if (size < 2048) {
843
6
    args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(
844
        env->isolate(), "DH parameter is less than 2048 bits"));
845
  }
846
847
7
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_DH_USE);
848
849
7
  if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) {
850
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
851
        env, "Error setting temp DH parameter");
852
  }
853
}
854
855
11
void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
856
  SecureContext* sc;
857
11
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
858
859
11
  CHECK_EQ(args.Length(), 1);
860
11
  CHECK(args[0]->IsInt32());
861
862
22
  int version = args[0].As<Int32>()->Value();
863
864
11
  CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
865
}
866
867
void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
868
  SecureContext* sc;
869
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
870
871
  CHECK_EQ(args.Length(), 1);
872
  CHECK(args[0]->IsInt32());
873
874
  int version = args[0].As<Int32>()->Value();
875
876
  CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
877
}
878
879
11
void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
880
  SecureContext* sc;
881
11
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
882
883
11
  CHECK_EQ(args.Length(), 0);
884
885
  long version =  // NOLINT(runtime/int)
886
11
    SSL_CTX_get_min_proto_version(sc->ctx_.get());
887
22
  args.GetReturnValue().Set(static_cast<uint32_t>(version));
888
}
889
890
11
void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
891
  SecureContext* sc;
892
11
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
893
894
11
  CHECK_EQ(args.Length(), 0);
895
896
  long version =  // NOLINT(runtime/int)
897
11
    SSL_CTX_get_max_proto_version(sc->ctx_.get());
898
22
  args.GetReturnValue().Set(static_cast<uint32_t>(version));
899
}
900
901
925
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
902
925
  Environment* env = Environment::GetCurrent(args);
903
  SecureContext* sc;
904
925
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
905
906
925
  CHECK_GE(args.Length(), 1);
907
925
  CHECK(args[0]->IsNumber());
908
909
925
  int64_t val = args[0]->IntegerValue(env->context()).FromMaybe(0);
910
911
925
  SSL_CTX_set_options(sc->ctx_.get(),
912
                      static_cast<long>(val));  // NOLINT(runtime/int)
913
}
914
915
854
void SecureContext::SetSessionIdContext(
916
    const FunctionCallbackInfo<Value>& args) {
917
  SecureContext* sc;
918
1708
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
919
854
  Environment* env = sc->env();
920
921
854
  CHECK_GE(args.Length(), 1);
922
1708
  CHECK(args[0]->IsString());
923
924
854
  const Utf8Value sessionIdContext(env->isolate(), args[0]);
925
  const unsigned char* sid_ctx =
926
854
      reinterpret_cast<const unsigned char*>(*sessionIdContext);
927
854
  unsigned int sid_ctx_len = sessionIdContext.length();
928
929
854
  if (SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len) == 1)
930
854
    return;
931
932
  BUF_MEM* mem;
933
  Local<String> message;
934
935
  BIOPointer bio(BIO_new(BIO_s_mem()));
936
  if (!bio) {
937
    message = FIXED_ONE_BYTE_STRING(env->isolate(),
938
                                    "SSL_CTX_set_session_id_context error");
939
  } else {
940
    ERR_print_errors(bio.get());
941
    BIO_get_mem_ptr(bio.get(), &mem);
942
    message = OneByteString(env->isolate(), mem->data, mem->length);
943
  }
944
945
  env->isolate()->ThrowException(Exception::TypeError(message));
946
}
947
948
1
void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
949
  SecureContext* sc;
950
1
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
951
952
1
  CHECK_GE(args.Length(), 1);
953
1
  CHECK(args[0]->IsInt32());
954
955
2
  int32_t sessionTimeout = args[0].As<Int32>()->Value();
956
1
  SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout);
957
}
958
959
void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
960
  SecureContext* sc;
961
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
962
  sc->Reset();
963
}
964
965
// Takes .pfx or .p12 and password in string or buffer format
966
18
void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
967
18
  Environment* env = Environment::GetCurrent(args);
968
969
18
  std::vector<char> pass;
970
18
  bool ret = false;
971
972
  SecureContext* sc;
973
18
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
974
  ClearErrorOnReturn clear_error_on_return;
975
976
18
  if (args.Length() < 1) {
977
    return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory");
978
  }
979
980
18
  BIOPointer in(LoadBIO(env, args[0]));
981
18
  if (!in) {
982
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
983
        env, "Unable to load PFX certificate");
984
  }
985
986
18
  if (args.Length() >= 2) {
987
15
    THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase");
988
30
    Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>();
989
15
    size_t passlen = abv->ByteLength();
990
15
    pass.resize(passlen + 1);
991
15
    abv->CopyContents(pass.data(), passlen);
992
15
    pass[passlen] = '\0';
993
  }
994
995
  // Free previous certs
996
18
  sc->issuer_.reset();
997
18
  sc->cert_.reset();
998
999
18
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1000
1001
18
  DeleteFnPtr<PKCS12, PKCS12_free> p12;
1002
18
  EVPKeyPointer pkey;
1003
18
  X509Pointer cert;
1004
18
  StackOfX509 extra_certs;
1005
1006
18
  PKCS12* p12_ptr = nullptr;
1007
18
  EVP_PKEY* pkey_ptr = nullptr;
1008
18
  X509* cert_ptr = nullptr;
1009
18
  STACK_OF(X509)* extra_certs_ptr = nullptr;
1010
18
  if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
1011
32
      (p12.reset(p12_ptr), true) &&  // Move ownership to the smart pointer.
1012
16
      PKCS12_parse(p12.get(), pass.data(),
1013
                   &pkey_ptr,
1014
                   &cert_ptr,
1015
                   &extra_certs_ptr) &&
1016
12
      (pkey.reset(pkey_ptr), cert.reset(cert_ptr),
1017
24
       extra_certs.reset(extra_certs_ptr), true) &&  // Move ownership.
1018
12
      SSL_CTX_use_certificate_chain(sc->ctx_.get(),
1019
12
                                    std::move(cert),
1020
                                    extra_certs.get(),
1021
12
                                    &sc->cert_,
1022

46
                                    &sc->issuer_) &&
1023
12
      SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
1024
    // Add CA certs too
1025
21
    for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
1026
9
      X509* ca = sk_X509_value(extra_certs.get(), i);
1027
1028
9
      if (cert_store == GetOrCreateRootCertStore()) {
1029
6
        cert_store = NewRootCertStore();
1030
6
        SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1031
      }
1032
9
      X509_STORE_add_cert(cert_store, ca);
1033
9
      SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
1034
    }
1035
12
    ret = true;
1036
  }
1037
1038
18
  if (!ret) {
1039
    // TODO(@jasnell): Should this use ThrowCryptoError?
1040
6
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
1041
6
    const char* str = ERR_reason_error_string(err);
1042
6
    str = str != nullptr ? str : "Unknown error";
1043
1044
6
    return env->ThrowError(str);
1045
  }
1046
}
1047
1048
#ifndef OPENSSL_NO_ENGINE
1049
void SecureContext::SetClientCertEngine(
1050
    const FunctionCallbackInfo<Value>& args) {
1051
  Environment* env = Environment::GetCurrent(args);
1052
  CHECK_EQ(args.Length(), 1);
1053
  CHECK(args[0]->IsString());
1054
1055
  SecureContext* sc;
1056
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1057
1058
  MarkPopErrorOnReturn mark_pop_error_on_return;
1059
1060
  // SSL_CTX_set_client_cert_engine does not itself support multiple
1061
  // calls by cleaning up before overwriting the client_cert_engine
1062
  // internal context variable.
1063
  // Instead of trying to fix up this problem we in turn also do not
1064
  // support multiple calls to SetClientCertEngine.
1065
  CHECK(!sc->client_cert_engine_provided_);
1066
1067
  CryptoErrorStore errors;
1068
  const Utf8Value engine_id(env->isolate(), args[0]);
1069
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
1070
  if (!engine) {
1071
    Local<Value> exception;
1072
    if (errors.ToException(env).ToLocal(&exception))
1073
      env->isolate()->ThrowException(exception);
1074
    return;
1075
  }
1076
1077
  // Note that this takes another reference to `engine`.
1078
  if (!SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get()))
1079
    return ThrowCryptoError(env, ERR_get_error());
1080
  sc->client_cert_engine_provided_ = true;
1081
}
1082
#endif  // !OPENSSL_NO_ENGINE
1083
1084
10
void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1085
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1086
1087
  SecureContext* wrap;
1088
10
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1089
1090
  Local<Object> buff;
1091
20
  if (!Buffer::New(wrap->env(), 48).ToLocal(&buff))
1092
    return;
1093
1094
10
  memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
1095
10
  memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
1096
10
  memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
1097
1098
20
  args.GetReturnValue().Set(buff);
1099
#endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1100
}
1101
1102
23
void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1103
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1104
  SecureContext* wrap;
1105
23
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1106
1107
23
  CHECK_GE(args.Length(), 1);  // Ticket keys argument is mandatory
1108
23
  CHECK(args[0]->IsArrayBufferView());
1109
46
  ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
1110
1111
23
  CHECK_EQ(buf.length(), 48);
1112
1113
23
  memcpy(wrap->ticket_key_name_, buf.data(), 16);
1114
23
  memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16);
1115
23
  memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16);
1116
1117
46
  args.GetReturnValue().Set(true);
1118
#endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1119
}
1120
1121
// Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
1122
// the regression test in test/parallel/test-https-resume-after-renew.js.
1123
1
void SecureContext::EnableTicketKeyCallback(
1124
    const FunctionCallbackInfo<Value>& args) {
1125
  SecureContext* wrap;
1126
1
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1127
1128
1
  SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
1129
}
1130
1131
4
int SecureContext::TicketKeyCallback(SSL* ssl,
1132
                                     unsigned char* name,
1133
                                     unsigned char* iv,
1134
                                     EVP_CIPHER_CTX* ectx,
1135
                                     HMAC_CTX* hctx,
1136
                                     int enc) {
1137
  static const int kTicketPartSize = 16;
1138
1139
  SecureContext* sc = static_cast<SecureContext*>(
1140
4
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1141
1142
4
  Environment* env = sc->env();
1143
8
  HandleScope handle_scope(env->isolate());
1144
4
  Context::Scope context_scope(env->context());
1145
1146
16
  Local<Value> argv[3];
1147
1148
8
  if (!Buffer::Copy(
1149
          env,
1150
          reinterpret_cast<char*>(name),
1151
12
          kTicketPartSize).ToLocal(&argv[0]) ||
1152
4
      !Buffer::Copy(
1153
          env,
1154
          reinterpret_cast<char*>(iv),
1155
8
          kTicketPartSize).ToLocal(&argv[1])) {
1156
    return -1;
1157
  }
1158
1159
8
  argv[2] = enc != 0 ? v8::True(env->isolate()) : v8::False(env->isolate());
1160
1161
  Local<Value> ret;
1162
8
  if (!node::MakeCallback(
1163
          env->isolate(),
1164
          sc->object(),
1165
          env->ticketkeycallback_string(),
1166
4
          arraysize(argv),
1167
          argv,
1168

12
          {0, 0}).ToLocal(&ret) ||
1169
4
      !ret->IsArray()) {
1170
    return -1;
1171
  }
1172
4
  Local<Array> arr = ret.As<Array>();
1173
1174
  Local<Value> val;
1175

12
  if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) ||
1176
4
      !val->IsInt32()) {
1177
    return -1;
1178
  }
1179
1180
4
  int r = val.As<Int32>()->Value();
1181
4
  if (r < 0)
1182
    return r;
1183
1184
  Local<Value> hmac;
1185
  Local<Value> aes;
1186
1187
4
  if (!arr->Get(env->context(), kTicketKeyHMACIndex).ToLocal(&hmac) ||
1188


16
      !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) ||
1189
4
      Buffer::Length(aes) != kTicketPartSize) {
1190
    return -1;
1191
  }
1192
1193
4
  if (enc) {
1194
    Local<Value> name_val;
1195
    Local<Value> iv_val;
1196
3
    if (!arr->Get(env->context(), kTicketKeyNameIndex).ToLocal(&name_val) ||
1197

9
        !arr->Get(env->context(), kTicketKeyIVIndex).ToLocal(&iv_val) ||
1198

9
        Buffer::Length(name_val) != kTicketPartSize ||
1199
3
        Buffer::Length(iv_val) != kTicketPartSize) {
1200
      return -1;
1201
    }
1202
1203
3
    name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1204
3
    iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1205
  }
1206
1207
4
  ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1208
8
  HMAC_Init_ex(hctx,
1209
4
               hmac_buf.data(),
1210
4
               hmac_buf.length(),
1211
               EVP_sha256(),
1212
               nullptr);
1213
1214
4
  ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1215
4
  if (enc) {
1216
3
    EVP_EncryptInit_ex(ectx,
1217
                       EVP_aes_128_cbc(),
1218
                       nullptr,
1219
                       aes_key.data(),
1220
                       iv);
1221
  } else {
1222
1
    EVP_DecryptInit_ex(ectx,
1223
                       EVP_aes_128_cbc(),
1224
                       nullptr,
1225
                       aes_key.data(),
1226
                       iv);
1227
  }
1228
1229
4
  return r;
1230
}
1231
1232
1340
int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1233
                                               unsigned char* name,
1234
                                               unsigned char* iv,
1235
                                               EVP_CIPHER_CTX* ectx,
1236
                                               HMAC_CTX* hctx,
1237
                                               int enc) {
1238
  SecureContext* sc = static_cast<SecureContext*>(
1239
1340
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1240
1241
1340
  if (enc) {
1242
1280
    memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1243
2560
    if (CSPRNG(iv, 16).is_err() ||
1244
1280
        EVP_EncryptInit_ex(
1245

2560
            ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, iv) <= 0 ||
1246
1280
        HMAC_Init_ex(hctx,
1247
1280
                     sc->ticket_key_hmac_,
1248
                     sizeof(sc->ticket_key_hmac_),
1249
                     EVP_sha256(),
1250
                     nullptr) <= 0) {
1251
      return -1;
1252
    }
1253
1280
    return 1;
1254
  }
1255
1256
60
  if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1257
    // The ticket key name does not match. Discard the ticket.
1258
9
    return 0;
1259
  }
1260
1261
51
  if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1262

102
                         iv) <= 0 ||
1263
51
      HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1264
                   EVP_sha256(), nullptr) <= 0) {
1265
    return -1;
1266
  }
1267
51
  return 1;
1268
}
1269
1270
2
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1271
  SecureContext* sc;
1272
2
  ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1273
4
  Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1274
4
  info.GetReturnValue().Set(ext);
1275
}
1276
1277
template <bool primary>
1278
12
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1279
  SecureContext* wrap;
1280
12
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1281
12
  Environment* env = wrap->env();
1282
  X509* cert;
1283
1284
  if (primary)
1285
6
    cert = wrap->cert_.get();
1286
  else
1287
6
    cert = wrap->issuer_.get();
1288
12
  if (cert == nullptr)
1289
    return args.GetReturnValue().SetNull();
1290
1291
12
  int size = i2d_X509(cert, nullptr);
1292
  Local<Object> buff;
1293
24
  if (!Buffer::New(env, size).ToLocal(&buff))
1294
    return;
1295
12
  unsigned char* serialized = reinterpret_cast<unsigned char*>(
1296
12
      Buffer::Data(buff));
1297
12
  i2d_X509(cert, &serialized);
1298
1299
24
  args.GetReturnValue().Set(buff);
1300
}
1301
1302
namespace {
1303
4
unsigned long AddCertsFromFile(  // NOLINT(runtime/int)
1304
    X509_STORE* store,
1305
    const char* file) {
1306
4
  ERR_clear_error();
1307
8
  MarkPopErrorOnReturn mark_pop_error_on_return;
1308
1309
8
  BIOPointer bio(BIO_new_file(file, "r"));
1310
4
  if (!bio)
1311
1
    return ERR_get_error();
1312
1313
  while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509(
1314
6
             bio.get(), nullptr, NoPasswordCallback, nullptr))) {
1315
3
    X509_STORE_add_cert(store, x509.get());
1316
3
  }
1317
1318
3
  unsigned long err = ERR_peek_error();  // NOLINT(runtime/int)
1319
  // Ignore error if its EOF/no start line found.
1320

6
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1321
3
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1322
3
    return 0;
1323
  }
1324
1325
  return err;
1326
}
1327
}  // namespace
1328
1329
// UseExtraCaCerts is called only once at the start of the Node.js process.
1330
4
void UseExtraCaCerts(const std::string& file) {
1331
4
  if (file.empty()) return;
1332
4
  ClearErrorOnReturn clear_error_on_return;
1333
4
  X509_STORE* store = GetOrCreateRootCertStore();
1334
4
  if (auto err = AddCertsFromFile(store, file.c_str())) {
1335
    char buf[256];
1336
1
    ERR_error_string_n(err, buf, sizeof(buf));
1337
1
    fprintf(stderr,
1338
            "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1339
            file.c_str(),
1340
            buf);
1341
  } else {
1342
3
    extra_root_certs_loaded = true;
1343
  }
1344
}
1345
1346
// Exposed to JavaScript strictly for testing purposes.
1347
3
void IsExtraRootCertsFileLoaded(
1348
    const FunctionCallbackInfo<Value>& args) {
1349
6
  return args.GetReturnValue().Set(extra_root_certs_loaded);
1350
}
1351
1352
}  // namespace crypto
1353
}  // namespace node