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: 588 693 84.8 %
Date: 2021-06-10 04:11:54 Branches: 336 537 62.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
2317
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
56
4634
  HandleScope scope(env->isolate());
57
58
4634
  if (v->IsString()) {
59
2652
    Utf8Value s(env->isolate(), v);
60
1326
    return NodeBIO::NewFixed(*s, s.length());
61
  }
62
63
991
  if (v->IsArrayBufferView()) {
64
991
    ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
65
991
    return NodeBIO::NewFixed(buf.data(), buf.length());
66
  }
67
68
  return nullptr;
69
}
70
71
namespace {
72
881
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
881
  CHECK(!*issuer_);
78
881
  CHECK(!*cert);
79
881
  X509* issuer = nullptr;
80
81
881
  int ret = SSL_CTX_use_certificate(ctx, x.get());
82
83
881
  if (ret) {
84
    // If we could set up our certificate, now proceed to
85
    // the CA certificates.
86
881
    SSL_CTX_clear_extra_chain_certs(ctx);
87
88
1300
    for (int i = 0; i < sk_X509_num(extra_certs); i++) {
89
419
      X509* ca = sk_X509_value(extra_certs, i);
90
91
      // NOTE: Increments reference count on `ca`
92
419
      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

419
      if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
104
4
        continue;
105
106
415
      issuer = ca;
107
    }
108
  }
109
110
  // Try getting issuer from a cert store
111
881
  if (ret) {
112
881
    if (issuer == nullptr) {
113
466
      ret = SSL_CTX_get_issuer(ctx, x.get(), &issuer);
114
466
      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
415
      issuer = X509_dup(issuer);
120
415
      if (issuer == nullptr) {
121
        ret = 0;
122
      }
123
    }
124
  }
125
126
881
  issuer_->reset(issuer);
127
128

881
  if (ret && x != nullptr) {
129
881
    cert->reset(X509_dup(x.get()));
130
881
    if (!*cert)
131
      ret = 0;
132
  }
133
881
  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
869
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
869
  ERR_clear_error();
148
149
  X509Pointer x(
150
1738
      PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
151
152
869
  if (!x)
153
    return 0;
154
155
869
  unsigned long err = 0;  // NOLINT(runtime/int)
156
157
1738
  StackOfX509 extra_certs(sk_X509_new_null());
158
869
  if (!extra_certs)
159
    return 0;
160
161
  while (X509Pointer extra {PEM_read_bio_X509(in.get(),
162
                                    nullptr,
163
                                    NoPasswordCallback,
164
1279
                                    nullptr)}) {
165
410
    if (sk_X509_push(extra_certs.get(), extra.get())) {
166
410
      extra.release();
167
410
      continue;
168
    }
169
170
    return 0;
171
410
  }
172
173
  // When the while loop ends, it's usually just EOF.
174
869
  err = ERR_peek_last_error();
175

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

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

273
  static Mutex root_certs_vector_mutex;
195
546
  Mutex::ScopedLock lock(root_certs_vector_mutex);
196
197

539
  if (root_certs_vector.empty() &&
198
266
      per_process::cli_options->ssl_openssl_cert_store == false) {
199
36835
    for (size_t i = 0; i < arraysize(root_certs); i++) {
200
      X509* x509 =
201
73140
          PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
202
36570
                                              strlen(root_certs[i])).get(),
203
                            nullptr,   // no re-use of X509 structure
204
                            NoPasswordCallback,
205
36570
                            nullptr);  // no callback data
206
207
      // Parse errors from the built-in roots are fatal.
208
36570
      CHECK_NOT_NULL(x509);
209
210
36570
      root_certs_vector.push_back(x509);
211
    }
212
  }
213
214
273
  X509_STORE* store = X509_STORE_new();
215
273
  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
546
  Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
222
273
  if (per_process::cli_options->ssl_openssl_cert_store) {
223
1
    X509_STORE_set_default_paths(store);
224
  } else {
225
37808
    for (X509* cert : root_certs_vector) {
226
37536
      X509_up_ref(cert);
227
37536
      X509_STORE_add_cert(store, cert);
228
    }
229
  }
230
231
546
  return store;
232
}
233
234
221
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
235
221
  Environment* env = Environment::GetCurrent(args);
236
30719
  Local<Value> result[arraysize(root_certs)];
237
238
30719
  for (size_t i = 0; i < arraysize(root_certs); i++) {
239
60996
    if (!String::NewFromOneByte(
240
            env->isolate(),
241
30498
            reinterpret_cast<const uint8_t*>(root_certs[i]))
242
60996
            .ToLocal(&result[i])) {
243
      return;
244
    }
245
  }
246
247
663
  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
4169
Local<FunctionTemplate> SecureContext::GetConstructorTemplate(
256
    Environment* env) {
257
4169
  Local<FunctionTemplate> tmpl = env->secure_context_constructor_template();
258
4169
  if (tmpl.IsEmpty()) {
259
4169
    tmpl = env->NewFunctionTemplate(New);
260
12507
    tmpl->InstanceTemplate()->SetInternalFieldCount(
261
4169
        SecureContext::kInternalFieldCount);
262
8338
    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
263
8338
    tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"));
264
265
4169
    env->SetProtoMethod(tmpl, "init", Init);
266
4169
    env->SetProtoMethod(tmpl, "setKey", SetKey);
267
4169
    env->SetProtoMethod(tmpl, "setCert", SetCert);
268
4169
    env->SetProtoMethod(tmpl, "addCACert", AddCACert);
269
4169
    env->SetProtoMethod(tmpl, "addCRL", AddCRL);
270
4169
    env->SetProtoMethod(tmpl, "addRootCerts", AddRootCerts);
271
4169
    env->SetProtoMethod(tmpl, "setCipherSuites", SetCipherSuites);
272
4169
    env->SetProtoMethod(tmpl, "setCiphers", SetCiphers);
273
4169
    env->SetProtoMethod(tmpl, "setSigalgs", SetSigalgs);
274
4169
    env->SetProtoMethod(tmpl, "setECDHCurve", SetECDHCurve);
275
4169
    env->SetProtoMethod(tmpl, "setDHParam", SetDHParam);
276
4169
    env->SetProtoMethod(tmpl, "setMaxProto", SetMaxProto);
277
4169
    env->SetProtoMethod(tmpl, "setMinProto", SetMinProto);
278
4169
    env->SetProtoMethod(tmpl, "getMaxProto", GetMaxProto);
279
4169
    env->SetProtoMethod(tmpl, "getMinProto", GetMinProto);
280
4169
    env->SetProtoMethod(tmpl, "setOptions", SetOptions);
281
4169
    env->SetProtoMethod(tmpl, "setSessionIdContext", SetSessionIdContext);
282
4169
    env->SetProtoMethod(tmpl, "setSessionTimeout", SetSessionTimeout);
283
4169
    env->SetProtoMethod(tmpl, "close", Close);
284
4169
    env->SetProtoMethod(tmpl, "loadPKCS12", LoadPKCS12);
285
4169
    env->SetProtoMethod(tmpl, "setTicketKeys", SetTicketKeys);
286
4169
    env->SetProtoMethod(tmpl, "setFreeListLength", SetFreeListLength);
287
    env->SetProtoMethod(tmpl, "enableTicketKeyCallback",
288
4169
        EnableTicketKeyCallback);
289
290
4169
    env->SetProtoMethodNoSideEffect(tmpl, "getTicketKeys", GetTicketKeys);
291
    env->SetProtoMethodNoSideEffect(tmpl, "getCertificate",
292
4169
        GetCertificate<true>);
293
    env->SetProtoMethodNoSideEffect(tmpl, "getIssuer",
294
4169
        GetCertificate<false>);
295
296
  #ifndef OPENSSL_NO_ENGINE
297
4169
    env->SetProtoMethod(tmpl, "setEngineKey", SetEngineKey);
298
4169
    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
12507
    SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
305
12507
    SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
306
12507
    SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
307
12507
    SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
308
12507
    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
8338
                              Signature::New(env->isolate(), tmpl));
316
317
16676
    tmpl->PrototypeTemplate()->SetAccessorProperty(
318
        FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
319
        ctx_getter_templ,
320
        Local<FunctionTemplate>(),
321
4169
        static_cast<PropertyAttribute>(ReadOnly | DontDelete));
322
323
4169
    env->set_secure_context_constructor_template(tmpl);
324
  }
325
4169
  return tmpl;
326
}
327
328
4169
void SecureContext::Initialize(Environment* env, Local<Object> target) {
329
4169
  env->SetConstructorFunction(
330
      target,
331
      "SecureContext",
332
      GetConstructorTemplate(env),
333
4169
      Environment::SetConstructorFunctionFlag::NONE);
334
335
  env->SetMethodNoSideEffect(target, "getRootCertificates",
336
4169
                             GetRootCertificates);
337
  // Exposed for testing purposes only.
338
  env->SetMethodNoSideEffect(target, "isExtraRootCertsFileLoaded",
339
4169
                             IsExtraRootCertsFileLoaded);
340
4169
}
341
342
SecureContext* SecureContext::Create(Environment* env) {
343
  Local<Object> obj;
344
  if (!GetConstructorTemplate(env)
345
          ->InstanceTemplate()
346
          ->NewInstance(env->context()).ToLocal(&obj)) {
347
    return nullptr;
348
  }
349
350
  return new SecureContext(env, obj);
351
}
352
353
2363
SecureContext::SecureContext(Environment* env, Local<Object> wrap)
354
2363
    : BaseObject(env, wrap) {
355
2363
  MakeWeak();
356
2363
  env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
357
2363
}
358
359
2339
inline void SecureContext::Reset() {
360
2339
  if (ctx_ != nullptr) {
361
2288
    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
362
  }
363
2339
  ctx_.reset();
364
2339
  cert_.reset();
365
2339
  issuer_.reset();
366
2339
}
367
368
7017
SecureContext::~SecureContext() {
369
2339
  Reset();
370
4678
}
371
372
2363
void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
373
2363
  Environment* env = Environment::GetCurrent(args);
374
2363
  new SecureContext(env, args.This());
375
2363
}
376
377
2361
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
378
  SecureContext* sc;
379
2410
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
380
2361
  Environment* env = sc->env();
381
382
2361
  CHECK_EQ(args.Length(), 3);
383
4722
  CHECK(args[1]->IsInt32());
384
4722
  CHECK(args[2]->IsInt32());
385
386
7083
  int min_version = args[1].As<Int32>()->Value();
387
7083
  int max_version = args[2].As<Int32>()->Value();
388
2361
  const SSL_METHOD* method = TLS_method();
389
390
2361
  if (max_version == 0)
391
    max_version = kMaxSupportedVersion;
392
393
7083
  if (args[0]->IsString()) {
394
679
    Utf8Value sslmethod(env->isolate(), args[0]);
395
396
    // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
397
    // are still accepted.  They are OpenSSL's way of saying that all known
398
    // protocols below TLS 1.3 are supported unless explicitly disabled (which
399
    // we do below for SSLv2 and SSLv3.)
400

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

712
        sslmethod == "SSLv2_server_method" ||
402
348
        sslmethod == "SSLv2_client_method") {
403
17
      THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
404
17
      return;
405

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

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

6936
  if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
498

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

15
    if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
743
      // TLS1.2 ciphers were deliberately cleared, so don't consider
744
      // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
745
      // works). If the user actually sets a value (like "no-such-cipher"), then
746
      // that's actually an error.
747
11
      return;
748
    }
749
4
    return ThrowCryptoError(env, err, "Failed to set ciphers");
750
  }
751
}
752
753
2230
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
754
  SecureContext* sc;
755
2233
  ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
756
2230
  Environment* env = sc->env();
757
758
2230
  CHECK_GE(args.Length(), 1);  // ECDH curve name argument is mandatory
759
6690
  CHECK(args[0]->IsString());
760
761
4457
  Utf8Value curve(env->isolate(), args[0]);
762
763

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

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

9
          kTicketPartSize).ToLocal(&argv[0]) ||
1107
9
      !Buffer::Copy(
1108
          env,
1109
          reinterpret_cast<char*>(iv),
1110
3
          kTicketPartSize).ToLocal(&argv[1])) {
1111
    return -1;
1112
  }
1113
1114
6
  argv[2] = env != 0 ? v8::True(env->isolate()) : v8::False(env->isolate());
1115
1116
  Local<Value> ret;
1117
9
  if (!node::MakeCallback(
1118
          env->isolate(),
1119
          sc->object(),
1120
          env->ticketkeycallback_string(),
1121
3
          arraysize(argv),
1122
          argv,
1123

15
          {0, 0}).ToLocal(&ret) ||
1124
3
      !ret->IsArray()) {
1125
    return -1;
1126
  }
1127
3
  Local<Array> arr = ret.As<Array>();
1128
1129
  Local<Value> val;
1130

12
  if (!arr->Get(env->context(), kTicketKeyReturnIndex).ToLocal(&val) ||
1131
3
      !val->IsInt32()) {
1132
    return -1;
1133
  }
1134
1135
6
  int r = val.As<Int32>()->Value();
1136
3
  if (r < 0)
1137
    return r;
1138
1139
  Local<Value> hmac;
1140
  Local<Value> aes;
1141
1142

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

15
      !arr->Get(env->context(), kTicketKeyAESIndex).ToLocal(&aes) ||
1144
3
      Buffer::Length(aes) != kTicketPartSize) {
1145
    return -1;
1146
  }
1147
1148
3
  if (enc) {
1149
    Local<Value> name_val;
1150
    Local<Value> iv_val;
1151

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

6
        Buffer::Length(name_val) != kTicketPartSize ||
1154
2
        Buffer::Length(iv_val) != kTicketPartSize) {
1155
      return -1;
1156
    }
1157
1158
4
    name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1159
4
    iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1160
  }
1161
1162
3
  ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1163
6
  HMAC_Init_ex(hctx,
1164
3
               hmac_buf.data(),
1165
3
               hmac_buf.length(),
1166
               EVP_sha256(),
1167
3
               nullptr);
1168
1169
3
  ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1170
3
  if (enc) {
1171
2
    EVP_EncryptInit_ex(ectx,
1172
                       EVP_aes_128_cbc(),
1173
                       nullptr,
1174
                       aes_key.data(),
1175
2
                       iv);
1176
  } else {
1177
1
    EVP_DecryptInit_ex(ectx,
1178
                       EVP_aes_128_cbc(),
1179
                       nullptr,
1180
                       aes_key.data(),
1181
1
                       iv);
1182
  }
1183
1184
3
  return r;
1185
}
1186
1187
1192
int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1188
                                               unsigned char* name,
1189
                                               unsigned char* iv,
1190
                                               EVP_CIPHER_CTX* ectx,
1191
                                               HMAC_CTX* hctx,
1192
                                               int enc) {
1193
  SecureContext* sc = static_cast<SecureContext*>(
1194
1192
      SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1195
1196
1192
  if (enc) {
1197
1138
    memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1198

3414
    if (RAND_bytes(iv, 16) <= 0 ||
1199
1138
        EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
1200

2276
                           sc->ticket_key_aes_, iv) <= 0 ||
1201
1138
        HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1202
                     EVP_sha256(), nullptr) <= 0) {
1203
      return -1;
1204
    }
1205
1138
    return 1;
1206
  }
1207
1208
54
  if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1209
    // The ticket key name does not match. Discard the ticket.
1210
12
    return 0;
1211
  }
1212
1213
84
  if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1214

84
                         iv) <= 0 ||
1215
42
      HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1216
                   EVP_sha256(), nullptr) <= 0) {
1217
    return -1;
1218
  }
1219
42
  return 1;
1220
}
1221
1222
2
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1223
  SecureContext* sc;
1224
2
  ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1225
4
  Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1226
4
  info.GetReturnValue().Set(ext);
1227
}
1228
1229
template <bool primary>
1230
6
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1231
  SecureContext* wrap;
1232

6
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1233
6
  Environment* env = wrap->env();
1234
  X509* cert;
1235
1236
  if (primary)
1237
3
    cert = wrap->cert_.get();
1238
  else
1239
3
    cert = wrap->issuer_.get();
1240

6
  if (cert == nullptr)
1241
    return args.GetReturnValue().SetNull();
1242
1243
6
  int size = i2d_X509(cert, nullptr);
1244
  Local<Object> buff;
1245

12
  if (!Buffer::New(env, size).ToLocal(&buff))
1246
    return;
1247
  unsigned char* serialized = reinterpret_cast<unsigned char*>(
1248
6
      Buffer::Data(buff));
1249
6
  i2d_X509(cert, &serialized);
1250
1251
12
  args.GetReturnValue().Set(buff);
1252
}
1253
1254
namespace {
1255
4
unsigned long AddCertsFromFile(  // NOLINT(runtime/int)
1256
    X509_STORE* store,
1257
    const char* file) {
1258
4
  ERR_clear_error();
1259
8
  MarkPopErrorOnReturn mark_pop_error_on_return;
1260
1261
8
  BIOPointer bio(BIO_new_file(file, "r"));
1262
4
  if (!bio)
1263
1
    return ERR_get_error();
1264
1265
  while (X509* x509 =
1266
6
      PEM_read_bio_X509(bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1267
3
    X509_STORE_add_cert(store, x509);
1268
3
    X509_free(x509);
1269
3
  }
1270
1271
3
  unsigned long err = ERR_peek_error();  // NOLINT(runtime/int)
1272
  // Ignore error if its EOF/no start line found.
1273

6
  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1274
3
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1275
3
    return 0;
1276
  }
1277
1278
  return err;
1279
}
1280
}  // namespace
1281
1282
// UseExtraCaCerts is called only once at the start of the Node.js process.
1283
4
void UseExtraCaCerts(const std::string& file) {
1284
4
  ClearErrorOnReturn clear_error_on_return;
1285
1286
4
  if (root_cert_store == nullptr) {
1287
4
    root_cert_store = NewRootCertStore();
1288
1289
4
    if (!file.empty()) {
1290
4
      unsigned long err = AddCertsFromFile(  // NOLINT(runtime/int)
1291
                                           root_cert_store,
1292
4
                                           file.c_str());
1293
4
      if (err) {
1294
1
        fprintf(stderr,
1295
                "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1296
                file.c_str(),
1297
1
                ERR_error_string(err, nullptr));
1298
      } else {
1299
3
        extra_root_certs_loaded = true;
1300
      }
1301
    }
1302
  }
1303
4
}
1304
1305
// Exposed to JavaScript strictly for testing purposes.
1306
3
void IsExtraRootCertsFileLoaded(
1307
    const FunctionCallbackInfo<Value>& args) {
1308
9
  return args.GetReturnValue().Set(extra_root_certs_loaded);
1309
}
1310
1311
}  // namespace crypto
1312

14538
}  // namespace node