GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_context.cc Lines: 608 717 84.8 %
Date: 2022-04-22 04:19:20 Branches: 292 474 61.6 %

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::Local;
35
using v8::Object;
36
using v8::PropertyAttribute;
37
using v8::ReadOnly;
38
using v8::Signature;
39
using v8::String;
40
using v8::Value;
41
42
namespace crypto {
43
static const char* const root_certs[] = {
44
#include "node_root_certs.h"  // NOLINT(build/include_order)
45
};
46
47
static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
48
49
static X509_STORE* root_cert_store;
50
51
static bool extra_root_certs_loaded = false;
52
53
// Takes a string or buffer and loads it into a BIO.
54
// Caller responsible for BIO_free_all-ing the returned object.
55
2548
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
56
5096
  HandleScope scope(env->isolate());
57
58
5096
  if (v->IsString()) {
59
2944
    Utf8Value s(env->isolate(), v);
60
1472
    return NodeBIO::NewFixed(*s, s.length());
61
  }
62
63
1076
  if (v->IsArrayBufferView()) {
64
1076
    ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
65
1076
    return NodeBIO::NewFixed(buf.data(), buf.length());
66
  }
67
68
  return nullptr;
69
}
70
71
namespace {
72
944
int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
73
                                  X509Pointer&& x,
74
                                  STACK_OF(X509)* extra_certs,
75
                                  X509Pointer* cert,
76
                                  X509Pointer* issuer_) {
77
944
  CHECK(!*issuer_);
78
944
  CHECK(!*cert);
79
944
  X509* issuer = nullptr;
80
81
944
  int ret = SSL_CTX_use_certificate(ctx, x.get());
82
83
944
  if (ret) {
84
    // If we could set up our certificate, now proceed to
85
    // the CA certificates.
86
944
    SSL_CTX_clear_extra_chain_certs(ctx);
87
88
1368
    for (int i = 0; i < sk_X509_num(extra_certs); i++) {
89
424
      X509* ca = sk_X509_value(extra_certs, i);
90
91
      // NOTE: Increments reference count on `ca`
92
424
      if (!SSL_CTX_add1_chain_cert(ctx, ca)) {
93
        ret = 0;
94
        issuer = nullptr;
95
        break;
96
      }
97
      // Note that we must not free r if it was successfully
98
      // added to the chain (while we must free the main
99
      // certificate, since its reference count is increased
100
      // by SSL_CTX_use_certificate).
101
102
      // Find issuer
103

424
      if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
104
4
        continue;
105
106
420
      issuer = ca;
107
    }
108
  }
109
110
  // Try getting issuer from a cert store
111
944
  if (ret) {
112
944
    if (issuer == nullptr) {
113
524
      ret = SSL_CTX_get_issuer(ctx, x.get(), &issuer);
114
524
      ret = ret < 0 ? 0 : 1;
115
      // NOTE: get_cert_store doesn't increment reference count,
116
      // no need to free `store`
117
    } else {
118
      // Increment issuer reference count
119
420
      issuer = X509_dup(issuer);
120
420
      if (issuer == nullptr) {
121
        ret = 0;
122
      }
123
    }
124
  }
125
126
944
  issuer_->reset(issuer);
127
128

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

1864
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
176
932
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
177
932
    ERR_clear_error();
178
  } else {
179
    // some real error
180
    return 0;
181
  }
182
183
1864
  return SSL_CTX_use_certificate_chain(ctx,
184
932
                                       std::move(x),
185
                                       extra_certs.get(),
186
                                       cert,
187
932
                                       issuer);
188
}
189
190
}  // namespace
191
192
277
X509_STORE* NewRootCertStore() {
193

277
  static std::vector<X509*> root_certs_vector;
194

277
  static Mutex root_certs_vector_mutex;
195
554
  Mutex::ScopedLock lock(root_certs_vector_mutex);
196
197

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

713
        sslmethod == "SSLv2_server_method" ||
443
348
        sslmethod == "SSLv2_client_method") {
444
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
445
17
      return;
446
679
    } else if (sslmethod == "SSLv3_method" ||
447

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

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

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

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

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

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

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


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

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

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

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

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

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