Coverage Report

Created: 2025-09-05 10:05

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