GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/crypto/crypto_context.cc Lines: 590 683 86.4 %
Date: 2020-11-20 19:51:53 Branches: 336 533 63.0 %

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

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

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

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

262
  static std::vector<X509*> root_certs_vector;
193

262
  static Mutex root_certs_vector_mutex;
194
524
  Mutex::ScopedLock lock(root_certs_vector_mutex);
195
196

517
  if (root_certs_vector.empty() &&
197
255
      per_process::cli_options->ssl_openssl_cert_store == false) {
198
35306
    for (size_t i = 0; i < arraysize(root_certs); i++) {
199
      X509* x509 =
200
70104
          PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
201
35052
                                              strlen(root_certs[i])).get(),
202
                            nullptr,   // no re-use of X509 structure
203
                            NoPasswordCallback,
204
35052
                            nullptr);  // no callback data
205
206
      // Parse errors from the built-in roots are fatal.
207
35052
      CHECK_NOT_NULL(x509);
208
209
35052
      root_certs_vector.push_back(x509);
210
    }
211
  }
212
213
262
  X509_STORE* store = X509_STORE_new();
214
262
  if (*system_cert_path != '\0') {
215
    ERR_set_mark();
216
    X509_STORE_load_locations(store, system_cert_path, nullptr);
217
    ERR_pop_to_mark();
218
  }
219
220
524
  Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
221
262
  if (per_process::cli_options->ssl_openssl_cert_store) {
222
1
    X509_STORE_set_default_paths(store);
223
  } else {
224
36279
    for (X509* cert : root_certs_vector) {
225
36018
      X509_up_ref(cert);
226
36018
      X509_STORE_add_cert(store, cert);
227
    }
228
  }
229
230
524
  return store;
231
}
232
233
211
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
234
211
  Environment* env = Environment::GetCurrent(args);
235
29329
  Local<Value> result[arraysize(root_certs)];
236
237
29329
  for (size_t i = 0; i < arraysize(root_certs); i++) {
238
58236
    if (!String::NewFromOneByte(
239
            env->isolate(),
240
29118
            reinterpret_cast<const uint8_t*>(root_certs[i]))
241
58236
            .ToLocal(&result[i])) {
242
      return;
243
    }
244
  }
245
246
633
  args.GetReturnValue().Set(
247
      Array::New(env->isolate(), result, arraysize(root_certs)));
248
}
249
250
653
void SecureContext::Initialize(Environment* env, Local<Object> target) {
251
653
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
252
1962
  t->InstanceTemplate()->SetInternalFieldCount(
253
654
      SecureContext::kInternalFieldCount);
254
1307
  t->Inherit(BaseObject::GetConstructorTemplate(env));
255
  Local<String> secureContextString =
256
654
      FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext");
257
653
  t->SetClassName(secureContextString);
258
259
654
  env->SetProtoMethod(t, "init", Init);
260
654
  env->SetProtoMethod(t, "setKey", SetKey);
261
#ifndef OPENSSL_NO_ENGINE
262
654
  env->SetProtoMethod(t, "setEngineKey", SetEngineKey);
263
#endif  // !OPENSSL_NO_ENGINE
264
654
  env->SetProtoMethod(t, "setCert", SetCert);
265
654
  env->SetProtoMethod(t, "addCACert", AddCACert);
266
654
  env->SetProtoMethod(t, "addCRL", AddCRL);
267
654
  env->SetProtoMethod(t, "addRootCerts", AddRootCerts);
268
654
  env->SetProtoMethod(t, "setCipherSuites", SetCipherSuites);
269
654
  env->SetProtoMethod(t, "setCiphers", SetCiphers);
270
654
  env->SetProtoMethod(t, "setSigalgs", SetSigalgs);
271
654
  env->SetProtoMethod(t, "setECDHCurve", SetECDHCurve);
272
654
  env->SetProtoMethod(t, "setDHParam", SetDHParam);
273
654
  env->SetProtoMethod(t, "setMaxProto", SetMaxProto);
274
654
  env->SetProtoMethod(t, "setMinProto", SetMinProto);
275
654
  env->SetProtoMethod(t, "getMaxProto", GetMaxProto);
276
654
  env->SetProtoMethod(t, "getMinProto", GetMinProto);
277
654
  env->SetProtoMethod(t, "setOptions", SetOptions);
278
654
  env->SetProtoMethod(t, "setSessionIdContext", SetSessionIdContext);
279
654
  env->SetProtoMethod(t, "setSessionTimeout", SetSessionTimeout);
280
654
  env->SetProtoMethod(t, "close", Close);
281
654
  env->SetProtoMethod(t, "loadPKCS12", LoadPKCS12);
282
#ifndef OPENSSL_NO_ENGINE
283
654
  env->SetProtoMethod(t, "setClientCertEngine", SetClientCertEngine);
284
#endif  // !OPENSSL_NO_ENGINE
285
654
  env->SetProtoMethodNoSideEffect(t, "getTicketKeys", GetTicketKeys);
286
654
  env->SetProtoMethod(t, "setTicketKeys", SetTicketKeys);
287
654
  env->SetProtoMethod(t, "setFreeListLength", SetFreeListLength);
288
654
  env->SetProtoMethod(t, "enableTicketKeyCallback", EnableTicketKeyCallback);
289
654
  env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate<true>);
290
654
  env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate<false>);
291
292
#define SET_INTEGER_CONSTANTS(name, value)                                     \
293
    t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), name),                        \
294
           Integer::NewFromUnsigned(env->isolate(), value));
295
1962
  SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
296
1962
  SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
297
1962
  SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
298
1962
  SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
299
1961
  SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex);
300
301
#undef SET_INTEGER_CONSTANTS
302
303
  Local<FunctionTemplate> ctx_getter_templ =
304
      FunctionTemplate::New(env->isolate(),
305
                            CtxGetter,
306
                            Local<Value>(),
307
1308
                            Signature::New(env->isolate(), t));
308
309
310
2615
  t->PrototypeTemplate()->SetAccessorProperty(
311
      FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
312
      ctx_getter_templ,
313
      Local<FunctionTemplate>(),
314
654
      static_cast<PropertyAttribute>(ReadOnly | DontDelete));
315
316
1307
  target->Set(env->context(), secureContextString,
317
3268
              t->GetFunction(env->context()).ToLocalChecked()).Check();
318
654
  env->set_secure_context_constructor_template(t);
319
320
  env->SetMethodNoSideEffect(target, "getRootCertificates",
321
654
                             GetRootCertificates);
322
  // Exposed for testing purposes only.
323
  env->SetMethodNoSideEffect(target, "isExtraRootCertsFileLoaded",
324
654
                             IsExtraRootCertsFileLoaded);
325
654
}
326
327
2316
SecureContext::SecureContext(Environment* env, Local<Object> wrap)
328
2316
    : BaseObject(env, wrap) {
329
2316
  MakeWeak();
330
2316
  env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
331
2316
}
332
333
3566
inline void SecureContext::Reset() {
334
3566
  if (ctx_ != nullptr) {
335
2243
    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
336
  }
337
3566
  ctx_.reset();
338
3566
  cert_.reset();
339
3566
  issuer_.reset();
340
3566
}
341
342
6882
SecureContext::~SecureContext() {
343
2294
  Reset();
344
4588
}
345
346
2316
void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
347
2316
  Environment* env = Environment::GetCurrent(args);
348
2316
  new SecureContext(env, args.This());
349
2316
}
350
351
2314
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
352
  SecureContext* sc;
353
2363
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
354
2314
  Environment* env = sc->env();
355
356
2314
  CHECK_EQ(args.Length(), 3);
357
4628
  CHECK(args[1]->IsInt32());
358
4628
  CHECK(args[2]->IsInt32());
359
360
6942
  int min_version = args[1].As<Int32>()->Value();
361
6942
  int max_version = args[2].As<Int32>()->Value();
362
2314
  const SSL_METHOD* method = TLS_method();
363
364
2314
  if (max_version == 0)
365
    max_version = kMaxSupportedVersion;
366
367
6942
  if (args[0]->IsString()) {
368
679
    Utf8Value sslmethod(env->isolate(), args[0]);
369
370
    // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
371
    // are still accepted.  They are OpenSSL's way of saying that all known
372
    // protocols below TLS 1.3 are supported unless explicitly disabled (which
373
    // we do below for SSLv2 and SSLv3.)
374

1077
    if (sslmethod == "SSLv2_method" ||
375

712
        sslmethod == "SSLv2_server_method" ||
376
348
        sslmethod == "SSLv2_client_method") {
377
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
378
17
      return;
379

1026
    } else if (sslmethod == "SSLv3_method" ||
380

678
               sslmethod == "SSLv3_server_method" ||
381
331
               sslmethod == "SSLv3_client_method") {
382
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled");
383
17
      return;
384
330
    } else if (sslmethod == "SSLv23_method") {
385
36
      max_version = TLS1_2_VERSION;
386
294
    } else if (sslmethod == "SSLv23_server_method") {
387
1
      max_version = TLS1_2_VERSION;
388
1
      method = TLS_server_method();
389
293
    } else if (sslmethod == "SSLv23_client_method") {
390
1
      max_version = TLS1_2_VERSION;
391
1
      method = TLS_client_method();
392
292
    } else if (sslmethod == "TLS_method") {
393
53
      min_version = 0;
394
53
      max_version = kMaxSupportedVersion;
395
239
    } else if (sslmethod == "TLS_server_method") {
396
      min_version = 0;
397
      max_version = kMaxSupportedVersion;
398
      method = TLS_server_method();
399
239
    } else if (sslmethod == "TLS_client_method") {
400
      min_version = 0;
401
      max_version = kMaxSupportedVersion;
402
      method = TLS_client_method();
403
239
    } else if (sslmethod == "TLSv1_method") {
404
71
      min_version = TLS1_VERSION;
405
71
      max_version = TLS1_VERSION;
406
168
    } else if (sslmethod == "TLSv1_server_method") {
407
1
      min_version = TLS1_VERSION;
408
1
      max_version = TLS1_VERSION;
409
1
      method = TLS_server_method();
410
167
    } else if (sslmethod == "TLSv1_client_method") {
411
1
      min_version = TLS1_VERSION;
412
1
      max_version = TLS1_VERSION;
413
1
      method = TLS_client_method();
414
166
    } else if (sslmethod == "TLSv1_1_method") {
415
71
      min_version = TLS1_1_VERSION;
416
71
      max_version = TLS1_1_VERSION;
417
95
    } else if (sslmethod == "TLSv1_1_server_method") {
418
1
      min_version = TLS1_1_VERSION;
419
1
      max_version = TLS1_1_VERSION;
420
1
      method = TLS_server_method();
421
94
    } else if (sslmethod == "TLSv1_1_client_method") {
422
1
      min_version = TLS1_1_VERSION;
423
1
      max_version = TLS1_1_VERSION;
424
1
      method = TLS_client_method();
425
93
    } else if (sslmethod == "TLSv1_2_method") {
426
75
      min_version = TLS1_2_VERSION;
427
75
      max_version = TLS1_2_VERSION;
428
18
    } else if (sslmethod == "TLSv1_2_server_method") {
429
2
      min_version = TLS1_2_VERSION;
430
2
      max_version = TLS1_2_VERSION;
431
2
      method = TLS_server_method();
432
16
    } else if (sslmethod == "TLSv1_2_client_method") {
433
1
      min_version = TLS1_2_VERSION;
434
1
      max_version = TLS1_2_VERSION;
435
1
      method = TLS_client_method();
436
    } else {
437
30
      const std::string msg("Unknown method: ");
438
15
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, (msg + * sslmethod).c_str());
439
15
      return;
440
    }
441
  }
442
443
2265
  sc->ctx_.reset(SSL_CTX_new(method));
444
2265
  SSL_CTX_set_app_data(sc->ctx_.get(), sc);
445
446
  // Disable SSLv2 in the case when method == TLS_method() and the
447
  // cipher list contains SSLv2 ciphers (not the default, should be rare.)
448
  // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
449
  // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
450
2265
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2);
451
2265
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3);
452
453
  // Enable automatic cert chaining. This is enabled by default in OpenSSL, but
454
  // disabled by default in BoringSSL. Enable it explicitly to make the
455
  // behavior match when Node is built with BoringSSL.
456
2265
  SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
457
458
  // SSL session cache configuration
459
2265
  SSL_CTX_set_session_cache_mode(sc->ctx_.get(),
460
                                 SSL_SESS_CACHE_CLIENT |
461
                                 SSL_SESS_CACHE_SERVER |
462
                                 SSL_SESS_CACHE_NO_INTERNAL |
463
2265
                                 SSL_SESS_CACHE_NO_AUTO_CLEAR);
464
465
2265
  SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
466
2265
  SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
467
468
  // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
469
  // exposed in the public API. To retain compatibility, install a callback
470
  // which restores the old algorithm.
471

6795
  if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
472

4530
      RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
473
2265
      RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
474
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
475
        env, "Error generating ticket keys");
476
  }
477
2265
  SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
478
}
479
480
12203
SSLPointer SecureContext::CreateSSL() {
481
12203
  return SSLPointer(SSL_new(ctx_.get()));
482
}
483
484
12203
void SecureContext::SetNewSessionCallback(NewSessionCb cb) {
485
12203
  SSL_CTX_sess_set_new_cb(ctx_.get(), cb);
486
12203
}
487
488
12203
void SecureContext::SetGetSessionCallback(GetSessionCb cb) {
489
12203
  SSL_CTX_sess_set_get_cb(ctx_.get(), cb);
490
12203
}
491
492
853
void SecureContext::SetSelectSNIContextCallback(SelectSNIContextCb cb) {
493
853
  SSL_CTX_set_tlsext_servername_callback(ctx_.get(), cb);
494
853
}
495
496
8
void SecureContext::SetKeylogCallback(KeylogCb cb) {
497
8
  SSL_CTX_set_keylog_callback(ctx_.get(), cb);
498
8
}
499
500
833
void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
501
833
  Environment* env = Environment::GetCurrent(args);
502
503
  SecureContext* sc;
504
841
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
505
506
833
  CHECK_GE(args.Length(), 1);  // Private key argument is mandatory
507
508
1658
  BIOPointer bio(LoadBIO(env, args[0]));
509
833
  if (!bio)
510
    return;
511
512
1658
  ByteSource passphrase;
513
2499
  if (args[1]->IsString())
514
48
    passphrase = ByteSource::FromString(env, args[1].As<String>());
515
  // This redirection is necessary because the PasswordCallback expects a
516
  // pointer to a pointer to the passphrase ByteSource to allow passing in
517
  // const ByteSources.
518
833
  const ByteSource* pass_ptr = &passphrase;
519
520
  EVPKeyPointer key(
521
      PEM_read_bio_PrivateKey(bio.get(),
522
                              nullptr,
523
                              PasswordCallback,
524
1658
                              &pass_ptr));
525
526
833
  if (!key)
527
7
    return ThrowCryptoError(env, ERR_get_error(), "PEM_read_bio_PrivateKey");
528
529
826
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
530
1
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
531
}
532
533
8
void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
534
  SecureContext* sc;
535
8
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
536
8
  Environment* env = sc->env();
537
8
  ClearErrorOnReturn clear_error_on_return;
538
539
8
  CHECK_EQ(args.Length(), 1);
540
24
  CHECK(args[0]->IsString());
541
542
16
  const Utf8Value sigalgs(env->isolate(), args[0]);
543
544
8
  if (!SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs))
545
    return ThrowCryptoError(env, ERR_get_error());
546
}
547
548
#ifndef OPENSSL_NO_ENGINE
549
void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
550
  Environment* env = Environment::GetCurrent(args);
551
552
  SecureContext* sc;
553
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
554
555
  CHECK_EQ(args.Length(), 2);
556
557
  CryptoErrorVector errors;
558
  Utf8Value engine_id(env->isolate(), args[1]);
559
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
560
  if (!engine) {
561
    Local<Value> exception;
562
    if (errors.ToException(env).ToLocal(&exception))
563
      env->isolate()->ThrowException(exception);
564
    return;
565
  }
566
567
  if (!ENGINE_init(engine.get())) {
568
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
569
        env, "Failure to initialize engine");
570
  }
571
572
  engine.finish_on_exit = true;
573
574
  Utf8Value key_name(env->isolate(), args[0]);
575
  EVPKeyPointer key(ENGINE_load_private_key(engine.get(), *key_name,
576
                                            nullptr, nullptr));
577
578
  if (!key)
579
    return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
580
581
  if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get()))
582
    return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
583
584
  sc->private_key_engine_ = std::move(engine);
585
}
586
#endif  // !OPENSSL_NO_ENGINE
587
588
851
void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
589
851
  Environment* env = Environment::GetCurrent(args);
590
591
  SecureContext* sc;
592
851
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
593
594
851
  CHECK_GE(args.Length(), 1);  // Certificate argument is mandator
595
596
1702
  BIOPointer bio(LoadBIO(env, args[0]));
597
851
  if (!bio)
598
    return;
599
600
851
  sc->cert_.reset();
601
851
  sc->issuer_.reset();
602
603
2553
  if (!SSL_CTX_use_certificate_chain(
604
851
          sc->ctx_.get(),
605
851
          std::move(bio),
606
851
          &sc->cert_,
607
851
          &sc->issuer_)) {
608
    return ThrowCryptoError(
609
        env,
610
        ERR_get_error(),
611
        "SSL_CTX_use_certificate_chain");
612
  }
613
}
614
615
554
void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
616
554
  Environment* env = Environment::GetCurrent(args);
617
618
  SecureContext* sc;
619
554
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
620
554
  ClearErrorOnReturn clear_error_on_return;
621
622
554
  CHECK_GE(args.Length(), 1);  // CA certificate argument is mandatory
623
624
1108
  BIOPointer bio(LoadBIO(env, args[0]));
625
554
  if (!bio)
626
    return;
627
628
554
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
629
1448
  while (X509* x509 = PEM_read_bio_X509_AUX(
630
1448
      bio.get(), nullptr, NoPasswordCallback, nullptr)) {
631
894
    if (cert_store == root_cert_store) {
632
1
      cert_store = NewRootCertStore();
633
1
      SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
634
    }
635
894
    X509_STORE_add_cert(cert_store, x509);
636
894
    SSL_CTX_add_client_CA(sc->ctx_.get(), x509);
637
894
    X509_free(x509);
638
894
  }
639
}
640
641
2
void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
642
2
  Environment* env = Environment::GetCurrent(args);
643
644
  SecureContext* sc;
645
3
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
646
647
2
  CHECK_GE(args.Length(), 1);  // CRL argument is mandatory
648
649
1
  ClearErrorOnReturn clear_error_on_return;
650
651
3
  BIOPointer bio(LoadBIO(env, args[0]));
652
2
  if (!bio)
653
    return;
654
655
  DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
656
3
      PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
657
658
2
  if (!crl)
659
1
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to parse CRL");
660
661
1
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
662
1
  if (cert_store == root_cert_store) {
663
    cert_store = NewRootCertStore();
664
    SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
665
  }
666
667
1
  X509_STORE_add_crl(cert_store, crl.get());
668
  X509_STORE_set_flags(cert_store,
669
1
                       X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
670
}
671
672
1731
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
673
  SecureContext* sc;
674
1731
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
675
1731
  ClearErrorOnReturn clear_error_on_return;
676
677
1731
  if (root_cert_store == nullptr) {
678
250
    root_cert_store = NewRootCertStore();
679
  }
680
681
  // Increment reference count so global store is not deleted along with CTX.
682
1731
  X509_STORE_up_ref(root_cert_store);
683
1731
  SSL_CTX_set_cert_store(sc->ctx_.get(), root_cert_store);
684
}
685
686
2189
void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
687
  // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
688
#ifndef OPENSSL_IS_BORINGSSL
689
  SecureContext* sc;
690
2190
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
691
2189
  Environment* env = sc->env();
692
2188
  ClearErrorOnReturn clear_error_on_return;
693
694
2189
  CHECK_EQ(args.Length(), 1);
695
6567
  CHECK(args[0]->IsString());
696
697
4377
  const Utf8Value ciphers(env->isolate(), args[0]);
698
2189
  if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
699
1
    return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
700
#endif
701
}
702
703
2191
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
704
  SecureContext* sc;
705
2206
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
706
2191
  Environment* env = sc->env();
707
2176
  ClearErrorOnReturn clear_error_on_return;
708
709
2191
  CHECK_EQ(args.Length(), 1);
710
6573
  CHECK(args[0]->IsString());
711
712
4367
  Utf8Value ciphers(env->isolate(), args[0]);
713
2191
  if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
714
15
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
715
716

15
    if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
717
      // TLS1.2 ciphers were deliberately cleared, so don't consider
718
      // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
719
      // works). If the user actually sets a value (like "no-such-cipher"), then
720
      // that's actually an error.
721
11
      return;
722
    }
723
4
    return ThrowCryptoError(env, err, "Failed to set ciphers");
724
  }
725
}
726
727
2183
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
728
  SecureContext* sc;
729
2186
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
730
2183
  Environment* env = sc->env();
731
732
2183
  CHECK_GE(args.Length(), 1);  // ECDH curve name argument is mandatory
733
6549
  CHECK(args[0]->IsString());
734
735
4363
  Utf8Value curve(env->isolate(), args[0]);
736
737

2193
  if (strcmp(*curve, "auto") != 0 &&
738
10
      !SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve)) {
739
3
    return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to set ECDH curve");
740
  }
741
}
742
743
10
void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
744
  SecureContext* sc;
745
13
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
746
10
  Environment* env = sc->env();
747
7
  ClearErrorOnReturn clear_error_on_return;
748
749
10
  CHECK_GE(args.Length(), 1);  // DH argument is mandatory
750
751
17
  DHPointer dh;
752
  {
753
20
    BIOPointer bio(LoadBIO(env, args[0]));
754
10
    if (!bio)
755
      return;
756
757
10
    dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
758
  }
759
760
  // Invalid dhparam is silently discarded and DHE is no longer used.
761
10
  if (!dh)
762
1
    return;
763
764
  const BIGNUM* p;
765
9
  DH_get0_pqg(dh.get(), &p, nullptr, nullptr);
766
9
  const int size = BN_num_bits(p);
767
9
  if (size < 1024) {
768
    return THROW_ERR_INVALID_ARG_VALUE(
769
2
        env, "DH parameter is less than 1024 bits");
770
7
  } else if (size < 2048) {
771
9
    args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(
772
        env->isolate(), "DH parameter is less than 2048 bits"));
773
  }
774
775
7
  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_DH_USE);
776
777
7
  if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) {
778
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
779
        env, "Error setting temp DH parameter");
780
  }
781
}
782
783
11
void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
784
  SecureContext* sc;
785
11
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
786
787
11
  CHECK_EQ(args.Length(), 1);
788
22
  CHECK(args[0]->IsInt32());
789
790
33
  int version = args[0].As<Int32>()->Value();
791
792
11
  CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
793
}
794
795
46
void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
796
  SecureContext* sc;
797
46
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
798
799
46
  CHECK_EQ(args.Length(), 1);
800
92
  CHECK(args[0]->IsInt32());
801
802
138
  int version = args[0].As<Int32>()->Value();
803
804
46
  CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
805
}
806
807
57
void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
808
  SecureContext* sc;
809
57
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
810
811
57
  CHECK_EQ(args.Length(), 0);
812
813
  long version =  // NOLINT(runtime/int)
814
57
    SSL_CTX_get_min_proto_version(sc->ctx_.get());
815
171
  args.GetReturnValue().Set(static_cast<uint32_t>(version));
816
}
817
818
76
void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
819
  SecureContext* sc;
820
76
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
821
822
76
  CHECK_EQ(args.Length(), 0);
823
824
  long version =  // NOLINT(runtime/int)
825
76
    SSL_CTX_get_max_proto_version(sc->ctx_.get());
826
228
  args.GetReturnValue().Set(static_cast<uint32_t>(version));
827
}
828
829
838
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
830
838
  Environment* env = Environment::GetCurrent(args);
831
  SecureContext* sc;
832
838
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
833
834
838
  CHECK_GE(args.Length(), 1);
835
1676
  CHECK(args[0]->IsNumber());
836
837
3352
  int64_t val = args[0]->IntegerValue(env->context()).FromMaybe(0);
838
839
838
  SSL_CTX_set_options(sc->ctx_.get(),
840
838
                      static_cast<long>(val));  // NOLINT(runtime/int)
841
}
842
843
767
void SecureContext::SetSessionIdContext(
844
    const FunctionCallbackInfo<Value>& args) {
845
  SecureContext* sc;
846
1534
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
847
767
  Environment* env = sc->env();
848
849
767
  CHECK_GE(args.Length(), 1);
850
2301
  CHECK(args[0]->IsString());
851
852
767
  const Utf8Value sessionIdContext(env->isolate(), args[0]);
853
  const unsigned char* sid_ctx =
854
767
      reinterpret_cast<const unsigned char*>(*sessionIdContext);
855
767
  unsigned int sid_ctx_len = sessionIdContext.length();
856
857
767
  if (SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len) == 1)
858
767
    return;
859
860
  BUF_MEM* mem;
861
  Local<String> message;
862
863
  BIOPointer bio(BIO_new(BIO_s_mem()));
864
  if (!bio) {
865
    message = FIXED_ONE_BYTE_STRING(env->isolate(),
866
                                    "SSL_CTX_set_session_id_context error");
867
  } else {
868
    ERR_print_errors(bio.get());
869
    BIO_get_mem_ptr(bio.get(), &mem);
870
    message = OneByteString(env->isolate(), mem->data, mem->length);
871
  }
872
873
  env->isolate()->ThrowException(Exception::TypeError(message));
874
}
875
876
1
void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
877
  SecureContext* sc;
878
1
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
879
880
1
  CHECK_GE(args.Length(), 1);
881
2
  CHECK(args[0]->IsInt32());
882
883
3
  int32_t sessionTimeout = args[0].As<Int32>()->Value();
884
1
  SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout);
885
}
886
887
1272
void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
888
  SecureContext* sc;
889
1272
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
890
1272
  sc->Reset();
891
}
892
893
// Takes .pfx or .p12 and password in string or buffer format
894
18
void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
895
18
  Environment* env = Environment::GetCurrent(args);
896
897
30
  std::vector<char> pass;
898
18
  bool ret = false;
899
900
  SecureContext* sc;
901
18
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
902
12
  ClearErrorOnReturn clear_error_on_return;
903
904
18
  if (args.Length() < 1) {
905
    return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory");
906
  }
907
908
30
  BIOPointer in(LoadBIO(env, args[0]));
909
18
  if (!in) {
910
    return THROW_ERR_CRYPTO_OPERATION_FAILED(
911
        env, "Unable to load PFX certificate");
912
  }
913
914
18
  if (args.Length() >= 2) {
915
15
    THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase");
916
30
    Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>();
917
15
    size_t passlen = abv->ByteLength();
918
15
    pass.resize(passlen + 1);
919
30
    abv->CopyContents(pass.data(), passlen);
920
15
    pass[passlen] = '\0';
921
  }
922
923
  // Free previous certs
924
18
  sc->issuer_.reset();
925
18
  sc->cert_.reset();
926
927
18
  X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
928
929
30
  DeleteFnPtr<PKCS12, PKCS12_free> p12;
930
30
  EVPKeyPointer pkey;
931
30
  X509Pointer cert;
932
30
  StackOfX509 extra_certs;
933
934
18
  PKCS12* p12_ptr = nullptr;
935
18
  EVP_PKEY* pkey_ptr = nullptr;
936
18
  X509* cert_ptr = nullptr;
937
18
  STACK_OF(X509)* extra_certs_ptr = nullptr;
938
36
  if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
939
32
      (p12.reset(p12_ptr), true) &&  // Move ownership to the smart pointer.
940
16
      PKCS12_parse(p12.get(), pass.data(),
941
                   &pkey_ptr,
942
                   &cert_ptr,
943
                   &extra_certs_ptr) &&
944
12
      (pkey.reset(pkey_ptr), cert.reset(cert_ptr),
945
24
       extra_certs.reset(extra_certs_ptr), true) &&  // Move ownership.
946
36
      SSL_CTX_use_certificate_chain(sc->ctx_.get(),
947
12
                                    std::move(cert),
948
                                    extra_certs.get(),
949
12
                                    &sc->cert_,
950

42
                                    &sc->issuer_) &&
951
12
      SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
952
    // Add CA certs too
953
21
    for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
954
9
      X509* ca = sk_X509_value(extra_certs.get(), i);
955
956
9
      if (cert_store == root_cert_store) {
957
6
        cert_store = NewRootCertStore();
958
6
        SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
959
      }
960
9
      X509_STORE_add_cert(cert_store, ca);
961
9
      SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
962
    }
963
12
    ret = true;
964
  }
965
966
18
  if (!ret) {
967
    // TODO(@jasnell): Should this use ThrowCryptoError?
968
6
    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
969
6
    const char* str = ERR_reason_error_string(err);
970
6
    return env->ThrowError(str);
971
  }
972
}
973
974
#ifndef OPENSSL_NO_ENGINE
975
void SecureContext::SetClientCertEngine(
976
    const FunctionCallbackInfo<Value>& args) {
977
  Environment* env = Environment::GetCurrent(args);
978
  CHECK_EQ(args.Length(), 1);
979
  CHECK(args[0]->IsString());
980
981
  SecureContext* sc;
982
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
983
984
  MarkPopErrorOnReturn mark_pop_error_on_return;
985
986
  // SSL_CTX_set_client_cert_engine does not itself support multiple
987
  // calls by cleaning up before overwriting the client_cert_engine
988
  // internal context variable.
989
  // Instead of trying to fix up this problem we in turn also do not
990
  // support multiple calls to SetClientCertEngine.
991
  CHECK(!sc->client_cert_engine_provided_);
992
993
  CryptoErrorVector errors;
994
  const Utf8Value engine_id(env->isolate(), args[0]);
995
  EnginePointer engine = LoadEngineById(*engine_id, &errors);
996
  if (!engine) {
997
    Local<Value> exception;
998
    if (errors.ToException(env).ToLocal(&exception))
999
      env->isolate()->ThrowException(exception);
1000
    return;
1001
  }
1002
1003
  // Note that this takes another reference to `engine`.
1004
  if (!SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get()))
1005
    return ThrowCryptoError(env, ERR_get_error());
1006
  sc->client_cert_engine_provided_ = true;
1007
}
1008
#endif  // !OPENSSL_NO_ENGINE
1009
1010
10
void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1011
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1012
1013
  SecureContext* wrap;
1014
10
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1015
1016
  Local<Object> buff;
1017
20
  if (!Buffer::New(wrap->env(), 48).ToLocal(&buff))
1018
    return;
1019
1020
10
  memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
1021
10
  memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
1022
10
  memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
1023
1024
20
  args.GetReturnValue().Set(buff);
1025
#endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1026
}
1027
1028
23
void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1029
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1030
  SecureContext* wrap;
1031
23
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1032
1033
23
  CHECK_GE(args.Length(), 1);  // Ticket keys argument is mandatory
1034
46
  CHECK(args[0]->IsArrayBufferView());
1035
46
  ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
1036
1037
23
  CHECK_EQ(buf.length(), 48);
1038
1039
23
  memcpy(wrap->ticket_key_name_, buf.data(), 16);
1040
23
  memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16);
1041
23
  memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16);
1042
1043
46
  args.GetReturnValue().Set(true);
1044
#endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1045
}
1046
1047
1298
void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
1048
1298
}
1049
1050
// Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
1051
// the regression test in test/parallel/test-https-resume-after-renew.js.
1052
1
void SecureContext::EnableTicketKeyCallback(
1053
    const FunctionCallbackInfo<Value>& args) {
1054
  SecureContext* wrap;
1055
1
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1056
1057
1
  SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
1058
}
1059
1060
3
int SecureContext::TicketKeyCallback(SSL* ssl,
1061
                                     unsigned char* name,
1062
                                     unsigned char* iv,
1063
                                     EVP_CIPHER_CTX* ectx,
1064
                                     HMAC_CTX* hctx,
1065
                                     int enc) {
1066
  static const int kTicketPartSize = 16;
1067
1068
  SecureContext* sc = static_cast<SecureContext*>(
1069
3
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1070
1071
3
  Environment* env = sc->env();
1072
6
  HandleScope handle_scope(env->isolate());
1073
3
  Context::Scope context_scope(env->context());
1074
1075
12
  Local<Value> argv[3];
1076
1077
12
  if (!Buffer::Copy(
1078
          env,
1079
          reinterpret_cast<char*>(name),
1080

9
          kTicketPartSize).ToLocal(&argv[0]) ||
1081
9
      !Buffer::Copy(
1082
          env,
1083
          reinterpret_cast<char*>(iv),
1084
3
          kTicketPartSize).ToLocal(&argv[1])) {
1085
    return -1;
1086
  }
1087
1088
6
  argv[2] = env != 0 ? v8::True(env->isolate()) : v8::False(env->isolate());
1089
1090
  Local<Value> ret;
1091
9
  if (!node::MakeCallback(
1092
          env->isolate(),
1093
          sc->object(),
1094
          env->ticketkeycallback_string(),
1095
3
          arraysize(argv),
1096
          argv,
1097

15
          {0, 0}).ToLocal(&ret) ||
1098
3
      !ret->IsArray()) {
1099
    return -1;
1100
  }
1101
3
  Local<Array> arr = ret.As<Array>();
1102
1103
  Local<Value> val;
1104

12
  if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) ||
1105
3
      !val->IsInt32()) {
1106
    return -1;
1107
  }
1108
1109
6
  int r = val.As<Int32>()->Value();
1110
3
  if (r < 0)
1111
    return r;
1112
1113
  Local<Value> hmac;
1114
  Local<Value> aes;
1115
1116

18
  if (!arr->Get(env->context(), kTicketKeyHMACIndex).ToLocal(&hmac) ||
1117

15
      !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) ||
1118
3
      Buffer::Length(aes) != kTicketPartSize) {
1119
    return -1;
1120
  }
1121
1122
3
  if (enc) {
1123
    Local<Value> name_val;
1124
    Local<Value> iv_val;
1125

12
    if (!arr->Get(env->context(), kTicketKeyNameIndex).ToLocal(&name_val) ||
1126
10
        !arr->Get(env->context(), kTicketKeyIVIndex).ToLocal(&iv_val) ||
1127

6
        Buffer::Length(name_val) != kTicketPartSize ||
1128
2
        Buffer::Length(iv_val) != kTicketPartSize) {
1129
      return -1;
1130
    }
1131
1132
4
    name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1133
4
    iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1134
  }
1135
1136
3
  ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1137
6
  HMAC_Init_ex(hctx,
1138
3
               hmac_buf.data(),
1139
3
               hmac_buf.length(),
1140
               EVP_sha256(),
1141
3
               nullptr);
1142
1143
3
  ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1144
3
  if (enc) {
1145
2
    EVP_EncryptInit_ex(ectx,
1146
                       EVP_aes_128_cbc(),
1147
                       nullptr,
1148
                       aes_key.data(),
1149
2
                       iv);
1150
  } else {
1151
1
    EVP_DecryptInit_ex(ectx,
1152
                       EVP_aes_128_cbc(),
1153
                       nullptr,
1154
                       aes_key.data(),
1155
1
                       iv);
1156
  }
1157
1158
3
  return r;
1159
}
1160
1161
1178
int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1162
                                               unsigned char* name,
1163
                                               unsigned char* iv,
1164
                                               EVP_CIPHER_CTX* ectx,
1165
                                               HMAC_CTX* hctx,
1166
                                               int enc) {
1167
  SecureContext* sc = static_cast<SecureContext*>(
1168
1178
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1169
1170
1178
  if (enc) {
1171
1124
    memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1172

3372
    if (RAND_bytes(iv, 16) <= 0 ||
1173
1124
        EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
1174

2248
                           sc->ticket_key_aes_, iv) <= 0 ||
1175
1124
        HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1176
                     EVP_sha256(), nullptr) <= 0) {
1177
      return -1;
1178
    }
1179
1124
    return 1;
1180
  }
1181
1182
54
  if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1183
    // The ticket key name does not match. Discard the ticket.
1184
12
    return 0;
1185
  }
1186
1187
84
  if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1188

84
                         iv) <= 0 ||
1189
42
      HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1190
                   EVP_sha256(), nullptr) <= 0) {
1191
    return -1;
1192
  }
1193
42
  return 1;
1194
}
1195
1196
2
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1197
  SecureContext* sc;
1198
2
  ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1199
4
  Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1200
4
  info.GetReturnValue().Set(ext);
1201
}
1202
1203
template <bool primary>
1204
6
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1205
  SecureContext* wrap;
1206

6
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1207
6
  Environment* env = wrap->env();
1208
  X509* cert;
1209
1210
  if (primary)
1211
3
    cert = wrap->cert_.get();
1212
  else
1213
3
    cert = wrap->issuer_.get();
1214

6
  if (cert == nullptr)
1215
    return args.GetReturnValue().SetNull();
1216
1217
6
  int size = i2d_X509(cert, nullptr);
1218
  Local<Object> buff;
1219

12
  if (!Buffer::New(env, size).ToLocal(&buff))
1220
    return;
1221
  unsigned char* serialized = reinterpret_cast<unsigned char*>(
1222
6
      Buffer::Data(buff));
1223
6
  i2d_X509(cert, &serialized);
1224
1225
12
  args.GetReturnValue().Set(buff);
1226
}
1227
1228
namespace {
1229
4
unsigned long AddCertsFromFile(  // NOLINT(runtime/int)
1230
    X509_STORE* store,
1231
    const char* file) {
1232
4
  ERR_clear_error();
1233
8
  MarkPopErrorOnReturn mark_pop_error_on_return;
1234
1235
8
  BIOPointer bio(BIO_new_file(file, "r"));
1236
4
  if (!bio)
1237
1
    return ERR_get_error();
1238
1239
  while (X509* x509 =
1240
6
      PEM_read_bio_X509(bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1241
3
    X509_STORE_add_cert(store, x509);
1242
3
    X509_free(x509);
1243
3
  }
1244
1245
3
  unsigned long err = ERR_peek_error();  // NOLINT(runtime/int)
1246
  // Ignore error if its EOF/no start line found.
1247

6
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1248
3
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1249
3
    return 0;
1250
  }
1251
1252
  return err;
1253
}
1254
}  // namespace
1255
1256
// UseExtraCaCerts is called only once at the start of the Node.js process.
1257
4
void UseExtraCaCerts(const std::string& file) {
1258
4
  ClearErrorOnReturn clear_error_on_return;
1259
1260
4
  if (root_cert_store == nullptr) {
1261
4
    root_cert_store = NewRootCertStore();
1262
1263
4
    if (!file.empty()) {
1264
4
      unsigned long err = AddCertsFromFile(  // NOLINT(runtime/int)
1265
                                           root_cert_store,
1266
4
                                           file.c_str());
1267
4
      if (err) {
1268
1
        fprintf(stderr,
1269
                "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1270
                file.c_str(),
1271
1
                ERR_error_string(err, nullptr));
1272
      } else {
1273
3
        extra_root_certs_loaded = true;
1274
      }
1275
    }
1276
  }
1277
4
}
1278
1279
// Exposed to JavaScript strictly for testing purposes.
1280
3
void IsExtraRootCertsFileLoaded(
1281
    const FunctionCallbackInfo<Value>& args) {
1282
9
  return args.GetReturnValue().Set(extra_root_certs_loaded);
1283
}
1284
1285
}  // namespace crypto
1286

14034
}  // namespace node