1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 #include "node_crypto.h"
23 #include "node_buffer.h"
24 #include "node_crypto_bio.h"
25 #include "node_crypto_common.h"
26 #include "node_crypto_clienthello-inl.h"
27 #include "node_crypto_groups.h"
28 #include "node_errors.h"
29 #include "node_mutex.h"
30 #include "node_process-inl.h"
31 #include "allocated_buffer-inl.h"
32 #include "tls_wrap.h" // TLSWrap
33
34 #include "async_wrap-inl.h"
35 #include "base_object-inl.h"
36 #include "env-inl.h"
37 #include "memory_tracker-inl.h"
38 #include "string_bytes.h"
39 #include "threadpoolwork-inl.h"
40 #include "util-inl.h"
41 #include "v8.h"
42
43 #include <openssl/ec.h>
44 #include <openssl/ecdh.h>
45 #ifndef OPENSSL_NO_ENGINE
46 # include <openssl/engine.h>
47 #endif // !OPENSSL_NO_ENGINE
48
49 #ifdef OPENSSL_FIPS
50 # include <openssl/fips.h>
51 #endif // OPENSSL_FIPS
52
53 #include <openssl/evp.h>
54 #include <openssl/pem.h>
55 #include <openssl/x509v3.h>
56 #include <openssl/hmac.h>
57 #include <openssl/rand.h>
58 #include <openssl/pkcs12.h>
59
60 #include <cerrno>
61 #include <climits> // INT_MAX
62 #include <cstring>
63
64 #include <algorithm>
65 #include <memory>
66 #include <utility>
67 #include <vector>
68
69 namespace node {
70 namespace crypto {
71
72 using node::THROW_ERR_TLS_INVALID_PROTOCOL_METHOD;
73
74 using v8::Array;
75 using v8::ArrayBuffer;
76 using v8::ArrayBufferView;
77 using v8::BackingStore;
78 using v8::Boolean;
79 using v8::ConstructorBehavior;
80 using v8::Context;
81 using v8::DontDelete;
82 using v8::Exception;
83 using v8::External;
84 using v8::False;
85 using v8::Function;
86 using v8::FunctionCallback;
87 using v8::FunctionCallbackInfo;
88 using v8::FunctionTemplate;
89 using v8::HandleScope;
90 using v8::Int32;
91 using v8::Integer;
92 using v8::Isolate;
93 using v8::Just;
94 using v8::Local;
95 using v8::Maybe;
96 using v8::MaybeLocal;
97 using v8::NewStringType;
98 using v8::Nothing;
99 using v8::Null;
100 using v8::Object;
101 using v8::PropertyAttribute;
102 using v8::ReadOnly;
103 using v8::SideEffectType;
104 using v8::Signature;
105 using v8::String;
106 using v8::TryCatch;
107 using v8::Uint32;
108 using v8::Uint8Array;
109 using v8::Undefined;
110 using v8::Value;
111
112 #ifdef OPENSSL_NO_OCB
113 # define IS_OCB_MODE(mode) false
114 #else
115 # define IS_OCB_MODE(mode) ((mode) == EVP_CIPH_OCB_MODE)
116 #endif
117
118 static const char* const root_certs[] = {
119 #include "node_root_certs.h" // NOLINT(build/include_order)
120 };
121
122 static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH;
123
124 static X509_STORE* root_cert_store;
125
126 static bool extra_root_certs_loaded = false;
127
128 // Just to generate static methods
129 template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
130 Local<FunctionTemplate> t);
131 template void SSLWrap<TLSWrap>::ConfigureSecureContext(SecureContext* sc);
132 template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc);
133 template void SSLWrap<TLSWrap>::MemoryInfo(MemoryTracker* tracker) const;
134 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
135 SSL* s,
136 const unsigned char* key,
137 int len,
138 int* copy);
139 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
140 SSL_SESSION* sess);
141 template void SSLWrap<TLSWrap>::KeylogCallback(const SSL* s,
142 const char* line);
143 template void SSLWrap<TLSWrap>::OnClientHello(
144 void* arg,
145 const ClientHelloParser::ClientHello& hello);
146 template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
147 template void SSLWrap<TLSWrap>::DestroySSL();
148 template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void* arg);
149 template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void* arg);
150 template int SSLWrap<TLSWrap>::SelectALPNCallback(
151 SSL* s,
152 const unsigned char** out,
153 unsigned char* outlen,
154 const unsigned char* in,
155 unsigned int inlen,
156 void* arg);
157
158 template <typename T>
Decode(const FunctionCallbackInfo<Value> & args,void (* callback)(T *,const FunctionCallbackInfo<Value> &,const char *,size_t))159 void Decode(const FunctionCallbackInfo<Value>& args,
160 void (*callback)(T*, const FunctionCallbackInfo<Value>&,
161 const char*, size_t)) {
162 T* ctx;
163 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
164
165 if (args[0]->IsString()) {
166 StringBytes::InlineDecoder decoder;
167 Environment* env = Environment::GetCurrent(args);
168 enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
169 if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
170 return;
171 callback(ctx, args, decoder.out(), decoder.size());
172 } else {
173 ArrayBufferViewContents<char> buf(args[0]);
174 callback(ctx, args, buf.data(), buf.length());
175 }
176 }
177
PasswordCallback(char * buf,int size,int rwflag,void * u)178 static int PasswordCallback(char* buf, int size, int rwflag, void* u) {
179 const char* passphrase = static_cast<char*>(u);
180 if (passphrase != nullptr) {
181 size_t buflen = static_cast<size_t>(size);
182 size_t len = strlen(passphrase);
183 if (buflen < len)
184 return -1;
185 memcpy(buf, passphrase, len);
186 return len;
187 }
188
189 return -1;
190 }
191
TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value> & args)192 void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) {
193 #ifdef OPENSSL_FIPS
194 const auto enabled = FIPS_selftest() ? 1 : 0;
195 #else // OPENSSL_FIPS
196 const auto enabled = 0;
197 #endif // OPENSSL_FIPS
198
199 args.GetReturnValue().Set(enabled);
200 }
201
202 // Loads OpenSSL engine by engine id and returns it. The loaded engine
203 // gets a reference so remember the corresponding call to ENGINE_free.
204 // In case of error the appropriate js exception is scheduled
205 // and nullptr is returned.
206 #ifndef OPENSSL_NO_ENGINE
LoadEngineById(const char * engine_id,char (* errmsg)[1024])207 static ENGINE* LoadEngineById(const char* engine_id, char (*errmsg)[1024]) {
208 MarkPopErrorOnReturn mark_pop_error_on_return;
209
210 ENGINE* engine = ENGINE_by_id(engine_id);
211
212 if (engine == nullptr) {
213 // Engine not found, try loading dynamically.
214 engine = ENGINE_by_id("dynamic");
215 if (engine != nullptr) {
216 if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", engine_id, 0) ||
217 !ENGINE_ctrl_cmd_string(engine, "LOAD", nullptr, 0)) {
218 ENGINE_free(engine);
219 engine = nullptr;
220 }
221 }
222 }
223
224 if (engine == nullptr) {
225 int err = ERR_get_error();
226 if (err != 0) {
227 ERR_error_string_n(err, *errmsg, sizeof(*errmsg));
228 } else {
229 snprintf(*errmsg, sizeof(*errmsg),
230 "Engine \"%s\" was not found", engine_id);
231 }
232 }
233
234 return engine;
235 }
236 #endif // !OPENSSL_NO_ENGINE
237
238 // This callback is used to avoid the default passphrase callback in OpenSSL
239 // which will typically prompt for the passphrase. The prompting is designed
240 // for the OpenSSL CLI, but works poorly for Node.js because it involves
241 // synchronous interaction with the controlling terminal, something we never
242 // want, and use this function to avoid it.
NoPasswordCallback(char * buf,int size,int rwflag,void * u)243 static int NoPasswordCallback(char* buf, int size, int rwflag, void* u) {
244 return 0;
245 }
246
247
248 // namespace node::crypto::error
249 namespace error {
Decorate(Environment * env,Local<Object> obj,unsigned long err)250 Maybe<bool> Decorate(Environment* env, Local<Object> obj,
251 unsigned long err) { // NOLINT(runtime/int)
252 if (err == 0) return Just(true); // No decoration necessary.
253
254 const char* ls = ERR_lib_error_string(err);
255 const char* fs = ERR_func_error_string(err);
256 const char* rs = ERR_reason_error_string(err);
257
258 Isolate* isolate = env->isolate();
259 Local<Context> context = isolate->GetCurrentContext();
260
261 if (ls != nullptr) {
262 if (obj->Set(context, env->library_string(),
263 OneByteString(isolate, ls)).IsNothing()) {
264 return Nothing<bool>();
265 }
266 }
267 if (fs != nullptr) {
268 if (obj->Set(context, env->function_string(),
269 OneByteString(isolate, fs)).IsNothing()) {
270 return Nothing<bool>();
271 }
272 }
273 if (rs != nullptr) {
274 if (obj->Set(context, env->reason_string(),
275 OneByteString(isolate, rs)).IsNothing()) {
276 return Nothing<bool>();
277 }
278
279 // SSL has no API to recover the error name from the number, so we
280 // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
281 // which ends up being close to the original error macro name.
282 std::string reason(rs);
283
284 for (auto& c : reason) {
285 if (c == ' ')
286 c = '_';
287 else
288 c = ToUpper(c);
289 }
290
291 #define OSSL_ERROR_CODES_MAP(V) \
292 V(SYS) \
293 V(BN) \
294 V(RSA) \
295 V(DH) \
296 V(EVP) \
297 V(BUF) \
298 V(OBJ) \
299 V(PEM) \
300 V(DSA) \
301 V(X509) \
302 V(ASN1) \
303 V(CONF) \
304 V(CRYPTO) \
305 V(EC) \
306 V(SSL) \
307 V(BIO) \
308 V(PKCS7) \
309 V(X509V3) \
310 V(PKCS12) \
311 V(RAND) \
312 V(DSO) \
313 V(ENGINE) \
314 V(OCSP) \
315 V(UI) \
316 V(COMP) \
317 V(ECDSA) \
318 V(ECDH) \
319 V(OSSL_STORE) \
320 V(FIPS) \
321 V(CMS) \
322 V(TS) \
323 V(HMAC) \
324 V(CT) \
325 V(ASYNC) \
326 V(KDF) \
327 V(SM2) \
328 V(USER) \
329
330 #define V(name) case ERR_LIB_##name: lib = #name "_"; break;
331 const char* lib = "";
332 const char* prefix = "OSSL_";
333 switch (ERR_GET_LIB(err)) { OSSL_ERROR_CODES_MAP(V) }
334 #undef V
335 #undef OSSL_ERROR_CODES_MAP
336 // Don't generate codes like "ERR_OSSL_SSL_".
337 if (lib && strcmp(lib, "SSL_") == 0)
338 prefix = "";
339
340 // All OpenSSL reason strings fit in a single 80-column macro definition,
341 // all prefix lengths are <= 10, and ERR_OSSL_ is 9, so 128 is more than
342 // sufficient.
343 char code[128];
344 snprintf(code, sizeof(code), "ERR_%s%s%s", prefix, lib, reason.c_str());
345
346 if (obj->Set(env->isolate()->GetCurrentContext(),
347 env->code_string(),
348 OneByteString(env->isolate(), code)).IsNothing())
349 return Nothing<bool>();
350 }
351
352 return Just(true);
353 }
354 } // namespace error
355
356
357 struct CryptoErrorVector : public std::vector<std::string> {
Capturenode::crypto::CryptoErrorVector358 inline void Capture() {
359 clear();
360 while (auto err = ERR_get_error()) {
361 char buf[256];
362 ERR_error_string_n(err, buf, sizeof(buf));
363 push_back(buf);
364 }
365 std::reverse(begin(), end());
366 }
367
ToExceptionnode::crypto::CryptoErrorVector368 inline MaybeLocal<Value> ToException(
369 Environment* env,
370 Local<String> exception_string = Local<String>()) const {
371 if (exception_string.IsEmpty()) {
372 CryptoErrorVector copy(*this);
373 if (copy.empty()) copy.push_back("no error"); // But possibly a bug...
374 // Use last element as the error message, everything else goes
375 // into the .opensslErrorStack property on the exception object.
376 auto exception_string =
377 String::NewFromUtf8(env->isolate(), copy.back().data(),
378 NewStringType::kNormal, copy.back().size())
379 .ToLocalChecked();
380 copy.pop_back();
381 return copy.ToException(env, exception_string);
382 }
383
384 Local<Value> exception_v = Exception::Error(exception_string);
385 CHECK(!exception_v.IsEmpty());
386
387 if (!empty()) {
388 CHECK(exception_v->IsObject());
389 Local<Object> exception = exception_v.As<Object>();
390 Maybe<bool> ok = exception->Set(env->context(),
391 env->openssl_error_stack(),
392 ToV8Value(env->context(), *this).ToLocalChecked());
393 if (ok.IsNothing())
394 return MaybeLocal<Value>();
395 }
396
397 return exception_v;
398 }
399 };
400
401
ThrowCryptoError(Environment * env,unsigned long err,const char * message)402 void ThrowCryptoError(Environment* env,
403 unsigned long err, // NOLINT(runtime/int)
404 // Default, only used if there is no SSL `err` which can
405 // be used to create a long-style message string.
406 const char* message) {
407 char message_buffer[128] = {0};
408 if (err != 0 || message == nullptr) {
409 ERR_error_string_n(err, message_buffer, sizeof(message_buffer));
410 message = message_buffer;
411 }
412 HandleScope scope(env->isolate());
413 Local<String> exception_string =
414 String::NewFromUtf8(env->isolate(), message).ToLocalChecked();
415 CryptoErrorVector errors;
416 errors.Capture();
417 Local<Value> exception;
418 if (!errors.ToException(env, exception_string).ToLocal(&exception))
419 return;
420 Local<Object> obj;
421 if (!exception->ToObject(env->context()).ToLocal(&obj))
422 return;
423 if (error::Decorate(env, obj, err).IsNothing())
424 return;
425 env->isolate()->ThrowException(exception);
426 }
427
428
429 // Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
430 // The entropy pool starts out empty and needs to fill up before the PRNG
431 // can be used securely. Once the pool is filled, it never dries up again;
432 // its contents is stirred and reused when necessary.
433 //
434 // OpenSSL normally fills the pool automatically but not when someone starts
435 // generating random numbers before the pool is full: in that case OpenSSL
436 // keeps lowering the entropy estimate to thwart attackers trying to guess
437 // the initial state of the PRNG.
438 //
439 // When that happens, we will have to wait until enough entropy is available.
440 // That should normally never take longer than a few milliseconds.
441 //
442 // OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
443 // block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
444 // block under normal circumstances.
445 //
446 // The only time when /dev/urandom may conceivably block is right after boot,
447 // when the whole system is still low on entropy. That's not something we can
448 // do anything about.
CheckEntropy()449 inline void CheckEntropy() {
450 for (;;) {
451 int status = RAND_status();
452 CHECK_GE(status, 0); // Cannot fail.
453 if (status != 0)
454 break;
455
456 // Give up, RAND_poll() not supported.
457 if (RAND_poll() == 0)
458 break;
459 }
460 }
461
462
EntropySource(unsigned char * buffer,size_t length)463 bool EntropySource(unsigned char* buffer, size_t length) {
464 // Ensure that OpenSSL's PRNG is properly seeded.
465 CheckEntropy();
466 // RAND_bytes() can return 0 to indicate that the entropy data is not truly
467 // random. That's okay, it's still better than V8's stock source of entropy,
468 // which is /dev/urandom on UNIX platforms and the current time on Windows.
469 return RAND_bytes(buffer, length) != -1;
470 }
471
Initialize(Environment * env,Local<Object> target)472 void SecureContext::Initialize(Environment* env, Local<Object> target) {
473 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
474 t->InstanceTemplate()->SetInternalFieldCount(
475 SecureContext::kInternalFieldCount);
476 t->Inherit(BaseObject::GetConstructorTemplate(env));
477 Local<String> secureContextString =
478 FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext");
479 t->SetClassName(secureContextString);
480
481 env->SetProtoMethod(t, "init", Init);
482 env->SetProtoMethod(t, "setKey", SetKey);
483 #ifndef OPENSSL_NO_ENGINE
484 env->SetProtoMethod(t, "setEngineKey", SetEngineKey);
485 #endif // !OPENSSL_NO_ENGINE
486 env->SetProtoMethod(t, "setCert", SetCert);
487 env->SetProtoMethod(t, "addCACert", AddCACert);
488 env->SetProtoMethod(t, "addCRL", AddCRL);
489 env->SetProtoMethod(t, "addRootCerts", AddRootCerts);
490 env->SetProtoMethod(t, "setCipherSuites", SetCipherSuites);
491 env->SetProtoMethod(t, "setCiphers", SetCiphers);
492 env->SetProtoMethod(t, "setSigalgs", SetSigalgs);
493 env->SetProtoMethod(t, "setECDHCurve", SetECDHCurve);
494 env->SetProtoMethod(t, "setDHParam", SetDHParam);
495 env->SetProtoMethod(t, "setMaxProto", SetMaxProto);
496 env->SetProtoMethod(t, "setMinProto", SetMinProto);
497 env->SetProtoMethod(t, "getMaxProto", GetMaxProto);
498 env->SetProtoMethod(t, "getMinProto", GetMinProto);
499 env->SetProtoMethod(t, "setOptions", SetOptions);
500 env->SetProtoMethod(t, "setSessionIdContext", SetSessionIdContext);
501 env->SetProtoMethod(t, "setSessionTimeout", SetSessionTimeout);
502 env->SetProtoMethod(t, "close", Close);
503 env->SetProtoMethod(t, "loadPKCS12", LoadPKCS12);
504 #ifndef OPENSSL_NO_ENGINE
505 env->SetProtoMethod(t, "setClientCertEngine", SetClientCertEngine);
506 #endif // !OPENSSL_NO_ENGINE
507 env->SetProtoMethodNoSideEffect(t, "getTicketKeys", GetTicketKeys);
508 env->SetProtoMethod(t, "setTicketKeys", SetTicketKeys);
509 env->SetProtoMethod(t, "setFreeListLength", SetFreeListLength);
510 env->SetProtoMethod(t, "enableTicketKeyCallback", EnableTicketKeyCallback);
511 env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate<true>);
512 env->SetProtoMethodNoSideEffect(t, "getIssuer", GetCertificate<false>);
513
514 #define SET_INTEGER_CONSTANTS(name, value) \
515 t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), name), \
516 Integer::NewFromUnsigned(env->isolate(), value));
517 SET_INTEGER_CONSTANTS("kTicketKeyReturnIndex", kTicketKeyReturnIndex);
518 SET_INTEGER_CONSTANTS("kTicketKeyHMACIndex", kTicketKeyHMACIndex);
519 SET_INTEGER_CONSTANTS("kTicketKeyAESIndex", kTicketKeyAESIndex);
520 SET_INTEGER_CONSTANTS("kTicketKeyNameIndex", kTicketKeyNameIndex);
521 SET_INTEGER_CONSTANTS("kTicketKeyIVIndex", kTicketKeyIVIndex);
522
523 #undef SET_INTEGER_CONSTANTS
524
525 Local<FunctionTemplate> ctx_getter_templ =
526 FunctionTemplate::New(env->isolate(),
527 CtxGetter,
528 Local<Value>(),
529 Signature::New(env->isolate(), t));
530
531
532 t->PrototypeTemplate()->SetAccessorProperty(
533 FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
534 ctx_getter_templ,
535 Local<FunctionTemplate>(),
536 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
537
538 target->Set(env->context(), secureContextString,
539 t->GetFunction(env->context()).ToLocalChecked()).Check();
540 env->set_secure_context_constructor_template(t);
541 }
542
SecureContext(Environment * env,Local<Object> wrap)543 SecureContext::SecureContext(Environment* env, Local<Object> wrap)
544 : BaseObject(env, wrap) {
545 MakeWeak();
546 env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
547 }
548
Reset()549 inline void SecureContext::Reset() {
550 if (ctx_ != nullptr) {
551 env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
552 }
553 ctx_.reset();
554 cert_.reset();
555 issuer_.reset();
556 }
557
~SecureContext()558 SecureContext::~SecureContext() {
559 Reset();
560 }
561
New(const FunctionCallbackInfo<Value> & args)562 void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
563 Environment* env = Environment::GetCurrent(args);
564 new SecureContext(env, args.This());
565 }
566
567 // A maxVersion of 0 means "any", but OpenSSL may support TLS versions that
568 // Node.js doesn't, so pin the max to what we do support.
569 const int MAX_SUPPORTED_VERSION = TLS1_3_VERSION;
570
Init(const FunctionCallbackInfo<Value> & args)571 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
572 SecureContext* sc;
573 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
574 Environment* env = sc->env();
575
576 CHECK_EQ(args.Length(), 3);
577 CHECK(args[1]->IsInt32());
578 CHECK(args[2]->IsInt32());
579
580 int min_version = args[1].As<Int32>()->Value();
581 int max_version = args[2].As<Int32>()->Value();
582 const SSL_METHOD* method = TLS_method();
583
584 if (max_version == 0)
585 max_version = MAX_SUPPORTED_VERSION;
586
587 if (args[0]->IsString()) {
588 const node::Utf8Value sslmethod(env->isolate(), args[0]);
589
590 // Note that SSLv2 and SSLv3 are disallowed but SSLv23_method and friends
591 // are still accepted. They are OpenSSL's way of saying that all known
592 // protocols below TLS 1.3 are supported unless explicitly disabled (which
593 // we do below for SSLv2 and SSLv3.)
594 if (sslmethod == "SSLv2_method" ||
595 sslmethod == "SSLv2_server_method" ||
596 sslmethod == "SSLv2_client_method") {
597 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv2 methods disabled");
598 return;
599 } else if (sslmethod == "SSLv3_method" ||
600 sslmethod == "SSLv3_server_method" ||
601 sslmethod == "SSLv3_client_method") {
602 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "SSLv3 methods disabled");
603 return;
604 } else if (sslmethod == "SSLv23_method") {
605 max_version = TLS1_2_VERSION;
606 } else if (sslmethod == "SSLv23_server_method") {
607 max_version = TLS1_2_VERSION;
608 method = TLS_server_method();
609 } else if (sslmethod == "SSLv23_client_method") {
610 max_version = TLS1_2_VERSION;
611 method = TLS_client_method();
612 } else if (sslmethod == "TLS_method") {
613 min_version = 0;
614 max_version = MAX_SUPPORTED_VERSION;
615 } else if (sslmethod == "TLS_server_method") {
616 min_version = 0;
617 max_version = MAX_SUPPORTED_VERSION;
618 method = TLS_server_method();
619 } else if (sslmethod == "TLS_client_method") {
620 min_version = 0;
621 max_version = MAX_SUPPORTED_VERSION;
622 method = TLS_client_method();
623 } else if (sslmethod == "TLSv1_method") {
624 min_version = TLS1_VERSION;
625 max_version = TLS1_VERSION;
626 } else if (sslmethod == "TLSv1_server_method") {
627 min_version = TLS1_VERSION;
628 max_version = TLS1_VERSION;
629 method = TLS_server_method();
630 } else if (sslmethod == "TLSv1_client_method") {
631 min_version = TLS1_VERSION;
632 max_version = TLS1_VERSION;
633 method = TLS_client_method();
634 } else if (sslmethod == "TLSv1_1_method") {
635 min_version = TLS1_1_VERSION;
636 max_version = TLS1_1_VERSION;
637 } else if (sslmethod == "TLSv1_1_server_method") {
638 min_version = TLS1_1_VERSION;
639 max_version = TLS1_1_VERSION;
640 method = TLS_server_method();
641 } else if (sslmethod == "TLSv1_1_client_method") {
642 min_version = TLS1_1_VERSION;
643 max_version = TLS1_1_VERSION;
644 method = TLS_client_method();
645 } else if (sslmethod == "TLSv1_2_method") {
646 min_version = TLS1_2_VERSION;
647 max_version = TLS1_2_VERSION;
648 } else if (sslmethod == "TLSv1_2_server_method") {
649 min_version = TLS1_2_VERSION;
650 max_version = TLS1_2_VERSION;
651 method = TLS_server_method();
652 } else if (sslmethod == "TLSv1_2_client_method") {
653 min_version = TLS1_2_VERSION;
654 max_version = TLS1_2_VERSION;
655 method = TLS_client_method();
656 } else {
657 const std::string msg("Unknown method: ");
658 THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, (msg + * sslmethod).c_str());
659 return;
660 }
661 }
662
663 sc->ctx_.reset(SSL_CTX_new(method));
664 SSL_CTX_set_app_data(sc->ctx_.get(), sc);
665
666 // Disable SSLv2 in the case when method == TLS_method() and the
667 // cipher list contains SSLv2 ciphers (not the default, should be rare.)
668 // The bundled OpenSSL doesn't have SSLv2 support but the system OpenSSL may.
669 // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.)
670 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2);
671 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3);
672
673 // Enable automatic cert chaining. This is enabled by default in OpenSSL, but
674 // disabled by default in BoringSSL. Enable it explicitly to make the
675 // behavior match when Node is built with BoringSSL.
676 SSL_CTX_clear_mode(sc->ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
677
678 // SSL session cache configuration
679 SSL_CTX_set_session_cache_mode(sc->ctx_.get(),
680 SSL_SESS_CACHE_CLIENT |
681 SSL_SESS_CACHE_SERVER |
682 SSL_SESS_CACHE_NO_INTERNAL |
683 SSL_SESS_CACHE_NO_AUTO_CLEAR);
684
685 SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
686 SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
687
688 // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
689 // exposed in the public API. To retain compatibility, install a callback
690 // which restores the old algorithm.
691 if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
692 RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
693 RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
694 return env->ThrowError("Error generating ticket keys");
695 }
696 SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
697 }
698
699
700 // Takes a string or buffer and loads it into a BIO.
701 // Caller responsible for BIO_free_all-ing the returned object.
LoadBIO(Environment * env,Local<Value> v)702 static BIOPointer LoadBIO(Environment* env, Local<Value> v) {
703 HandleScope scope(env->isolate());
704
705 if (v->IsString()) {
706 const node::Utf8Value s(env->isolate(), v);
707 return NodeBIO::NewFixed(*s, s.length());
708 }
709
710 if (v->IsArrayBufferView()) {
711 ArrayBufferViewContents<char> buf(v.As<ArrayBufferView>());
712 return NodeBIO::NewFixed(buf.data(), buf.length());
713 }
714
715 return nullptr;
716 }
717
718
SetKey(const FunctionCallbackInfo<Value> & args)719 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
720 Environment* env = Environment::GetCurrent(args);
721
722 SecureContext* sc;
723 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
724
725 unsigned int len = args.Length();
726 if (len < 1) {
727 return THROW_ERR_MISSING_ARGS(env, "Private key argument is mandatory");
728 }
729
730 if (len > 2) {
731 return env->ThrowError("Only private key and pass phrase are expected");
732 }
733
734 if (len == 2) {
735 if (args[1]->IsUndefined() || args[1]->IsNull())
736 len = 1;
737 else
738 THROW_AND_RETURN_IF_NOT_STRING(env, args[1], "Pass phrase");
739 }
740
741 BIOPointer bio(LoadBIO(env, args[0]));
742 if (!bio)
743 return;
744
745 node::Utf8Value passphrase(env->isolate(), args[1]);
746
747 EVPKeyPointer key(
748 PEM_read_bio_PrivateKey(bio.get(),
749 nullptr,
750 PasswordCallback,
751 *passphrase));
752
753 if (!key) {
754 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
755 return ThrowCryptoError(env, err, "PEM_read_bio_PrivateKey");
756 }
757
758 int rv = SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get());
759
760 if (!rv) {
761 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
762 return ThrowCryptoError(env, err, "SSL_CTX_use_PrivateKey");
763 }
764 }
765
SetSigalgs(const FunctionCallbackInfo<Value> & args)766 void SecureContext::SetSigalgs(const FunctionCallbackInfo<Value>& args) {
767 SecureContext* sc;
768 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
769 Environment* env = sc->env();
770 ClearErrorOnReturn clear_error_on_return;
771
772 CHECK_EQ(args.Length(), 1);
773 CHECK(args[0]->IsString());
774
775 const node::Utf8Value sigalgs(env->isolate(), args[0]);
776
777 int rv = SSL_CTX_set1_sigalgs_list(sc->ctx_.get(), *sigalgs);
778
779 if (rv == 0) {
780 return ThrowCryptoError(env, ERR_get_error());
781 }
782 }
783
784 #ifndef OPENSSL_NO_ENGINE
785 // Helpers for the smart pointer.
ENGINE_free_fn(ENGINE * engine)786 void ENGINE_free_fn(ENGINE* engine) { ENGINE_free(engine); }
787
ENGINE_finish_and_free_fn(ENGINE * engine)788 void ENGINE_finish_and_free_fn(ENGINE* engine) {
789 ENGINE_finish(engine);
790 ENGINE_free(engine);
791 }
792
SetEngineKey(const FunctionCallbackInfo<Value> & args)793 void SecureContext::SetEngineKey(const FunctionCallbackInfo<Value>& args) {
794 Environment* env = Environment::GetCurrent(args);
795
796 SecureContext* sc;
797 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
798
799 CHECK_EQ(args.Length(), 2);
800
801 char errmsg[1024];
802 const node::Utf8Value engine_id(env->isolate(), args[1]);
803 std::unique_ptr<ENGINE, std::function<void(ENGINE*)>> e =
804 { LoadEngineById(*engine_id, &errmsg),
805 ENGINE_free_fn };
806 if (e.get() == nullptr) {
807 return env->ThrowError(errmsg);
808 }
809
810 if (!ENGINE_init(e.get())) {
811 return env->ThrowError("ENGINE_init");
812 }
813
814 e.get_deleter() = ENGINE_finish_and_free_fn;
815
816 const node::Utf8Value key_name(env->isolate(), args[0]);
817 EVPKeyPointer key(ENGINE_load_private_key(e.get(), *key_name,
818 nullptr, nullptr));
819
820 if (!key) {
821 return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key");
822 }
823
824 int rv = SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get());
825
826 if (rv == 0) {
827 return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey");
828 }
829
830 sc->private_key_engine_ = std::move(e);
831 }
832 #endif // !OPENSSL_NO_ENGINE
833
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,X509Pointer && x,STACK_OF (X509)* extra_certs,X509Pointer * cert,X509Pointer * issuer_)834 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
835 X509Pointer&& x,
836 STACK_OF(X509)* extra_certs,
837 X509Pointer* cert,
838 X509Pointer* issuer_) {
839 CHECK(!*issuer_);
840 CHECK(!*cert);
841 X509* issuer = nullptr;
842
843 int ret = SSL_CTX_use_certificate(ctx, x.get());
844
845 if (ret) {
846 // If we could set up our certificate, now proceed to
847 // the CA certificates.
848 SSL_CTX_clear_extra_chain_certs(ctx);
849
850 for (int i = 0; i < sk_X509_num(extra_certs); i++) {
851 X509* ca = sk_X509_value(extra_certs, i);
852
853 // NOTE: Increments reference count on `ca`
854 if (!SSL_CTX_add1_chain_cert(ctx, ca)) {
855 ret = 0;
856 issuer = nullptr;
857 break;
858 }
859 // Note that we must not free r if it was successfully
860 // added to the chain (while we must free the main
861 // certificate, since its reference count is increased
862 // by SSL_CTX_use_certificate).
863
864 // Find issuer
865 if (issuer != nullptr || X509_check_issued(ca, x.get()) != X509_V_OK)
866 continue;
867
868 issuer = ca;
869 }
870 }
871
872 // Try getting issuer from a cert store
873 if (ret) {
874 if (issuer == nullptr) {
875 ret = SSL_CTX_get_issuer(ctx, x.get(), &issuer);
876 ret = ret < 0 ? 0 : 1;
877 // NOTE: get_cert_store doesn't increment reference count,
878 // no need to free `store`
879 } else {
880 // Increment issuer reference count
881 issuer = X509_dup(issuer);
882 if (issuer == nullptr) {
883 ret = 0;
884 }
885 }
886 }
887
888 issuer_->reset(issuer);
889
890 if (ret && x != nullptr) {
891 cert->reset(X509_dup(x.get()));
892 if (!*cert)
893 ret = 0;
894 }
895 return ret;
896 }
897
898
899 // Read a file that contains our certificate in "PEM" format,
900 // possibly followed by a sequence of CA certificates that should be
901 // sent to the peer in the Certificate message.
902 //
903 // Taken from OpenSSL - edited for style.
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,BIOPointer && in,X509Pointer * cert,X509Pointer * issuer)904 int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
905 BIOPointer&& in,
906 X509Pointer* cert,
907 X509Pointer* issuer) {
908 // Just to ensure that `ERR_peek_last_error` below will return only errors
909 // that we are interested in
910 ERR_clear_error();
911
912 X509Pointer x(
913 PEM_read_bio_X509_AUX(in.get(), nullptr, NoPasswordCallback, nullptr));
914
915 if (!x)
916 return 0;
917
918 unsigned long err = 0; // NOLINT(runtime/int)
919
920 StackOfX509 extra_certs(sk_X509_new_null());
921 if (!extra_certs)
922 return 0;
923
924 while (X509Pointer extra {PEM_read_bio_X509(in.get(),
925 nullptr,
926 NoPasswordCallback,
927 nullptr)}) {
928 if (sk_X509_push(extra_certs.get(), extra.get())) {
929 extra.release();
930 continue;
931 }
932
933 return 0;
934 }
935
936 // When the while loop ends, it's usually just EOF.
937 err = ERR_peek_last_error();
938 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
939 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
940 ERR_clear_error();
941 } else {
942 // some real error
943 return 0;
944 }
945
946 return SSL_CTX_use_certificate_chain(ctx,
947 std::move(x),
948 extra_certs.get(),
949 cert,
950 issuer);
951 }
952
953
SetCert(const FunctionCallbackInfo<Value> & args)954 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
955 Environment* env = Environment::GetCurrent(args);
956
957 SecureContext* sc;
958 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
959
960 if (args.Length() != 1) {
961 return THROW_ERR_MISSING_ARGS(env, "Certificate argument is mandatory");
962 }
963
964 BIOPointer bio(LoadBIO(env, args[0]));
965 if (!bio)
966 return;
967
968 sc->cert_.reset();
969 sc->issuer_.reset();
970
971 int rv = SSL_CTX_use_certificate_chain(sc->ctx_.get(),
972 std::move(bio),
973 &sc->cert_,
974 &sc->issuer_);
975
976 if (!rv) {
977 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
978 return ThrowCryptoError(env, err, "SSL_CTX_use_certificate_chain");
979 }
980 }
981
982
NewRootCertStore()983 static X509_STORE* NewRootCertStore() {
984 static std::vector<X509*> root_certs_vector;
985 static Mutex root_certs_vector_mutex;
986 Mutex::ScopedLock lock(root_certs_vector_mutex);
987
988 if (root_certs_vector.empty()) {
989 for (size_t i = 0; i < arraysize(root_certs); i++) {
990 X509* x509 =
991 PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
992 strlen(root_certs[i])).get(),
993 nullptr, // no re-use of X509 structure
994 NoPasswordCallback,
995 nullptr); // no callback data
996
997 // Parse errors from the built-in roots are fatal.
998 CHECK_NOT_NULL(x509);
999
1000 root_certs_vector.push_back(x509);
1001 }
1002 }
1003
1004 X509_STORE* store = X509_STORE_new();
1005 if (*system_cert_path != '\0') {
1006 X509_STORE_load_locations(store, system_cert_path, nullptr);
1007 }
1008
1009 Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
1010 if (per_process::cli_options->ssl_openssl_cert_store) {
1011 X509_STORE_set_default_paths(store);
1012 } else {
1013 for (X509* cert : root_certs_vector) {
1014 X509_up_ref(cert);
1015 X509_STORE_add_cert(store, cert);
1016 }
1017 }
1018
1019 return store;
1020 }
1021
1022
GetRootCertificates(const FunctionCallbackInfo<Value> & args)1023 void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
1024 Environment* env = Environment::GetCurrent(args);
1025 Local<Value> result[arraysize(root_certs)];
1026
1027 for (size_t i = 0; i < arraysize(root_certs); i++) {
1028 if (!String::NewFromOneByte(
1029 env->isolate(),
1030 reinterpret_cast<const uint8_t*>(root_certs[i]))
1031 .ToLocal(&result[i])) {
1032 return;
1033 }
1034 }
1035
1036 args.GetReturnValue().Set(
1037 Array::New(env->isolate(), result, arraysize(root_certs)));
1038 }
1039
1040
AddCACert(const FunctionCallbackInfo<Value> & args)1041 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
1042 Environment* env = Environment::GetCurrent(args);
1043
1044 SecureContext* sc;
1045 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1046 ClearErrorOnReturn clear_error_on_return;
1047
1048 if (args.Length() != 1) {
1049 return THROW_ERR_MISSING_ARGS(env, "CA certificate argument is mandatory");
1050 }
1051
1052 BIOPointer bio(LoadBIO(env, args[0]));
1053 if (!bio)
1054 return;
1055
1056 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1057 while (X509* x509 = PEM_read_bio_X509_AUX(
1058 bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1059 if (cert_store == root_cert_store) {
1060 cert_store = NewRootCertStore();
1061 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1062 }
1063 X509_STORE_add_cert(cert_store, x509);
1064 SSL_CTX_add_client_CA(sc->ctx_.get(), x509);
1065 X509_free(x509);
1066 }
1067 }
1068
1069
AddCRL(const FunctionCallbackInfo<Value> & args)1070 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
1071 Environment* env = Environment::GetCurrent(args);
1072
1073 SecureContext* sc;
1074 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1075
1076 if (args.Length() != 1) {
1077 return THROW_ERR_MISSING_ARGS(env, "CRL argument is mandatory");
1078 }
1079
1080 ClearErrorOnReturn clear_error_on_return;
1081
1082 BIOPointer bio(LoadBIO(env, args[0]));
1083 if (!bio)
1084 return;
1085
1086 DeleteFnPtr<X509_CRL, X509_CRL_free> crl(
1087 PEM_read_bio_X509_CRL(bio.get(), nullptr, NoPasswordCallback, nullptr));
1088
1089 if (!crl)
1090 return env->ThrowError("Failed to parse CRL");
1091
1092 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1093 if (cert_store == root_cert_store) {
1094 cert_store = NewRootCertStore();
1095 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1096 }
1097
1098 X509_STORE_add_crl(cert_store, crl.get());
1099 X509_STORE_set_flags(cert_store,
1100 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1101 }
1102
1103
AddCertsFromFile(X509_STORE * store,const char * file)1104 static unsigned long AddCertsFromFile( // NOLINT(runtime/int)
1105 X509_STORE* store,
1106 const char* file) {
1107 ERR_clear_error();
1108 MarkPopErrorOnReturn mark_pop_error_on_return;
1109
1110 BIOPointer bio(BIO_new_file(file, "r"));
1111 if (!bio)
1112 return ERR_get_error();
1113
1114 while (X509* x509 =
1115 PEM_read_bio_X509(bio.get(), nullptr, NoPasswordCallback, nullptr)) {
1116 X509_STORE_add_cert(store, x509);
1117 X509_free(x509);
1118 }
1119
1120 unsigned long err = ERR_peek_error(); // NOLINT(runtime/int)
1121 // Ignore error if its EOF/no start line found.
1122 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1123 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
1124 return 0;
1125 }
1126
1127 return err;
1128 }
1129
1130
UseExtraCaCerts(const std::string & file)1131 void UseExtraCaCerts(const std::string& file) {
1132 ClearErrorOnReturn clear_error_on_return;
1133
1134 if (root_cert_store == nullptr) {
1135 root_cert_store = NewRootCertStore();
1136
1137 if (!file.empty()) {
1138 unsigned long err = AddCertsFromFile( // NOLINT(runtime/int)
1139 root_cert_store,
1140 file.c_str());
1141 if (err) {
1142 fprintf(stderr,
1143 "Warning: Ignoring extra certs from `%s`, load failed: %s\n",
1144 file.c_str(),
1145 ERR_error_string(err, nullptr));
1146 } else {
1147 extra_root_certs_loaded = true;
1148 }
1149 }
1150 }
1151 }
1152
1153
IsExtraRootCertsFileLoaded(const FunctionCallbackInfo<Value> & args)1154 static void IsExtraRootCertsFileLoaded(
1155 const FunctionCallbackInfo<Value>& args) {
1156 return args.GetReturnValue().Set(extra_root_certs_loaded);
1157 }
1158
1159
AddRootCerts(const FunctionCallbackInfo<Value> & args)1160 void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
1161 SecureContext* sc;
1162 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1163 ClearErrorOnReturn clear_error_on_return;
1164
1165 if (root_cert_store == nullptr) {
1166 root_cert_store = NewRootCertStore();
1167 }
1168
1169 // Increment reference count so global store is not deleted along with CTX.
1170 X509_STORE_up_ref(root_cert_store);
1171 SSL_CTX_set_cert_store(sc->ctx_.get(), root_cert_store);
1172 }
1173
1174
SetCipherSuites(const FunctionCallbackInfo<Value> & args)1175 void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
1176 // BoringSSL doesn't allow API config of TLS1.3 cipher suites.
1177 #ifndef OPENSSL_IS_BORINGSSL
1178 SecureContext* sc;
1179 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1180 Environment* env = sc->env();
1181 ClearErrorOnReturn clear_error_on_return;
1182
1183 CHECK_EQ(args.Length(), 1);
1184 CHECK(args[0]->IsString());
1185
1186 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
1187 if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers)) {
1188 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1189 return ThrowCryptoError(env, err, "Failed to set ciphers");
1190 }
1191 #endif
1192 }
1193
1194
SetCiphers(const FunctionCallbackInfo<Value> & args)1195 void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
1196 SecureContext* sc;
1197 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1198 Environment* env = sc->env();
1199 ClearErrorOnReturn clear_error_on_return;
1200
1201 CHECK_EQ(args.Length(), 1);
1202 CHECK(args[0]->IsString());
1203
1204 const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
1205 if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
1206 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1207
1208 if (strlen(*ciphers) == 0 && ERR_GET_REASON(err) == SSL_R_NO_CIPHER_MATCH) {
1209 // TLS1.2 ciphers were deliberately cleared, so don't consider
1210 // SSL_R_NO_CIPHER_MATCH to be an error (this is how _set_cipher_suites()
1211 // works). If the user actually sets a value (like "no-such-cipher"), then
1212 // that's actually an error.
1213 return;
1214 }
1215 return ThrowCryptoError(env, err, "Failed to set ciphers");
1216 }
1217 }
1218
1219
SetECDHCurve(const FunctionCallbackInfo<Value> & args)1220 void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
1221 SecureContext* sc;
1222 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1223 Environment* env = sc->env();
1224
1225 if (args.Length() != 1)
1226 return THROW_ERR_MISSING_ARGS(env, "ECDH curve name argument is mandatory");
1227
1228 THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "ECDH curve name");
1229
1230 node::Utf8Value curve(env->isolate(), args[0]);
1231
1232 if (strcmp(*curve, "auto") == 0)
1233 return;
1234
1235 if (!SSL_CTX_set1_curves_list(sc->ctx_.get(), *curve))
1236 return env->ThrowError("Failed to set ECDH curve");
1237 }
1238
1239
SetDHParam(const FunctionCallbackInfo<Value> & args)1240 void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
1241 SecureContext* sc;
1242 ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
1243 Environment* env = sc->env();
1244 ClearErrorOnReturn clear_error_on_return;
1245
1246 // Auto DH is not supported in openssl 1.0.1, so dhparam needs
1247 // to be specified explicitly
1248 if (args.Length() != 1)
1249 return THROW_ERR_MISSING_ARGS(env, "DH argument is mandatory");
1250
1251 DHPointer dh;
1252 {
1253 BIOPointer bio(LoadBIO(env, args[0]));
1254 if (!bio)
1255 return;
1256
1257 dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
1258 }
1259
1260 // Invalid dhparam is silently discarded and DHE is no longer used.
1261 if (!dh)
1262 return;
1263
1264 const BIGNUM* p;
1265 DH_get0_pqg(dh.get(), &p, nullptr, nullptr);
1266 const int size = BN_num_bits(p);
1267 if (size < 1024) {
1268 return THROW_ERR_INVALID_ARG_VALUE(
1269 env, "DH parameter is less than 1024 bits");
1270 } else if (size < 2048) {
1271 args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(
1272 env->isolate(), "DH parameter is less than 2048 bits"));
1273 }
1274
1275 SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_DH_USE);
1276 int r = SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get());
1277
1278 if (!r)
1279 return env->ThrowTypeError("Error setting temp DH parameter");
1280 }
1281
1282
SetMinProto(const FunctionCallbackInfo<Value> & args)1283 void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
1284 SecureContext* sc;
1285 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1286
1287 CHECK_EQ(args.Length(), 1);
1288 CHECK(args[0]->IsInt32());
1289
1290 int version = args[0].As<Int32>()->Value();
1291
1292 CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
1293 }
1294
1295
SetMaxProto(const FunctionCallbackInfo<Value> & args)1296 void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
1297 SecureContext* sc;
1298 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1299
1300 CHECK_EQ(args.Length(), 1);
1301 CHECK(args[0]->IsInt32());
1302
1303 int version = args[0].As<Int32>()->Value();
1304
1305 CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
1306 }
1307
1308
GetMinProto(const FunctionCallbackInfo<Value> & args)1309 void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
1310 SecureContext* sc;
1311 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1312
1313 CHECK_EQ(args.Length(), 0);
1314
1315 long version = // NOLINT(runtime/int)
1316 SSL_CTX_get_min_proto_version(sc->ctx_.get());
1317 args.GetReturnValue().Set(static_cast<uint32_t>(version));
1318 }
1319
1320
GetMaxProto(const FunctionCallbackInfo<Value> & args)1321 void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
1322 SecureContext* sc;
1323 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1324
1325 CHECK_EQ(args.Length(), 0);
1326
1327 long version = // NOLINT(runtime/int)
1328 SSL_CTX_get_max_proto_version(sc->ctx_.get());
1329 args.GetReturnValue().Set(static_cast<uint32_t>(version));
1330 }
1331
1332
SetOptions(const FunctionCallbackInfo<Value> & args)1333 void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
1334 SecureContext* sc;
1335 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1336 int64_t val;
1337
1338 if (args.Length() != 1 ||
1339 !args[0]->IntegerValue(args.GetIsolate()->GetCurrentContext()).To(&val)) {
1340 return THROW_ERR_INVALID_ARG_TYPE(
1341 sc->env(), "Options must be an integer value");
1342 }
1343
1344 SSL_CTX_set_options(sc->ctx_.get(),
1345 static_cast<long>(val)); // NOLINT(runtime/int)
1346 }
1347
1348
SetSessionIdContext(const FunctionCallbackInfo<Value> & args)1349 void SecureContext::SetSessionIdContext(
1350 const FunctionCallbackInfo<Value>& args) {
1351 SecureContext* sc;
1352 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1353 Environment* env = sc->env();
1354
1355 if (args.Length() != 1) {
1356 return THROW_ERR_MISSING_ARGS(
1357 env, "Session ID context argument is mandatory");
1358 }
1359
1360 THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "Session ID context");
1361
1362 const node::Utf8Value sessionIdContext(args.GetIsolate(), args[0]);
1363 const unsigned char* sid_ctx =
1364 reinterpret_cast<const unsigned char*>(*sessionIdContext);
1365 unsigned int sid_ctx_len = sessionIdContext.length();
1366
1367 int r = SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len);
1368 if (r == 1)
1369 return;
1370
1371 BUF_MEM* mem;
1372 Local<String> message;
1373
1374 BIOPointer bio(BIO_new(BIO_s_mem()));
1375 if (!bio) {
1376 message = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
1377 "SSL_CTX_set_session_id_context error");
1378 } else {
1379 ERR_print_errors(bio.get());
1380 BIO_get_mem_ptr(bio.get(), &mem);
1381 message = OneByteString(args.GetIsolate(), mem->data, mem->length);
1382 }
1383
1384 args.GetIsolate()->ThrowException(Exception::TypeError(message));
1385 }
1386
1387
SetSessionTimeout(const FunctionCallbackInfo<Value> & args)1388 void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
1389 SecureContext* sc;
1390 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1391
1392 if (args.Length() != 1 || !args[0]->IsInt32()) {
1393 return THROW_ERR_INVALID_ARG_TYPE(
1394 sc->env(), "Session timeout must be a 32-bit integer");
1395 }
1396
1397 int32_t sessionTimeout = args[0].As<Int32>()->Value();
1398 SSL_CTX_set_timeout(sc->ctx_.get(), sessionTimeout);
1399 }
1400
1401
Close(const FunctionCallbackInfo<Value> & args)1402 void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
1403 SecureContext* sc;
1404 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1405 sc->Reset();
1406 }
1407
1408
1409 // Takes .pfx or .p12 and password in string or buffer format
LoadPKCS12(const FunctionCallbackInfo<Value> & args)1410 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
1411 Environment* env = Environment::GetCurrent(args);
1412
1413 std::vector<char> pass;
1414 bool ret = false;
1415
1416 SecureContext* sc;
1417 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1418 ClearErrorOnReturn clear_error_on_return;
1419
1420 if (args.Length() < 1) {
1421 return THROW_ERR_MISSING_ARGS(env, "PFX certificate argument is mandatory");
1422 }
1423
1424 BIOPointer in(LoadBIO(env, args[0]));
1425 if (!in)
1426 return env->ThrowError("Unable to load BIO");
1427
1428 if (args.Length() >= 2) {
1429 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[1], "Pass phrase");
1430 Local<ArrayBufferView> abv = args[1].As<ArrayBufferView>();
1431 size_t passlen = abv->ByteLength();
1432 pass.resize(passlen + 1);
1433 abv->CopyContents(pass.data(), passlen);
1434 pass[passlen] = '\0';
1435 }
1436
1437 // Free previous certs
1438 sc->issuer_.reset();
1439 sc->cert_.reset();
1440
1441 X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get());
1442
1443 DeleteFnPtr<PKCS12, PKCS12_free> p12;
1444 EVPKeyPointer pkey;
1445 X509Pointer cert;
1446 StackOfX509 extra_certs;
1447
1448 PKCS12* p12_ptr = nullptr;
1449 EVP_PKEY* pkey_ptr = nullptr;
1450 X509* cert_ptr = nullptr;
1451 STACK_OF(X509)* extra_certs_ptr = nullptr;
1452 if (d2i_PKCS12_bio(in.get(), &p12_ptr) &&
1453 (p12.reset(p12_ptr), true) && // Move ownership to the smart pointer.
1454 PKCS12_parse(p12.get(), pass.data(),
1455 &pkey_ptr,
1456 &cert_ptr,
1457 &extra_certs_ptr) &&
1458 (pkey.reset(pkey_ptr), cert.reset(cert_ptr),
1459 extra_certs.reset(extra_certs_ptr), true) && // Move ownership.
1460 SSL_CTX_use_certificate_chain(sc->ctx_.get(),
1461 std::move(cert),
1462 extra_certs.get(),
1463 &sc->cert_,
1464 &sc->issuer_) &&
1465 SSL_CTX_use_PrivateKey(sc->ctx_.get(), pkey.get())) {
1466 // Add CA certs too
1467 for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) {
1468 X509* ca = sk_X509_value(extra_certs.get(), i);
1469
1470 if (cert_store == root_cert_store) {
1471 cert_store = NewRootCertStore();
1472 SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store);
1473 }
1474 X509_STORE_add_cert(cert_store, ca);
1475 SSL_CTX_add_client_CA(sc->ctx_.get(), ca);
1476 }
1477 ret = true;
1478 }
1479
1480 if (!ret) {
1481 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
1482 const char* str = ERR_reason_error_string(err);
1483 return env->ThrowError(str);
1484 }
1485 }
1486
1487
1488 #ifndef OPENSSL_NO_ENGINE
SetClientCertEngine(const FunctionCallbackInfo<Value> & args)1489 void SecureContext::SetClientCertEngine(
1490 const FunctionCallbackInfo<Value>& args) {
1491 Environment* env = Environment::GetCurrent(args);
1492 CHECK_EQ(args.Length(), 1);
1493 CHECK(args[0]->IsString());
1494
1495 SecureContext* sc;
1496 ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
1497
1498 MarkPopErrorOnReturn mark_pop_error_on_return;
1499
1500 // SSL_CTX_set_client_cert_engine does not itself support multiple
1501 // calls by cleaning up before overwriting the client_cert_engine
1502 // internal context variable.
1503 // Instead of trying to fix up this problem we in turn also do not
1504 // support multiple calls to SetClientCertEngine.
1505 if (sc->client_cert_engine_provided_) {
1506 return env->ThrowError(
1507 "Multiple calls to SetClientCertEngine are not allowed");
1508 }
1509
1510 const node::Utf8Value engine_id(env->isolate(), args[0]);
1511 char errmsg[1024];
1512 DeleteFnPtr<ENGINE, ENGINE_free_fn> engine(
1513 LoadEngineById(*engine_id, &errmsg));
1514
1515 if (!engine)
1516 return env->ThrowError(errmsg);
1517
1518 // Note that this takes another reference to `engine`.
1519 int r = SSL_CTX_set_client_cert_engine(sc->ctx_.get(), engine.get());
1520 if (r == 0)
1521 return ThrowCryptoError(env, ERR_get_error());
1522 sc->client_cert_engine_provided_ = true;
1523 }
1524 #endif // !OPENSSL_NO_ENGINE
1525
1526
GetTicketKeys(const FunctionCallbackInfo<Value> & args)1527 void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1528 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1529
1530 SecureContext* wrap;
1531 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1532
1533 Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
1534 memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
1535 memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
1536 memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
1537
1538 args.GetReturnValue().Set(buff);
1539 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1540 }
1541
1542
SetTicketKeys(const FunctionCallbackInfo<Value> & args)1543 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
1544 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
1545 SecureContext* wrap;
1546 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1547 Environment* env = wrap->env();
1548
1549 // TODO(@sam-github) Move type and len check to js, and CHECK() in C++.
1550 if (args.Length() < 1) {
1551 return THROW_ERR_MISSING_ARGS(env, "Ticket keys argument is mandatory");
1552 }
1553
1554 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Ticket keys");
1555 ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
1556
1557 if (buf.length() != 48) {
1558 return THROW_ERR_INVALID_ARG_VALUE(
1559 env, "Ticket keys length must be 48 bytes");
1560 }
1561
1562 memcpy(wrap->ticket_key_name_, buf.data(), 16);
1563 memcpy(wrap->ticket_key_hmac_, buf.data() + 16, 16);
1564 memcpy(wrap->ticket_key_aes_, buf.data() + 32, 16);
1565
1566 args.GetReturnValue().Set(true);
1567 #endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
1568 }
1569
1570
SetFreeListLength(const FunctionCallbackInfo<Value> & args)1571 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
1572 }
1573
1574
1575 // Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
1576 // the regression test in test/parallel/test-https-resume-after-renew.js.
EnableTicketKeyCallback(const FunctionCallbackInfo<Value> & args)1577 void SecureContext::EnableTicketKeyCallback(
1578 const FunctionCallbackInfo<Value>& args) {
1579 SecureContext* wrap;
1580 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1581
1582 SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
1583 }
1584
1585
TicketKeyCallback(SSL * ssl,unsigned char * name,unsigned char * iv,EVP_CIPHER_CTX * ectx,HMAC_CTX * hctx,int enc)1586 int SecureContext::TicketKeyCallback(SSL* ssl,
1587 unsigned char* name,
1588 unsigned char* iv,
1589 EVP_CIPHER_CTX* ectx,
1590 HMAC_CTX* hctx,
1591 int enc) {
1592 static const int kTicketPartSize = 16;
1593
1594 SecureContext* sc = static_cast<SecureContext*>(
1595 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1596
1597 Environment* env = sc->env();
1598 HandleScope handle_scope(env->isolate());
1599 Context::Scope context_scope(env->context());
1600
1601 Local<Value> argv[] = {
1602 Buffer::Copy(env,
1603 reinterpret_cast<char*>(name),
1604 kTicketPartSize).ToLocalChecked(),
1605 Buffer::Copy(env,
1606 reinterpret_cast<char*>(iv),
1607 kTicketPartSize).ToLocalChecked(),
1608 Boolean::New(env->isolate(), enc != 0)
1609 };
1610
1611 Local<Value> ret = node::MakeCallback(env->isolate(),
1612 sc->object(),
1613 env->ticketkeycallback_string(),
1614 arraysize(argv),
1615 argv,
1616 {0, 0}).ToLocalChecked();
1617 Local<Array> arr = ret.As<Array>();
1618
1619 int r =
1620 arr->Get(env->context(),
1621 kTicketKeyReturnIndex).ToLocalChecked()
1622 ->Int32Value(env->context()).FromJust();
1623 if (r < 0)
1624 return r;
1625
1626 Local<Value> hmac = arr->Get(env->context(),
1627 kTicketKeyHMACIndex).ToLocalChecked();
1628 Local<Value> aes = arr->Get(env->context(),
1629 kTicketKeyAESIndex).ToLocalChecked();
1630 if (Buffer::Length(aes) != kTicketPartSize)
1631 return -1;
1632
1633 if (enc) {
1634 Local<Value> name_val = arr->Get(env->context(),
1635 kTicketKeyNameIndex).ToLocalChecked();
1636 Local<Value> iv_val = arr->Get(env->context(),
1637 kTicketKeyIVIndex).ToLocalChecked();
1638
1639 if (Buffer::Length(name_val) != kTicketPartSize ||
1640 Buffer::Length(iv_val) != kTicketPartSize) {
1641 return -1;
1642 }
1643
1644 name_val.As<ArrayBufferView>()->CopyContents(name, kTicketPartSize);
1645 iv_val.As<ArrayBufferView>()->CopyContents(iv, kTicketPartSize);
1646 }
1647
1648 ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1649 HMAC_Init_ex(hctx,
1650 hmac_buf.data(),
1651 hmac_buf.length(),
1652 EVP_sha256(),
1653 nullptr);
1654
1655 ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
1656 if (enc) {
1657 EVP_EncryptInit_ex(ectx,
1658 EVP_aes_128_cbc(),
1659 nullptr,
1660 aes_key.data(),
1661 iv);
1662 } else {
1663 EVP_DecryptInit_ex(ectx,
1664 EVP_aes_128_cbc(),
1665 nullptr,
1666 aes_key.data(),
1667 iv);
1668 }
1669
1670 return r;
1671 }
1672
1673
TicketCompatibilityCallback(SSL * ssl,unsigned char * name,unsigned char * iv,EVP_CIPHER_CTX * ectx,HMAC_CTX * hctx,int enc)1674 int SecureContext::TicketCompatibilityCallback(SSL* ssl,
1675 unsigned char* name,
1676 unsigned char* iv,
1677 EVP_CIPHER_CTX* ectx,
1678 HMAC_CTX* hctx,
1679 int enc) {
1680 SecureContext* sc = static_cast<SecureContext*>(
1681 SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
1682
1683 if (enc) {
1684 memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
1685 if (RAND_bytes(iv, 16) <= 0 ||
1686 EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
1687 sc->ticket_key_aes_, iv) <= 0 ||
1688 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1689 EVP_sha256(), nullptr) <= 0) {
1690 return -1;
1691 }
1692 return 1;
1693 }
1694
1695 if (memcmp(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) != 0) {
1696 // The ticket key name does not match. Discard the ticket.
1697 return 0;
1698 }
1699
1700 if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1701 iv) <= 0 ||
1702 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1703 EVP_sha256(), nullptr) <= 0) {
1704 return -1;
1705 }
1706 return 1;
1707 }
1708
1709
CtxGetter(const FunctionCallbackInfo<Value> & info)1710 void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1711 SecureContext* sc;
1712 ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1713 Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1714 info.GetReturnValue().Set(ext);
1715 }
1716
1717
1718 template <bool primary>
GetCertificate(const FunctionCallbackInfo<Value> & args)1719 void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
1720 SecureContext* wrap;
1721 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
1722 Environment* env = wrap->env();
1723 X509* cert;
1724
1725 if (primary)
1726 cert = wrap->cert_.get();
1727 else
1728 cert = wrap->issuer_.get();
1729 if (cert == nullptr)
1730 return args.GetReturnValue().SetNull();
1731
1732 int size = i2d_X509(cert, nullptr);
1733 Local<Object> buff = Buffer::New(env, size).ToLocalChecked();
1734 unsigned char* serialized = reinterpret_cast<unsigned char*>(
1735 Buffer::Data(buff));
1736 i2d_X509(cert, &serialized);
1737
1738 args.GetReturnValue().Set(buff);
1739 }
1740
1741
1742 template <class Base>
AddMethods(Environment * env,Local<FunctionTemplate> t)1743 void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
1744 HandleScope scope(env->isolate());
1745
1746 env->SetProtoMethodNoSideEffect(t, "getPeerCertificate", GetPeerCertificate);
1747 env->SetProtoMethodNoSideEffect(t, "getCertificate", GetCertificate);
1748 env->SetProtoMethodNoSideEffect(t, "getFinished", GetFinished);
1749 env->SetProtoMethodNoSideEffect(t, "getPeerFinished", GetPeerFinished);
1750 env->SetProtoMethodNoSideEffect(t, "getSession", GetSession);
1751 env->SetProtoMethod(t, "setSession", SetSession);
1752 env->SetProtoMethod(t, "loadSession", LoadSession);
1753 env->SetProtoMethodNoSideEffect(t, "isSessionReused", IsSessionReused);
1754 env->SetProtoMethodNoSideEffect(t, "verifyError", VerifyError);
1755 env->SetProtoMethodNoSideEffect(t, "getCipher", GetCipher);
1756 env->SetProtoMethodNoSideEffect(t, "getSharedSigalgs", GetSharedSigalgs);
1757 env->SetProtoMethodNoSideEffect(
1758 t, "exportKeyingMaterial", ExportKeyingMaterial);
1759 env->SetProtoMethod(t, "endParser", EndParser);
1760 env->SetProtoMethod(t, "certCbDone", CertCbDone);
1761 env->SetProtoMethod(t, "renegotiate", Renegotiate);
1762 env->SetProtoMethodNoSideEffect(t, "getTLSTicket", GetTLSTicket);
1763 env->SetProtoMethod(t, "newSessionDone", NewSessionDone);
1764 env->SetProtoMethod(t, "setOCSPResponse", SetOCSPResponse);
1765 env->SetProtoMethod(t, "requestOCSP", RequestOCSP);
1766 env->SetProtoMethodNoSideEffect(t, "getEphemeralKeyInfo",
1767 GetEphemeralKeyInfo);
1768 env->SetProtoMethodNoSideEffect(t, "getProtocol", GetProtocol);
1769
1770 env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment);
1771
1772 env->SetProtoMethodNoSideEffect(t, "getALPNNegotiatedProtocol",
1773 GetALPNNegotiatedProto);
1774 env->SetProtoMethod(t, "setALPNProtocols", SetALPNProtocols);
1775 }
1776
1777
1778 template <class Base>
ConfigureSecureContext(SecureContext * sc)1779 void SSLWrap<Base>::ConfigureSecureContext(SecureContext* sc) {
1780 // OCSP stapling
1781 SSL_CTX_set_tlsext_status_cb(sc->ctx_.get(), TLSExtStatusCallback);
1782 SSL_CTX_set_tlsext_status_arg(sc->ctx_.get(), nullptr);
1783 }
1784
1785
1786 template <class Base>
GetSessionCallback(SSL * s,const unsigned char * key,int len,int * copy)1787 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
1788 const unsigned char* key,
1789 int len,
1790 int* copy) {
1791 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1792
1793 *copy = 0;
1794 return w->next_sess_.release();
1795 }
1796
1797
1798 template <class Base>
NewSessionCallback(SSL * s,SSL_SESSION * sess)1799 int SSLWrap<Base>::NewSessionCallback(SSL* s, SSL_SESSION* sess) {
1800 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1801 Environment* env = w->ssl_env();
1802 HandleScope handle_scope(env->isolate());
1803 Context::Scope context_scope(env->context());
1804
1805 if (!w->session_callbacks_)
1806 return 0;
1807
1808 // Check if session is small enough to be stored
1809 int size = i2d_SSL_SESSION(sess, nullptr);
1810 if (size > SecureContext::kMaxSessionSize)
1811 return 0;
1812
1813 // Serialize session
1814 Local<Object> session = Buffer::New(env, size).ToLocalChecked();
1815 unsigned char* session_data = reinterpret_cast<unsigned char*>(
1816 Buffer::Data(session));
1817 memset(session_data, 0, size);
1818 i2d_SSL_SESSION(sess, &session_data);
1819
1820 unsigned int session_id_length;
1821 const unsigned char* session_id_data = SSL_SESSION_get_id(sess,
1822 &session_id_length);
1823 Local<Object> session_id = Buffer::Copy(
1824 env,
1825 reinterpret_cast<const char*>(session_id_data),
1826 session_id_length).ToLocalChecked();
1827 Local<Value> argv[] = { session_id, session };
1828 // On servers, we pause the handshake until callback of 'newSession', which
1829 // calls NewSessionDoneCb(). On clients, there is no callback to wait for.
1830 if (w->is_server())
1831 w->awaiting_new_session_ = true;
1832 w->MakeCallback(env->onnewsession_string(), arraysize(argv), argv);
1833
1834 return 0;
1835 }
1836
1837
1838 template <class Base>
KeylogCallback(const SSL * s,const char * line)1839 void SSLWrap<Base>::KeylogCallback(const SSL* s, const char* line) {
1840 Base* w = static_cast<Base*>(SSL_get_app_data(s));
1841 Environment* env = w->ssl_env();
1842 HandleScope handle_scope(env->isolate());
1843 Context::Scope context_scope(env->context());
1844
1845 const size_t size = strlen(line);
1846 Local<Value> line_bf = Buffer::Copy(env, line, 1 + size).ToLocalChecked();
1847 char* data = Buffer::Data(line_bf);
1848 data[size] = '\n';
1849 w->MakeCallback(env->onkeylog_string(), 1, &line_bf);
1850 }
1851
1852
1853 template <class Base>
OnClientHello(void * arg,const ClientHelloParser::ClientHello & hello)1854 void SSLWrap<Base>::OnClientHello(void* arg,
1855 const ClientHelloParser::ClientHello& hello) {
1856 Base* w = static_cast<Base*>(arg);
1857 Environment* env = w->ssl_env();
1858 HandleScope handle_scope(env->isolate());
1859 Local<Context> context = env->context();
1860 Context::Scope context_scope(context);
1861
1862 Local<Object> hello_obj = Object::New(env->isolate());
1863 Local<Object> buff = Buffer::Copy(
1864 env,
1865 reinterpret_cast<const char*>(hello.session_id()),
1866 hello.session_size()).ToLocalChecked();
1867 hello_obj->Set(context, env->session_id_string(), buff).Check();
1868 if (hello.servername() == nullptr) {
1869 hello_obj->Set(context,
1870 env->servername_string(),
1871 String::Empty(env->isolate())).Check();
1872 } else {
1873 Local<String> servername = OneByteString(env->isolate(),
1874 hello.servername(),
1875 hello.servername_size());
1876 hello_obj->Set(context, env->servername_string(), servername).Check();
1877 }
1878 hello_obj->Set(context,
1879 env->tls_ticket_string(),
1880 Boolean::New(env->isolate(), hello.has_ticket())).Check();
1881
1882 Local<Value> argv[] = { hello_obj };
1883 w->MakeCallback(env->onclienthello_string(), arraysize(argv), argv);
1884 }
1885
1886 template <class Base>
GetPeerCertificate(const FunctionCallbackInfo<Value> & args)1887 void SSLWrap<Base>::GetPeerCertificate(
1888 const FunctionCallbackInfo<Value>& args) {
1889 Base* w;
1890 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1891 Environment* env = w->ssl_env();
1892
1893 bool abbreviated = args.Length() < 1 || !args[0]->IsTrue();
1894
1895 Local<Value> ret;
1896 if (GetPeerCert(env, w->ssl_, abbreviated, w->is_server()).ToLocal(&ret))
1897 args.GetReturnValue().Set(ret);
1898 }
1899
1900
1901 template <class Base>
GetCertificate(const FunctionCallbackInfo<Value> & args)1902 void SSLWrap<Base>::GetCertificate(
1903 const FunctionCallbackInfo<Value>& args) {
1904 Base* w;
1905 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1906 Environment* env = w->ssl_env();
1907
1908 Local<Value> ret;
1909 if (GetCert(env, w->ssl_).ToLocal(&ret))
1910 args.GetReturnValue().Set(ret);
1911 }
1912
1913
1914 template <class Base>
GetFinished(const FunctionCallbackInfo<Value> & args)1915 void SSLWrap<Base>::GetFinished(const FunctionCallbackInfo<Value>& args) {
1916 Environment* env = Environment::GetCurrent(args);
1917
1918 Base* w;
1919 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1920
1921 // We cannot just pass nullptr to SSL_get_finished()
1922 // because it would further be propagated to memcpy(),
1923 // where the standard requirements as described in ISO/IEC 9899:2011
1924 // sections 7.21.2.1, 7.21.1.2, and 7.1.4, would be violated.
1925 // Thus, we use a dummy byte.
1926 char dummy[1];
1927 size_t len = SSL_get_finished(w->ssl_.get(), dummy, sizeof dummy);
1928 if (len == 0)
1929 return;
1930
1931 AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, len);
1932 CHECK_EQ(len, SSL_get_finished(w->ssl_.get(), buf.data(), len));
1933 args.GetReturnValue().Set(buf.ToBuffer().ToLocalChecked());
1934 }
1935
1936
1937 template <class Base>
GetPeerFinished(const FunctionCallbackInfo<Value> & args)1938 void SSLWrap<Base>::GetPeerFinished(const FunctionCallbackInfo<Value>& args) {
1939 Environment* env = Environment::GetCurrent(args);
1940
1941 Base* w;
1942 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1943
1944 // We cannot just pass nullptr to SSL_get_peer_finished()
1945 // because it would further be propagated to memcpy(),
1946 // where the standard requirements as described in ISO/IEC 9899:2011
1947 // sections 7.21.2.1, 7.21.1.2, and 7.1.4, would be violated.
1948 // Thus, we use a dummy byte.
1949 char dummy[1];
1950 size_t len = SSL_get_peer_finished(w->ssl_.get(), dummy, sizeof dummy);
1951 if (len == 0)
1952 return;
1953
1954 AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, len);
1955 CHECK_EQ(len, SSL_get_peer_finished(w->ssl_.get(), buf.data(), len));
1956 args.GetReturnValue().Set(buf.ToBuffer().ToLocalChecked());
1957 }
1958
1959
1960 template <class Base>
GetSession(const FunctionCallbackInfo<Value> & args)1961 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
1962 Environment* env = Environment::GetCurrent(args);
1963
1964 Base* w;
1965 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1966
1967 SSL_SESSION* sess = SSL_get_session(w->ssl_.get());
1968 if (sess == nullptr)
1969 return;
1970
1971 int slen = i2d_SSL_SESSION(sess, nullptr);
1972 if (slen <= 0)
1973 return; // Invalid or malformed session.
1974
1975 AllocatedBuffer sbuf = AllocatedBuffer::AllocateManaged(env, slen);
1976 unsigned char* p = reinterpret_cast<unsigned char*>(sbuf.data());
1977 CHECK_LT(0, i2d_SSL_SESSION(sess, &p));
1978 args.GetReturnValue().Set(sbuf.ToBuffer().ToLocalChecked());
1979 }
1980
1981
1982 template <class Base>
SetSession(const FunctionCallbackInfo<Value> & args)1983 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
1984 Environment* env = Environment::GetCurrent(args);
1985
1986 Base* w;
1987 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
1988
1989 if (args.Length() < 1)
1990 return THROW_ERR_MISSING_ARGS(env, "Session argument is mandatory");
1991
1992 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Session");
1993
1994 SSLSessionPointer sess = GetTLSSession(args[0]);
1995 if (sess == nullptr)
1996 return;
1997
1998 if (!SetTLSSession(w->ssl_, sess))
1999 return env->ThrowError("SSL_set_session error");
2000 }
2001
2002
2003 template <class Base>
LoadSession(const FunctionCallbackInfo<Value> & args)2004 void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
2005 Base* w;
2006 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2007
2008 // TODO(@sam-github) check arg length and types in js, and CHECK in c++
2009 if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
2010 ArrayBufferViewContents<unsigned char> sbuf(args[0]);
2011
2012 const unsigned char* p = sbuf.data();
2013 SSL_SESSION* sess = d2i_SSL_SESSION(nullptr, &p, sbuf.length());
2014
2015 // Setup next session and move hello to the BIO buffer
2016 w->next_sess_.reset(sess);
2017 }
2018 }
2019
2020
2021 template <class Base>
IsSessionReused(const FunctionCallbackInfo<Value> & args)2022 void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
2023 Base* w;
2024 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2025 bool yes = SSL_session_reused(w->ssl_.get());
2026 args.GetReturnValue().Set(yes);
2027 }
2028
2029
2030 template <class Base>
EndParser(const FunctionCallbackInfo<Value> & args)2031 void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
2032 Base* w;
2033 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2034 w->hello_parser_.End();
2035 }
2036
2037
2038 template <class Base>
Renegotiate(const FunctionCallbackInfo<Value> & args)2039 void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
2040 Base* w;
2041 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2042
2043 ClearErrorOnReturn clear_error_on_return;
2044
2045 if (SSL_renegotiate(w->ssl_.get()) != 1) {
2046 return ThrowCryptoError(w->ssl_env(), ERR_get_error());
2047 }
2048 }
2049
2050
2051 template <class Base>
GetTLSTicket(const FunctionCallbackInfo<Value> & args)2052 void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
2053 Base* w;
2054 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2055 Environment* env = w->ssl_env();
2056
2057 SSL_SESSION* sess = SSL_get_session(w->ssl_.get());
2058 if (sess == nullptr)
2059 return;
2060
2061 const unsigned char* ticket;
2062 size_t length;
2063 SSL_SESSION_get0_ticket(sess, &ticket, &length);
2064
2065 if (ticket == nullptr)
2066 return;
2067
2068 Local<Object> buff = Buffer::Copy(
2069 env, reinterpret_cast<const char*>(ticket), length).ToLocalChecked();
2070
2071 args.GetReturnValue().Set(buff);
2072 }
2073
2074
2075 template <class Base>
NewSessionDone(const FunctionCallbackInfo<Value> & args)2076 void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
2077 Base* w;
2078 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2079 w->awaiting_new_session_ = false;
2080 w->NewSessionDoneCb();
2081 }
2082
2083
2084 template <class Base>
SetOCSPResponse(const FunctionCallbackInfo<Value> & args)2085 void SSLWrap<Base>::SetOCSPResponse(const FunctionCallbackInfo<Value>& args) {
2086 Base* w;
2087 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2088 Environment* env = w->env();
2089
2090 if (args.Length() < 1)
2091 return THROW_ERR_MISSING_ARGS(env, "OCSP response argument is mandatory");
2092
2093 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "OCSP response");
2094
2095 w->ocsp_response_.Reset(args.GetIsolate(), args[0].As<ArrayBufferView>());
2096 }
2097
2098
2099 template <class Base>
RequestOCSP(const FunctionCallbackInfo<Value> & args)2100 void SSLWrap<Base>::RequestOCSP(const FunctionCallbackInfo<Value>& args) {
2101 Base* w;
2102 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2103
2104 SSL_set_tlsext_status_type(w->ssl_.get(), TLSEXT_STATUSTYPE_ocsp);
2105 }
2106
2107
2108 template <class Base>
GetEphemeralKeyInfo(const FunctionCallbackInfo<Value> & args)2109 void SSLWrap<Base>::GetEphemeralKeyInfo(
2110 const FunctionCallbackInfo<Value>& args) {
2111 Base* w;
2112 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2113 Environment* env = Environment::GetCurrent(args);
2114
2115 CHECK(w->ssl_);
2116
2117 // tmp key is available on only client
2118 if (w->is_server())
2119 return args.GetReturnValue().SetNull();
2120
2121 Local<Object> ret;
2122 if (GetEphemeralKey(env, w->ssl_).ToLocal(&ret))
2123 args.GetReturnValue().Set(ret);
2124
2125 // TODO(@sam-github) semver-major: else return ThrowCryptoError(env,
2126 // ERR_get_error())
2127 }
2128
2129 template <class Base>
SetMaxSendFragment(const FunctionCallbackInfo<Value> & args)2130 void SSLWrap<Base>::SetMaxSendFragment(
2131 const FunctionCallbackInfo<Value>& args) {
2132 CHECK(args.Length() >= 1 && args[0]->IsNumber());
2133
2134 Base* w;
2135 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2136
2137 int rv = SSL_set_max_send_fragment(
2138 w->ssl_.get(),
2139 args[0]->Int32Value(w->ssl_env()->context()).FromJust());
2140 args.GetReturnValue().Set(rv);
2141 }
2142
2143
2144 template <class Base>
VerifyError(const FunctionCallbackInfo<Value> & args)2145 void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
2146 Base* w;
2147 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2148
2149 // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
2150 // peer certificate is questionable but it's compatible with what was
2151 // here before.
2152 long x509_verify_error = // NOLINT(runtime/int)
2153 VerifyPeerCertificate(w->ssl_, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
2154
2155 if (x509_verify_error == X509_V_OK)
2156 return args.GetReturnValue().SetNull();
2157
2158 const char* reason = X509_verify_cert_error_string(x509_verify_error);
2159 const char* code = reason;
2160 code = X509ErrorCode(x509_verify_error);
2161
2162 Isolate* isolate = args.GetIsolate();
2163 Local<String> reason_string = OneByteString(isolate, reason);
2164 Local<Value> exception_value = Exception::Error(reason_string);
2165 Local<Object> exception_object =
2166 exception_value->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
2167 exception_object->Set(w->env()->context(), w->env()->code_string(),
2168 OneByteString(isolate, code)).Check();
2169 args.GetReturnValue().Set(exception_object);
2170 }
2171
2172
2173 template <class Base>
GetCipher(const FunctionCallbackInfo<Value> & args)2174 void SSLWrap<Base>::GetCipher(const FunctionCallbackInfo<Value>& args) {
2175 Base* w;
2176 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2177 Environment* env = w->ssl_env();
2178
2179 const SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_.get());
2180 if (c == nullptr)
2181 return;
2182
2183 Local<Object> ret;
2184 if (GetCipherInfo(env, w->ssl_).ToLocal(&ret))
2185 args.GetReturnValue().Set(ret);
2186 }
2187
2188
2189 template <class Base>
GetSharedSigalgs(const FunctionCallbackInfo<Value> & args)2190 void SSLWrap<Base>::GetSharedSigalgs(const FunctionCallbackInfo<Value>& args) {
2191 Base* w;
2192 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2193 Environment* env = w->ssl_env();
2194
2195 SSL* ssl = w->ssl_.get();
2196 int nsig = SSL_get_shared_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr,
2197 nullptr);
2198 MaybeStackBuffer<Local<Value>, 16> ret_arr(nsig);
2199
2200 for (int i = 0; i < nsig; i++) {
2201 int hash_nid;
2202 int sign_nid;
2203 std::string sig_with_md;
2204
2205 SSL_get_shared_sigalgs(ssl, i, &sign_nid, &hash_nid, nullptr, nullptr,
2206 nullptr);
2207
2208 switch (sign_nid) {
2209 case EVP_PKEY_RSA:
2210 sig_with_md = "RSA+";
2211 break;
2212
2213 case EVP_PKEY_RSA_PSS:
2214 sig_with_md = "RSA-PSS+";
2215 break;
2216
2217 case EVP_PKEY_DSA:
2218 sig_with_md = "DSA+";
2219 break;
2220
2221 case EVP_PKEY_EC:
2222 sig_with_md = "ECDSA+";
2223 break;
2224
2225 case NID_ED25519:
2226 sig_with_md = "Ed25519+";
2227 break;
2228
2229 case NID_ED448:
2230 sig_with_md = "Ed448+";
2231 break;
2232 #ifndef OPENSSL_NO_GOST
2233 case NID_id_GostR3410_2001:
2234 sig_with_md = "gost2001+";
2235 break;
2236
2237 case NID_id_GostR3410_2012_256:
2238 sig_with_md = "gost2012_256+";
2239 break;
2240
2241 case NID_id_GostR3410_2012_512:
2242 sig_with_md = "gost2012_512+";
2243 break;
2244 #endif // !OPENSSL_NO_GOST
2245 default:
2246 const char* sn = OBJ_nid2sn(sign_nid);
2247
2248 if (sn != nullptr) {
2249 sig_with_md = std::string(sn) + "+";
2250 } else {
2251 sig_with_md = "UNDEF+";
2252 }
2253 break;
2254 }
2255
2256 const char* sn_hash = OBJ_nid2sn(hash_nid);
2257 if (sn_hash != nullptr) {
2258 sig_with_md += std::string(sn_hash);
2259 } else {
2260 sig_with_md += "UNDEF";
2261 }
2262 ret_arr[i] = OneByteString(env->isolate(), sig_with_md.c_str());
2263 }
2264
2265 args.GetReturnValue().Set(
2266 Array::New(env->isolate(), ret_arr.out(), ret_arr.length()));
2267 }
2268
2269 template <class Base>
ExportKeyingMaterial(const FunctionCallbackInfo<Value> & args)2270 void SSLWrap<Base>::ExportKeyingMaterial(
2271 const FunctionCallbackInfo<Value>& args) {
2272 CHECK(args[0]->IsInt32());
2273 CHECK(args[1]->IsString());
2274
2275 Base* w;
2276 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2277 Environment* env = w->ssl_env();
2278
2279 uint32_t olen = args[0].As<Uint32>()->Value();
2280 node::Utf8Value label(env->isolate(), args[1]);
2281
2282 AllocatedBuffer out = AllocatedBuffer::AllocateManaged(env, olen);
2283
2284 ByteSource context;
2285 bool use_context = !args[2]->IsUndefined();
2286 if (use_context)
2287 context = ByteSource::FromBuffer(args[2]);
2288
2289 if (SSL_export_keying_material(w->ssl_.get(),
2290 reinterpret_cast<unsigned char*>(out.data()),
2291 olen,
2292 *label,
2293 label.length(),
2294 reinterpret_cast<const unsigned char*>(
2295 context.get()),
2296 context.size(),
2297 use_context) != 1) {
2298 return ThrowCryptoError(env, ERR_get_error(), "SSL_export_keying_material");
2299 }
2300
2301 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
2302 }
2303
2304 template <class Base>
GetProtocol(const FunctionCallbackInfo<Value> & args)2305 void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) {
2306 Base* w;
2307 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2308
2309 const char* tls_version = SSL_get_version(w->ssl_.get());
2310 args.GetReturnValue().Set(OneByteString(args.GetIsolate(), tls_version));
2311 }
2312
2313
2314 template <class Base>
SelectALPNCallback(SSL * s,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)2315 int SSLWrap<Base>::SelectALPNCallback(SSL* s,
2316 const unsigned char** out,
2317 unsigned char* outlen,
2318 const unsigned char* in,
2319 unsigned int inlen,
2320 void* arg) {
2321 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2322 Environment* env = w->env();
2323 HandleScope handle_scope(env->isolate());
2324 Context::Scope context_scope(env->context());
2325
2326 Local<Value> alpn_buffer =
2327 w->object()->GetPrivate(
2328 env->context(),
2329 env->alpn_buffer_private_symbol()).ToLocalChecked();
2330 ArrayBufferViewContents<unsigned char> alpn_protos(alpn_buffer);
2331 int status = SSL_select_next_proto(const_cast<unsigned char**>(out), outlen,
2332 alpn_protos.data(), alpn_protos.length(),
2333 in, inlen);
2334 // According to 3.2. Protocol Selection of RFC7301, fatal
2335 // no_application_protocol alert shall be sent but OpenSSL 1.0.2 does not
2336 // support it yet. See
2337 // https://rt.openssl.org/Ticket/Display.html?id=3463&user=guest&pass=guest
2338 return status == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK
2339 : SSL_TLSEXT_ERR_NOACK;
2340 }
2341
2342
2343 template <class Base>
GetALPNNegotiatedProto(const FunctionCallbackInfo<Value> & args)2344 void SSLWrap<Base>::GetALPNNegotiatedProto(
2345 const FunctionCallbackInfo<Value>& args) {
2346 Base* w;
2347 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2348
2349 const unsigned char* alpn_proto;
2350 unsigned int alpn_proto_len;
2351
2352 SSL_get0_alpn_selected(w->ssl_.get(), &alpn_proto, &alpn_proto_len);
2353
2354 Local<Value> result;
2355 if (alpn_proto_len == 0) {
2356 result = False(args.GetIsolate());
2357 } else if (alpn_proto_len == sizeof("h2") - 1 &&
2358 0 == memcmp(alpn_proto, "h2", sizeof("h2") - 1)) {
2359 result = w->env()->h2_string();
2360 } else if (alpn_proto_len == sizeof("http/1.1") - 1 &&
2361 0 == memcmp(alpn_proto, "http/1.1", sizeof("http/1.1") - 1)) {
2362 result = w->env()->http_1_1_string();
2363 } else {
2364 result = OneByteString(args.GetIsolate(), alpn_proto, alpn_proto_len);
2365 }
2366
2367 args.GetReturnValue().Set(result);
2368 }
2369
2370
2371 template <class Base>
SetALPNProtocols(const FunctionCallbackInfo<Value> & args)2372 void SSLWrap<Base>::SetALPNProtocols(const FunctionCallbackInfo<Value>& args) {
2373 Base* w;
2374 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2375 Environment* env = w->env();
2376 if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
2377 return env->ThrowTypeError("Must give a Buffer as first argument");
2378
2379 if (w->is_client()) {
2380 CHECK(SetALPN(w->ssl_, args[0]));
2381 } else {
2382 CHECK(
2383 w->object()->SetPrivate(
2384 env->context(),
2385 env->alpn_buffer_private_symbol(),
2386 args[0]).FromJust());
2387 // Server should select ALPN protocol from list of advertised by client
2388 SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(w->ssl_.get()),
2389 SelectALPNCallback,
2390 nullptr);
2391 }
2392 }
2393
2394
2395 template <class Base>
TLSExtStatusCallback(SSL * s,void * arg)2396 int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
2397 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2398 Environment* env = w->env();
2399 HandleScope handle_scope(env->isolate());
2400
2401 if (w->is_client()) {
2402 // Incoming response
2403 Local<Value> arg;
2404 MaybeLocal<Value> ret = GetSSLOCSPResponse(env, s, Null(env->isolate()));
2405 if (ret.ToLocal(&arg))
2406 w->MakeCallback(env->onocspresponse_string(), 1, &arg);
2407
2408 // No async acceptance is possible, so always return 1 to accept the
2409 // response. The listener for 'OCSPResponse' event has no control over
2410 // return value, but it can .destroy() the connection if the response is not
2411 // acceptable.
2412 return 1;
2413 } else {
2414 // Outgoing response
2415 if (w->ocsp_response_.IsEmpty())
2416 return SSL_TLSEXT_ERR_NOACK;
2417
2418 Local<ArrayBufferView> obj = PersistentToLocal::Default(env->isolate(),
2419 w->ocsp_response_);
2420 size_t len = obj->ByteLength();
2421
2422 // OpenSSL takes control of the pointer after accepting it
2423 unsigned char* data = MallocOpenSSL<unsigned char>(len);
2424 obj->CopyContents(data, len);
2425
2426 if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
2427 OPENSSL_free(data);
2428 w->ocsp_response_.Reset();
2429
2430 return SSL_TLSEXT_ERR_OK;
2431 }
2432 }
2433
2434
2435 template <class Base>
WaitForCertCb(CertCb cb,void * arg)2436 void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
2437 cert_cb_ = cb;
2438 cert_cb_arg_ = arg;
2439 }
2440
2441
2442 template <class Base>
SSLCertCallback(SSL * s,void * arg)2443 int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
2444 Base* w = static_cast<Base*>(SSL_get_app_data(s));
2445
2446 if (!w->is_server())
2447 return 1;
2448
2449 if (!w->is_waiting_cert_cb())
2450 return 1;
2451
2452 if (w->cert_cb_running_)
2453 // Not an error. Suspend handshake with SSL_ERROR_WANT_X509_LOOKUP, and
2454 // handshake will continue after certcb is done.
2455 return -1;
2456
2457 Environment* env = w->env();
2458 Local<Context> context = env->context();
2459 HandleScope handle_scope(env->isolate());
2460 Context::Scope context_scope(context);
2461 w->cert_cb_running_ = true;
2462
2463 Local<Object> info = Object::New(env->isolate());
2464
2465 const char* servername = GetServerName(s);
2466 if (servername == nullptr) {
2467 info->Set(context,
2468 env->servername_string(),
2469 String::Empty(env->isolate())).Check();
2470 } else {
2471 Local<String> str = OneByteString(env->isolate(), servername,
2472 strlen(servername));
2473 info->Set(context, env->servername_string(), str).Check();
2474 }
2475
2476 const bool ocsp = (SSL_get_tlsext_status_type(s) == TLSEXT_STATUSTYPE_ocsp);
2477 info->Set(context, env->ocsp_request_string(),
2478 Boolean::New(env->isolate(), ocsp)).Check();
2479
2480 Local<Value> argv[] = { info };
2481 w->MakeCallback(env->oncertcb_string(), arraysize(argv), argv);
2482
2483 if (!w->cert_cb_running_)
2484 return 1;
2485
2486 // Performing async action, wait...
2487 return -1;
2488 }
2489
2490
2491 template <class Base>
CertCbDone(const FunctionCallbackInfo<Value> & args)2492 void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
2493 Base* w;
2494 ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
2495 Environment* env = w->env();
2496
2497 CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
2498
2499 Local<Object> object = w->object();
2500 Local<Value> ctx = object->Get(env->context(),
2501 env->sni_context_string()).ToLocalChecked();
2502 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
2503
2504 if (cons->HasInstance(ctx)) {
2505 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
2506 CHECK_NOT_NULL(sc);
2507 // Store the SNI context for later use.
2508 w->sni_context_ = BaseObjectPtr<SecureContext>(sc);
2509
2510 if (UseSNIContext(w->ssl_, w->sni_context_) && !w->SetCACerts(sc)) {
2511 // Not clear why sometimes we throw error, and sometimes we call
2512 // onerror(). Both cause .destroy(), but onerror does a bit more.
2513 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
2514 return ThrowCryptoError(env, err, "CertCbDone");
2515 }
2516 } else if (ctx->IsObject()) {
2517 // Failure: incorrect SNI context object
2518 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
2519 w->MakeCallback(env->onerror_string(), 1, &err);
2520 return;
2521 }
2522
2523 CertCb cb;
2524 void* arg;
2525
2526 cb = w->cert_cb_;
2527 arg = w->cert_cb_arg_;
2528
2529 w->cert_cb_running_ = false;
2530 w->cert_cb_ = nullptr;
2531 w->cert_cb_arg_ = nullptr;
2532
2533 cb(arg);
2534 }
2535
2536
2537 template <class Base>
DestroySSL()2538 void SSLWrap<Base>::DestroySSL() {
2539 if (!ssl_)
2540 return;
2541
2542 env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
2543 ssl_.reset();
2544 }
2545
2546
2547 template <class Base>
SetCACerts(SecureContext * sc)2548 int SSLWrap<Base>::SetCACerts(SecureContext* sc) {
2549 int err = SSL_set1_verify_cert_store(ssl_.get(),
2550 SSL_CTX_get_cert_store(sc->ctx_.get()));
2551 if (err != 1)
2552 return err;
2553
2554 STACK_OF(X509_NAME)* list = SSL_dup_CA_list(
2555 SSL_CTX_get_client_CA_list(sc->ctx_.get()));
2556
2557 // NOTE: `SSL_set_client_CA_list` takes the ownership of `list`
2558 SSL_set_client_CA_list(ssl_.get(), list);
2559 return 1;
2560 }
2561
2562 template <class Base>
MemoryInfo(MemoryTracker * tracker) const2563 void SSLWrap<Base>::MemoryInfo(MemoryTracker* tracker) const {
2564 tracker->TrackField("ocsp_response", ocsp_response_);
2565 tracker->TrackField("sni_context", sni_context_);
2566 }
2567
VerifyCallback(int preverify_ok,X509_STORE_CTX * ctx)2568 int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
2569 // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb:
2570 //
2571 // If VerifyCallback returns 1, the verification process is continued. If
2572 // VerifyCallback always returns 1, the TLS/SSL handshake will not be
2573 // terminated with respect to verification failures and the connection will
2574 // be established. The calling process can however retrieve the error code
2575 // of the last verification error using SSL_get_verify_result(3) or by
2576 // maintaining its own error storage managed by VerifyCallback.
2577 //
2578 // Since we cannot perform I/O quickly enough with X509_STORE_CTX_ APIs in
2579 // this callback, we ignore all preverify_ok errors and let the handshake
2580 // continue. It is imperative that the user use Connection::VerifyError after
2581 // the 'secure' callback has been made.
2582 return 1;
2583 }
2584
IsSupportedAuthenticatedMode(const EVP_CIPHER * cipher)2585 static bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
2586 const int mode = EVP_CIPHER_mode(cipher);
2587 // Check `chacha20-poly1305` separately, it is also an AEAD cipher,
2588 // but its mode is 0 which doesn't indicate
2589 return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305 ||
2590 mode == EVP_CIPH_CCM_MODE ||
2591 mode == EVP_CIPH_GCM_MODE ||
2592 IS_OCB_MODE(mode);
2593 }
2594
IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX * ctx)2595 static bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
2596 const EVP_CIPHER* cipher = EVP_CIPHER_CTX_cipher(ctx);
2597 return IsSupportedAuthenticatedMode(cipher);
2598 }
2599
2600 enum class ParseKeyResult {
2601 kParseKeyOk,
2602 kParseKeyNotRecognized,
2603 kParseKeyNeedPassphrase,
2604 kParseKeyFailed
2605 };
2606
TryParsePublicKey(EVPKeyPointer * pkey,const BIOPointer & bp,const char * name,const std::function<EVP_PKEY * (const unsigned char ** p,long l)> & parse)2607 static ParseKeyResult TryParsePublicKey(
2608 EVPKeyPointer* pkey,
2609 const BIOPointer& bp,
2610 const char* name,
2611 // NOLINTNEXTLINE(runtime/int)
2612 const std::function<EVP_PKEY*(const unsigned char** p, long l)>& parse) {
2613 unsigned char* der_data;
2614 long der_len; // NOLINT(runtime/int)
2615
2616 // This skips surrounding data and decodes PEM to DER.
2617 {
2618 MarkPopErrorOnReturn mark_pop_error_on_return;
2619 if (PEM_bytes_read_bio(&der_data, &der_len, nullptr, name,
2620 bp.get(), nullptr, nullptr) != 1)
2621 return ParseKeyResult::kParseKeyNotRecognized;
2622 }
2623
2624 // OpenSSL might modify the pointer, so we need to make a copy before parsing.
2625 const unsigned char* p = der_data;
2626 pkey->reset(parse(&p, der_len));
2627 OPENSSL_clear_free(der_data, der_len);
2628
2629 return *pkey ? ParseKeyResult::kParseKeyOk :
2630 ParseKeyResult::kParseKeyFailed;
2631 }
2632
ParsePublicKeyPEM(EVPKeyPointer * pkey,const char * key_pem,int key_pem_len)2633 static ParseKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
2634 const char* key_pem,
2635 int key_pem_len) {
2636 BIOPointer bp(BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len));
2637 if (!bp)
2638 return ParseKeyResult::kParseKeyFailed;
2639
2640 ParseKeyResult ret;
2641
2642 // Try parsing as a SubjectPublicKeyInfo first.
2643 ret = TryParsePublicKey(pkey, bp, "PUBLIC KEY",
2644 [](const unsigned char** p, long l) { // NOLINT(runtime/int)
2645 return d2i_PUBKEY(nullptr, p, l);
2646 });
2647 if (ret != ParseKeyResult::kParseKeyNotRecognized)
2648 return ret;
2649
2650 // Maybe it is PKCS#1.
2651 CHECK(BIO_reset(bp.get()));
2652 ret = TryParsePublicKey(pkey, bp, "RSA PUBLIC KEY",
2653 [](const unsigned char** p, long l) { // NOLINT(runtime/int)
2654 return d2i_PublicKey(EVP_PKEY_RSA, nullptr, p, l);
2655 });
2656 if (ret != ParseKeyResult::kParseKeyNotRecognized)
2657 return ret;
2658
2659 // X.509 fallback.
2660 CHECK(BIO_reset(bp.get()));
2661 return TryParsePublicKey(pkey, bp, "CERTIFICATE",
2662 [](const unsigned char** p, long l) { // NOLINT(runtime/int)
2663 X509Pointer x509(d2i_X509(nullptr, p, l));
2664 return x509 ? X509_get_pubkey(x509.get()) : nullptr;
2665 });
2666 }
2667
ParsePublicKey(EVPKeyPointer * pkey,const PublicKeyEncodingConfig & config,const char * key,size_t key_len)2668 static ParseKeyResult ParsePublicKey(EVPKeyPointer* pkey,
2669 const PublicKeyEncodingConfig& config,
2670 const char* key,
2671 size_t key_len) {
2672 if (config.format_ == kKeyFormatPEM) {
2673 return ParsePublicKeyPEM(pkey, key, key_len);
2674 } else {
2675 CHECK_EQ(config.format_, kKeyFormatDER);
2676
2677 const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
2678 if (config.type_.ToChecked() == kKeyEncodingPKCS1) {
2679 pkey->reset(d2i_PublicKey(EVP_PKEY_RSA, nullptr, &p, key_len));
2680 } else {
2681 CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSPKI);
2682 pkey->reset(d2i_PUBKEY(nullptr, &p, key_len));
2683 }
2684
2685 return *pkey ? ParseKeyResult::kParseKeyOk :
2686 ParseKeyResult::kParseKeyFailed;
2687 }
2688 }
2689
BIOToStringOrBuffer(Environment * env,BIO * bio,PKFormatType format)2690 static inline Local<Value> BIOToStringOrBuffer(Environment* env,
2691 BIO* bio,
2692 PKFormatType format) {
2693 BUF_MEM* bptr;
2694 BIO_get_mem_ptr(bio, &bptr);
2695 if (format == kKeyFormatPEM) {
2696 // PEM is an ASCII format, so we will return it as a string.
2697 return String::NewFromUtf8(env->isolate(), bptr->data,
2698 NewStringType::kNormal,
2699 bptr->length).ToLocalChecked();
2700 } else {
2701 CHECK_EQ(format, kKeyFormatDER);
2702 // DER is binary, return it as a buffer.
2703 return Buffer::Copy(env, bptr->data, bptr->length).ToLocalChecked();
2704 }
2705 }
2706
WritePublicKeyInner(EVP_PKEY * pkey,const BIOPointer & bio,const PublicKeyEncodingConfig & config)2707 static bool WritePublicKeyInner(EVP_PKEY* pkey,
2708 const BIOPointer& bio,
2709 const PublicKeyEncodingConfig& config) {
2710 if (config.type_.ToChecked() == kKeyEncodingPKCS1) {
2711 // PKCS#1 is only valid for RSA keys.
2712 CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
2713 RSAPointer rsa(EVP_PKEY_get1_RSA(pkey));
2714 if (config.format_ == kKeyFormatPEM) {
2715 // Encode PKCS#1 as PEM.
2716 return PEM_write_bio_RSAPublicKey(bio.get(), rsa.get()) == 1;
2717 } else {
2718 // Encode PKCS#1 as DER.
2719 CHECK_EQ(config.format_, kKeyFormatDER);
2720 return i2d_RSAPublicKey_bio(bio.get(), rsa.get()) == 1;
2721 }
2722 } else {
2723 CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSPKI);
2724 if (config.format_ == kKeyFormatPEM) {
2725 // Encode SPKI as PEM.
2726 return PEM_write_bio_PUBKEY(bio.get(), pkey) == 1;
2727 } else {
2728 // Encode SPKI as DER.
2729 CHECK_EQ(config.format_, kKeyFormatDER);
2730 return i2d_PUBKEY_bio(bio.get(), pkey) == 1;
2731 }
2732 }
2733 }
2734
WritePublicKey(Environment * env,EVP_PKEY * pkey,const PublicKeyEncodingConfig & config)2735 static MaybeLocal<Value> WritePublicKey(Environment* env,
2736 EVP_PKEY* pkey,
2737 const PublicKeyEncodingConfig& config) {
2738 BIOPointer bio(BIO_new(BIO_s_mem()));
2739 CHECK(bio);
2740
2741 if (!WritePublicKeyInner(pkey, bio, config)) {
2742 ThrowCryptoError(env, ERR_get_error(), "Failed to encode public key");
2743 return MaybeLocal<Value>();
2744 }
2745 return BIOToStringOrBuffer(env, bio.get(), config.format_);
2746 }
2747
IsASN1Sequence(const unsigned char * data,size_t size,size_t * data_offset,size_t * data_size)2748 static bool IsASN1Sequence(const unsigned char* data, size_t size,
2749 size_t* data_offset, size_t* data_size) {
2750 if (size < 2 || data[0] != 0x30)
2751 return false;
2752
2753 if (data[1] & 0x80) {
2754 // Long form.
2755 size_t n_bytes = data[1] & ~0x80;
2756 if (n_bytes + 2 > size || n_bytes > sizeof(size_t))
2757 return false;
2758 size_t length = 0;
2759 for (size_t i = 0; i < n_bytes; i++)
2760 length = (length << 8) | data[i + 2];
2761 *data_offset = 2 + n_bytes;
2762 *data_size = std::min(size - 2 - n_bytes, length);
2763 } else {
2764 // Short form.
2765 *data_offset = 2;
2766 *data_size = std::min<size_t>(size - 2, data[1]);
2767 }
2768
2769 return true;
2770 }
2771
IsRSAPrivateKey(const unsigned char * data,size_t size)2772 static bool IsRSAPrivateKey(const unsigned char* data, size_t size) {
2773 // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
2774 size_t offset, len;
2775 if (!IsASN1Sequence(data, size, &offset, &len))
2776 return false;
2777
2778 // An RSAPrivateKey sequence always starts with a single-byte integer whose
2779 // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
2780 // (which is the product of two primes and therefore at least 4), so we can
2781 // decide the type of the structure based on the first three bytes of the
2782 // sequence.
2783 return len >= 3 &&
2784 data[offset] == 2 &&
2785 data[offset + 1] == 1 &&
2786 !(data[offset + 2] & 0xfe);
2787 }
2788
IsEncryptedPrivateKeyInfo(const unsigned char * data,size_t size)2789 static bool IsEncryptedPrivateKeyInfo(const unsigned char* data, size_t size) {
2790 // Both PrivateKeyInfo and EncryptedPrivateKeyInfo start with a SEQUENCE.
2791 size_t offset, len;
2792 if (!IsASN1Sequence(data, size, &offset, &len))
2793 return false;
2794
2795 // A PrivateKeyInfo sequence always starts with an integer whereas an
2796 // EncryptedPrivateKeyInfo starts with an AlgorithmIdentifier.
2797 return len >= 1 &&
2798 data[offset] != 2;
2799 }
2800
ParsePrivateKey(EVPKeyPointer * pkey,const PrivateKeyEncodingConfig & config,const char * key,size_t key_len)2801 static ParseKeyResult ParsePrivateKey(EVPKeyPointer* pkey,
2802 const PrivateKeyEncodingConfig& config,
2803 const char* key,
2804 size_t key_len) {
2805 // OpenSSL needs a non-const pointer, that's why the const_cast is required.
2806 char* const passphrase = const_cast<char*>(config.passphrase_.get());
2807
2808 if (config.format_ == kKeyFormatPEM) {
2809 BIOPointer bio(BIO_new_mem_buf(key, key_len));
2810 if (!bio)
2811 return ParseKeyResult::kParseKeyFailed;
2812
2813 pkey->reset(PEM_read_bio_PrivateKey(bio.get(),
2814 nullptr,
2815 PasswordCallback,
2816 passphrase));
2817 } else {
2818 CHECK_EQ(config.format_, kKeyFormatDER);
2819
2820 if (config.type_.ToChecked() == kKeyEncodingPKCS1) {
2821 const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
2822 pkey->reset(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &p, key_len));
2823 } else if (config.type_.ToChecked() == kKeyEncodingPKCS8) {
2824 BIOPointer bio(BIO_new_mem_buf(key, key_len));
2825 if (!bio)
2826 return ParseKeyResult::kParseKeyFailed;
2827
2828 if (IsEncryptedPrivateKeyInfo(
2829 reinterpret_cast<const unsigned char*>(key), key_len)) {
2830 pkey->reset(d2i_PKCS8PrivateKey_bio(bio.get(),
2831 nullptr,
2832 PasswordCallback,
2833 passphrase));
2834 } else {
2835 PKCS8Pointer p8inf(d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr));
2836 if (p8inf)
2837 pkey->reset(EVP_PKCS82PKEY(p8inf.get()));
2838 }
2839 } else {
2840 CHECK_EQ(config.type_.ToChecked(), kKeyEncodingSEC1);
2841 const unsigned char* p = reinterpret_cast<const unsigned char*>(key);
2842 pkey->reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, key_len));
2843 }
2844 }
2845
2846 // OpenSSL can fail to parse the key but still return a non-null pointer.
2847 unsigned long err = ERR_peek_error(); // NOLINT(runtime/int)
2848 if (err != 0)
2849 pkey->reset();
2850
2851 if (*pkey)
2852 return ParseKeyResult::kParseKeyOk;
2853 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
2854 ERR_GET_REASON(err) == PEM_R_BAD_PASSWORD_READ) {
2855 if (config.passphrase_.get() == nullptr)
2856 return ParseKeyResult::kParseKeyNeedPassphrase;
2857 }
2858 return ParseKeyResult::kParseKeyFailed;
2859 }
2860
ByteSource(ByteSource && other)2861 ByteSource::ByteSource(ByteSource&& other)
2862 : data_(other.data_),
2863 allocated_data_(other.allocated_data_),
2864 size_(other.size_) {
2865 other.allocated_data_ = nullptr;
2866 }
2867
~ByteSource()2868 ByteSource::~ByteSource() {
2869 OPENSSL_clear_free(allocated_data_, size_);
2870 }
2871
operator =(ByteSource && other)2872 ByteSource& ByteSource::operator=(ByteSource&& other) {
2873 if (&other != this) {
2874 OPENSSL_clear_free(allocated_data_, size_);
2875 data_ = other.data_;
2876 allocated_data_ = other.allocated_data_;
2877 other.allocated_data_ = nullptr;
2878 size_ = other.size_;
2879 }
2880 return *this;
2881 }
2882
get() const2883 const char* ByteSource::get() const {
2884 return data_;
2885 }
2886
size() const2887 size_t ByteSource::size() const {
2888 return size_;
2889 }
2890
FromStringOrBuffer(Environment * env,Local<Value> value)2891 ByteSource ByteSource::FromStringOrBuffer(Environment* env,
2892 Local<Value> value) {
2893 return Buffer::HasInstance(value) ? FromBuffer(value)
2894 : FromString(env, value.As<String>());
2895 }
2896
FromString(Environment * env,Local<String> str,bool ntc)2897 ByteSource ByteSource::FromString(Environment* env, Local<String> str,
2898 bool ntc) {
2899 CHECK(str->IsString());
2900 size_t size = str->Utf8Length(env->isolate());
2901 size_t alloc_size = ntc ? size + 1 : size;
2902 char* data = MallocOpenSSL<char>(alloc_size);
2903 int opts = String::NO_OPTIONS;
2904 if (!ntc) opts |= String::NO_NULL_TERMINATION;
2905 str->WriteUtf8(env->isolate(), data, alloc_size, nullptr, opts);
2906 return Allocated(data, size);
2907 }
2908
FromBuffer(Local<Value> buffer,bool ntc)2909 ByteSource ByteSource::FromBuffer(Local<Value> buffer, bool ntc) {
2910 CHECK(buffer->IsArrayBufferView());
2911 Local<ArrayBufferView> abv = buffer.As<ArrayBufferView>();
2912 size_t size = abv->ByteLength();
2913 if (ntc) {
2914 char* data = MallocOpenSSL<char>(size + 1);
2915 abv->CopyContents(data, size);
2916 data[size] = 0;
2917 return Allocated(data, size);
2918 }
2919 return Foreign(Buffer::Data(buffer), size);
2920 }
2921
NullTerminatedCopy(Environment * env,Local<Value> value)2922 ByteSource ByteSource::NullTerminatedCopy(Environment* env,
2923 Local<Value> value) {
2924 return Buffer::HasInstance(value) ? FromBuffer(value, true)
2925 : FromString(env, value.As<String>(), true);
2926 }
2927
FromSymmetricKeyObjectHandle(Local<Value> handle)2928 ByteSource ByteSource::FromSymmetricKeyObjectHandle(Local<Value> handle) {
2929 CHECK(handle->IsObject());
2930 KeyObjectHandle* key = Unwrap<KeyObjectHandle>(handle.As<Object>());
2931 CHECK_NOT_NULL(key);
2932 return Foreign(key->Data()->GetSymmetricKey(),
2933 key->Data()->GetSymmetricKeySize());
2934 }
2935
ByteSource(const char * data,char * allocated_data,size_t size)2936 ByteSource::ByteSource(const char* data, char* allocated_data, size_t size)
2937 : data_(data),
2938 allocated_data_(allocated_data),
2939 size_(size) {}
2940
Allocated(char * data,size_t size)2941 ByteSource ByteSource::Allocated(char* data, size_t size) {
2942 return ByteSource(data, data, size);
2943 }
2944
Foreign(const char * data,size_t size)2945 ByteSource ByteSource::Foreign(const char* data, size_t size) {
2946 return ByteSource(data, nullptr, size);
2947 }
2948
2949 enum KeyEncodingContext {
2950 kKeyContextInput,
2951 kKeyContextExport,
2952 kKeyContextGenerate
2953 };
2954
GetKeyFormatAndTypeFromJs(AsymmetricKeyEncodingConfig * config,const FunctionCallbackInfo<Value> & args,unsigned int * offset,KeyEncodingContext context)2955 static void GetKeyFormatAndTypeFromJs(
2956 AsymmetricKeyEncodingConfig* config,
2957 const FunctionCallbackInfo<Value>& args,
2958 unsigned int* offset,
2959 KeyEncodingContext context) {
2960 // During key pair generation, it is possible not to specify a key encoding,
2961 // which will lead to a key object being returned.
2962 if (args[*offset]->IsUndefined()) {
2963 CHECK_EQ(context, kKeyContextGenerate);
2964 CHECK(args[*offset + 1]->IsUndefined());
2965 config->output_key_object_ = true;
2966 } else {
2967 config->output_key_object_ = false;
2968
2969 CHECK(args[*offset]->IsInt32());
2970 config->format_ = static_cast<PKFormatType>(
2971 args[*offset].As<Int32>()->Value());
2972
2973 if (args[*offset + 1]->IsInt32()) {
2974 config->type_ = Just<PKEncodingType>(static_cast<PKEncodingType>(
2975 args[*offset + 1].As<Int32>()->Value()));
2976 } else {
2977 CHECK(context == kKeyContextInput && config->format_ == kKeyFormatPEM);
2978 CHECK(args[*offset + 1]->IsNullOrUndefined());
2979 config->type_ = Nothing<PKEncodingType>();
2980 }
2981 }
2982
2983 *offset += 2;
2984 }
2985
GetPublicKeyEncodingFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset,KeyEncodingContext context)2986 static PublicKeyEncodingConfig GetPublicKeyEncodingFromJs(
2987 const FunctionCallbackInfo<Value>& args,
2988 unsigned int* offset,
2989 KeyEncodingContext context) {
2990 PublicKeyEncodingConfig result;
2991 GetKeyFormatAndTypeFromJs(&result, args, offset, context);
2992 return result;
2993 }
2994
GetParsedKey(Environment * env,EVPKeyPointer && pkey,ParseKeyResult ret,const char * default_msg)2995 static inline ManagedEVPPKey GetParsedKey(Environment* env,
2996 EVPKeyPointer&& pkey,
2997 ParseKeyResult ret,
2998 const char* default_msg) {
2999 switch (ret) {
3000 case ParseKeyResult::kParseKeyOk:
3001 CHECK(pkey);
3002 break;
3003 case ParseKeyResult::kParseKeyNeedPassphrase:
3004 THROW_ERR_MISSING_PASSPHRASE(env,
3005 "Passphrase required for encrypted key");
3006 break;
3007 default:
3008 ThrowCryptoError(env, ERR_get_error(), default_msg);
3009 }
3010
3011 return ManagedEVPPKey(std::move(pkey));
3012 }
3013
GetPrivateKeyEncodingFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset,KeyEncodingContext context)3014 static NonCopyableMaybe<PrivateKeyEncodingConfig> GetPrivateKeyEncodingFromJs(
3015 const FunctionCallbackInfo<Value>& args,
3016 unsigned int* offset,
3017 KeyEncodingContext context) {
3018 Environment* env = Environment::GetCurrent(args);
3019
3020 PrivateKeyEncodingConfig result;
3021 GetKeyFormatAndTypeFromJs(&result, args, offset, context);
3022
3023 if (result.output_key_object_) {
3024 if (context != kKeyContextInput)
3025 (*offset)++;
3026 } else {
3027 bool needs_passphrase = false;
3028 if (context != kKeyContextInput) {
3029 if (args[*offset]->IsString()) {
3030 String::Utf8Value cipher_name(env->isolate(),
3031 args[*offset].As<String>());
3032 result.cipher_ = EVP_get_cipherbyname(*cipher_name);
3033 if (result.cipher_ == nullptr) {
3034 THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env);
3035 return NonCopyableMaybe<PrivateKeyEncodingConfig>();
3036 }
3037 needs_passphrase = true;
3038 } else {
3039 CHECK(args[*offset]->IsNullOrUndefined());
3040 result.cipher_ = nullptr;
3041 }
3042 (*offset)++;
3043 }
3044
3045 if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
3046 CHECK_IMPLIES(context != kKeyContextInput, result.cipher_ != nullptr);
3047
3048 result.passphrase_ = ByteSource::NullTerminatedCopy(env, args[*offset]);
3049 } else {
3050 CHECK(args[*offset]->IsNullOrUndefined() && !needs_passphrase);
3051 }
3052 }
3053
3054 (*offset)++;
3055 return NonCopyableMaybe<PrivateKeyEncodingConfig>(std::move(result));
3056 }
3057
GetPrivateKeyFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset,bool allow_key_object)3058 static ManagedEVPPKey GetPrivateKeyFromJs(
3059 const FunctionCallbackInfo<Value>& args,
3060 unsigned int* offset,
3061 bool allow_key_object) {
3062 if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
3063 Environment* env = Environment::GetCurrent(args);
3064 ByteSource key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
3065 NonCopyableMaybe<PrivateKeyEncodingConfig> config =
3066 GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput);
3067 if (config.IsEmpty())
3068 return ManagedEVPPKey();
3069
3070 EVPKeyPointer pkey;
3071 ParseKeyResult ret =
3072 ParsePrivateKey(&pkey, config.Release(), key.get(), key.size());
3073 return GetParsedKey(env, std::move(pkey), ret,
3074 "Failed to read private key");
3075 } else {
3076 CHECK(args[*offset]->IsObject() && allow_key_object);
3077 KeyObjectHandle* key;
3078 ASSIGN_OR_RETURN_UNWRAP(&key, args[*offset].As<Object>(), ManagedEVPPKey());
3079 CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePrivate);
3080 (*offset) += 4;
3081 return key->Data()->GetAsymmetricKey();
3082 }
3083 }
3084
GetPublicOrPrivateKeyFromJs(const FunctionCallbackInfo<Value> & args,unsigned int * offset)3085 static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
3086 const FunctionCallbackInfo<Value>& args,
3087 unsigned int* offset) {
3088 if (args[*offset]->IsString() || Buffer::HasInstance(args[*offset])) {
3089 Environment* env = Environment::GetCurrent(args);
3090 ByteSource data = ByteSource::FromStringOrBuffer(env, args[(*offset)++]);
3091 NonCopyableMaybe<PrivateKeyEncodingConfig> config_ =
3092 GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput);
3093 if (config_.IsEmpty())
3094 return ManagedEVPPKey();
3095
3096 ParseKeyResult ret;
3097 PrivateKeyEncodingConfig config = config_.Release();
3098 EVPKeyPointer pkey;
3099 if (config.format_ == kKeyFormatPEM) {
3100 // For PEM, we can easily determine whether it is a public or private key
3101 // by looking for the respective PEM tags.
3102 ret = ParsePublicKeyPEM(&pkey, data.get(), data.size());
3103 if (ret == ParseKeyResult::kParseKeyNotRecognized) {
3104 ret = ParsePrivateKey(&pkey, config, data.get(), data.size());
3105 }
3106 } else {
3107 // For DER, the type determines how to parse it. SPKI, PKCS#8 and SEC1 are
3108 // easy, but PKCS#1 can be a public key or a private key.
3109 bool is_public;
3110 switch (config.type_.ToChecked()) {
3111 case kKeyEncodingPKCS1:
3112 is_public = !IsRSAPrivateKey(
3113 reinterpret_cast<const unsigned char*>(data.get()), data.size());
3114 break;
3115 case kKeyEncodingSPKI:
3116 is_public = true;
3117 break;
3118 case kKeyEncodingPKCS8:
3119 case kKeyEncodingSEC1:
3120 is_public = false;
3121 break;
3122 default:
3123 UNREACHABLE("Invalid key encoding type");
3124 }
3125
3126 if (is_public) {
3127 ret = ParsePublicKey(&pkey, config, data.get(), data.size());
3128 } else {
3129 ret = ParsePrivateKey(&pkey, config, data.get(), data.size());
3130 }
3131 }
3132
3133 return GetParsedKey(env, std::move(pkey), ret,
3134 "Failed to read asymmetric key");
3135 } else {
3136 CHECK(args[*offset]->IsObject());
3137 KeyObjectHandle* key = Unwrap<KeyObjectHandle>(args[*offset].As<Object>());
3138 CHECK_NOT_NULL(key);
3139 CHECK_NE(key->Data()->GetKeyType(), kKeyTypeSecret);
3140 (*offset) += 4;
3141 return key->Data()->GetAsymmetricKey();
3142 }
3143 }
3144
WritePrivateKey(Environment * env,EVP_PKEY * pkey,const PrivateKeyEncodingConfig & config)3145 static MaybeLocal<Value> WritePrivateKey(
3146 Environment* env,
3147 EVP_PKEY* pkey,
3148 const PrivateKeyEncodingConfig& config) {
3149 BIOPointer bio(BIO_new(BIO_s_mem()));
3150 CHECK(bio);
3151
3152 bool err;
3153
3154 PKEncodingType encoding_type = config.type_.ToChecked();
3155 if (encoding_type == kKeyEncodingPKCS1) {
3156 // PKCS#1 is only permitted for RSA keys.
3157 CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_RSA);
3158
3159 RSAPointer rsa(EVP_PKEY_get1_RSA(pkey));
3160 if (config.format_ == kKeyFormatPEM) {
3161 // Encode PKCS#1 as PEM.
3162 const char* pass = config.passphrase_.get();
3163 err = PEM_write_bio_RSAPrivateKey(
3164 bio.get(), rsa.get(),
3165 config.cipher_,
3166 reinterpret_cast<unsigned char*>(const_cast<char*>(pass)),
3167 config.passphrase_.size(),
3168 nullptr, nullptr) != 1;
3169 } else {
3170 // Encode PKCS#1 as DER. This does not permit encryption.
3171 CHECK_EQ(config.format_, kKeyFormatDER);
3172 CHECK_NULL(config.cipher_);
3173 err = i2d_RSAPrivateKey_bio(bio.get(), rsa.get()) != 1;
3174 }
3175 } else if (encoding_type == kKeyEncodingPKCS8) {
3176 if (config.format_ == kKeyFormatPEM) {
3177 // Encode PKCS#8 as PEM.
3178 err = PEM_write_bio_PKCS8PrivateKey(
3179 bio.get(), pkey,
3180 config.cipher_,
3181 const_cast<char*>(config.passphrase_.get()),
3182 config.passphrase_.size(),
3183 nullptr, nullptr) != 1;
3184 } else {
3185 // Encode PKCS#8 as DER.
3186 CHECK_EQ(config.format_, kKeyFormatDER);
3187 err = i2d_PKCS8PrivateKey_bio(
3188 bio.get(), pkey,
3189 config.cipher_,
3190 const_cast<char*>(config.passphrase_.get()),
3191 config.passphrase_.size(),
3192 nullptr, nullptr) != 1;
3193 }
3194 } else {
3195 CHECK_EQ(encoding_type, kKeyEncodingSEC1);
3196
3197 // SEC1 is only permitted for EC keys.
3198 CHECK_EQ(EVP_PKEY_id(pkey), EVP_PKEY_EC);
3199
3200 ECKeyPointer ec_key(EVP_PKEY_get1_EC_KEY(pkey));
3201 if (config.format_ == kKeyFormatPEM) {
3202 // Encode SEC1 as PEM.
3203 const char* pass = config.passphrase_.get();
3204 err = PEM_write_bio_ECPrivateKey(
3205 bio.get(), ec_key.get(),
3206 config.cipher_,
3207 reinterpret_cast<unsigned char*>(const_cast<char*>(pass)),
3208 config.passphrase_.size(),
3209 nullptr, nullptr) != 1;
3210 } else {
3211 // Encode SEC1 as DER. This does not permit encryption.
3212 CHECK_EQ(config.format_, kKeyFormatDER);
3213 CHECK_NULL(config.cipher_);
3214 err = i2d_ECPrivateKey_bio(bio.get(), ec_key.get()) != 1;
3215 }
3216 }
3217
3218 if (err) {
3219 ThrowCryptoError(env, ERR_get_error(), "Failed to encode private key");
3220 return MaybeLocal<Value>();
3221 }
3222 return BIOToStringOrBuffer(env, bio.get(), config.format_);
3223 }
3224
ManagedEVPPKey(EVPKeyPointer && pkey)3225 ManagedEVPPKey::ManagedEVPPKey(EVPKeyPointer&& pkey) : pkey_(std::move(pkey)) {}
3226
ManagedEVPPKey(const ManagedEVPPKey & that)3227 ManagedEVPPKey::ManagedEVPPKey(const ManagedEVPPKey& that) {
3228 *this = that;
3229 }
3230
operator =(const ManagedEVPPKey & that)3231 ManagedEVPPKey& ManagedEVPPKey::operator=(const ManagedEVPPKey& that) {
3232 pkey_.reset(that.get());
3233
3234 if (pkey_)
3235 EVP_PKEY_up_ref(pkey_.get());
3236
3237 return *this;
3238 }
3239
operator bool() const3240 ManagedEVPPKey::operator bool() const {
3241 return !!pkey_;
3242 }
3243
get() const3244 EVP_PKEY* ManagedEVPPKey::get() const {
3245 return pkey_.get();
3246 }
3247
CreateSecret(Local<ArrayBufferView> abv)3248 std::shared_ptr<KeyObjectData> KeyObjectData::CreateSecret(
3249 Local<ArrayBufferView> abv) {
3250 size_t key_len = abv->ByteLength();
3251 char* mem = MallocOpenSSL<char>(key_len);
3252 abv->CopyContents(mem, key_len);
3253 return std::shared_ptr<KeyObjectData>(new KeyObjectData(
3254 std::unique_ptr<char, std::function<void(char*)>>(mem,
3255 [key_len](char* p) {
3256 OPENSSL_clear_free(p, key_len);
3257 }),
3258 key_len));
3259 }
3260
CreateAsymmetric(KeyType key_type,const ManagedEVPPKey & pkey)3261 std::shared_ptr<KeyObjectData> KeyObjectData::CreateAsymmetric(
3262 KeyType key_type,
3263 const ManagedEVPPKey& pkey) {
3264 CHECK(pkey);
3265 return std::shared_ptr<KeyObjectData>(new KeyObjectData(key_type, pkey));
3266 }
3267
GetKeyType() const3268 KeyType KeyObjectData::GetKeyType() const {
3269 return key_type_;
3270 }
3271
GetAsymmetricKey() const3272 ManagedEVPPKey KeyObjectData::GetAsymmetricKey() const {
3273 CHECK_NE(key_type_, kKeyTypeSecret);
3274 return asymmetric_key_;
3275 }
3276
GetSymmetricKey() const3277 const char* KeyObjectData::GetSymmetricKey() const {
3278 CHECK_EQ(key_type_, kKeyTypeSecret);
3279 return symmetric_key_.get();
3280 }
3281
GetSymmetricKeySize() const3282 size_t KeyObjectData::GetSymmetricKeySize() const {
3283 CHECK_EQ(key_type_, kKeyTypeSecret);
3284 return symmetric_key_len_;
3285 }
3286
Initialize(Environment * env)3287 Local<Function> KeyObjectHandle::Initialize(Environment* env) {
3288 Local<Function> templ = env->crypto_key_object_handle_constructor();
3289 if (!templ.IsEmpty()) {
3290 return templ;
3291 }
3292 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3293 t->InstanceTemplate()->SetInternalFieldCount(
3294 KeyObjectHandle::kInternalFieldCount);
3295 t->Inherit(BaseObject::GetConstructorTemplate(env));
3296
3297 env->SetProtoMethod(t, "init", Init);
3298 env->SetProtoMethodNoSideEffect(t, "getSymmetricKeySize",
3299 GetSymmetricKeySize);
3300 env->SetProtoMethodNoSideEffect(t, "getAsymmetricKeyType",
3301 GetAsymmetricKeyType);
3302 env->SetProtoMethod(t, "export", Export);
3303
3304 auto function = t->GetFunction(env->context()).ToLocalChecked();
3305 env->set_crypto_key_object_handle_constructor(function);
3306 return KeyObjectHandle::Initialize(env);
3307 }
3308
Create(Environment * env,std::shared_ptr<KeyObjectData> data)3309 MaybeLocal<Object> KeyObjectHandle::Create(
3310 Environment* env,
3311 std::shared_ptr<KeyObjectData> data) {
3312 Local<Object> obj;
3313 Local<Function> fctun = KeyObjectHandle::Initialize(env);
3314 if (!fctun->NewInstance(env->context(), 0, nullptr).ToLocal(&obj)) {
3315 return MaybeLocal<Object>();
3316 }
3317
3318 KeyObjectHandle* key = Unwrap<KeyObjectHandle>(obj);
3319 CHECK_NOT_NULL(key);
3320 key->data_ = data;
3321 return obj;
3322 }
3323
Data()3324 const std::shared_ptr<KeyObjectData>& KeyObjectHandle::Data() {
3325 return data_;
3326 }
3327
New(const FunctionCallbackInfo<Value> & args)3328 void KeyObjectHandle::New(const FunctionCallbackInfo<Value>& args) {
3329 CHECK(args.IsConstructCall());
3330 Environment* env = Environment::GetCurrent(args);
3331 new KeyObjectHandle(env, args.This());
3332 }
3333
KeyObjectHandle(Environment * env,Local<Object> wrap)3334 KeyObjectHandle::KeyObjectHandle(Environment* env,
3335 Local<Object> wrap)
3336 : BaseObject(env, wrap) {
3337 MakeWeak();
3338 }
3339
Init(const FunctionCallbackInfo<Value> & args)3340 void KeyObjectHandle::Init(const FunctionCallbackInfo<Value>& args) {
3341 KeyObjectHandle* key;
3342 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3343 MarkPopErrorOnReturn mark_pop_error_on_return;
3344
3345 CHECK(args[0]->IsInt32());
3346 KeyType type = static_cast<KeyType>(args[0].As<Uint32>()->Value());
3347
3348 unsigned int offset;
3349 ManagedEVPPKey pkey;
3350
3351 switch (type) {
3352 case kKeyTypeSecret:
3353 CHECK_EQ(args.Length(), 2);
3354 CHECK(args[1]->IsArrayBufferView());
3355 key->data_ = KeyObjectData::CreateSecret(args[1].As<ArrayBufferView>());
3356 break;
3357 case kKeyTypePublic:
3358 CHECK_EQ(args.Length(), 4);
3359
3360 offset = 1;
3361 pkey = GetPublicOrPrivateKeyFromJs(args, &offset);
3362 if (!pkey)
3363 return;
3364 key->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
3365 break;
3366 case kKeyTypePrivate:
3367 CHECK_EQ(args.Length(), 5);
3368
3369 offset = 1;
3370 pkey = GetPrivateKeyFromJs(args, &offset, false);
3371 if (!pkey)
3372 return;
3373 key->data_ = KeyObjectData::CreateAsymmetric(type, pkey);
3374 break;
3375 default:
3376 CHECK(false);
3377 }
3378 }
3379
GetAsymmetricKeyType() const3380 Local<Value> KeyObjectHandle::GetAsymmetricKeyType() const {
3381 const ManagedEVPPKey& key = data_->GetAsymmetricKey();
3382 switch (EVP_PKEY_id(key.get())) {
3383 case EVP_PKEY_RSA:
3384 return env()->crypto_rsa_string();
3385 case EVP_PKEY_RSA_PSS:
3386 return env()->crypto_rsa_pss_string();
3387 case EVP_PKEY_DSA:
3388 return env()->crypto_dsa_string();
3389 case EVP_PKEY_DH:
3390 return env()->crypto_dh_string();
3391 case EVP_PKEY_EC:
3392 return env()->crypto_ec_string();
3393 case EVP_PKEY_ED25519:
3394 return env()->crypto_ed25519_string();
3395 case EVP_PKEY_ED448:
3396 return env()->crypto_ed448_string();
3397 case EVP_PKEY_X25519:
3398 return env()->crypto_x25519_string();
3399 case EVP_PKEY_X448:
3400 return env()->crypto_x448_string();
3401 default:
3402 return Undefined(env()->isolate());
3403 }
3404 }
3405
GetAsymmetricKeyType(const FunctionCallbackInfo<Value> & args)3406 void KeyObjectHandle::GetAsymmetricKeyType(
3407 const FunctionCallbackInfo<Value>& args) {
3408 KeyObjectHandle* key;
3409 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3410
3411 args.GetReturnValue().Set(key->GetAsymmetricKeyType());
3412 }
3413
GetSymmetricKeySize(const FunctionCallbackInfo<Value> & args)3414 void KeyObjectHandle::GetSymmetricKeySize(
3415 const FunctionCallbackInfo<Value>& args) {
3416 KeyObjectHandle* key;
3417 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3418 args.GetReturnValue().Set(
3419 static_cast<uint32_t>(key->Data()->GetSymmetricKeySize()));
3420 }
3421
Export(const FunctionCallbackInfo<Value> & args)3422 void KeyObjectHandle::Export(const FunctionCallbackInfo<Value>& args) {
3423 KeyObjectHandle* key;
3424 ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
3425
3426 KeyType type = key->Data()->GetKeyType();
3427
3428 MaybeLocal<Value> result;
3429 if (type == kKeyTypeSecret) {
3430 result = key->ExportSecretKey();
3431 } else if (type == kKeyTypePublic) {
3432 unsigned int offset = 0;
3433 PublicKeyEncodingConfig config =
3434 GetPublicKeyEncodingFromJs(args, &offset, kKeyContextExport);
3435 CHECK_EQ(offset, static_cast<unsigned int>(args.Length()));
3436 result = key->ExportPublicKey(config);
3437 } else {
3438 CHECK_EQ(type, kKeyTypePrivate);
3439 unsigned int offset = 0;
3440 NonCopyableMaybe<PrivateKeyEncodingConfig> config =
3441 GetPrivateKeyEncodingFromJs(args, &offset, kKeyContextExport);
3442 if (config.IsEmpty())
3443 return;
3444 CHECK_EQ(offset, static_cast<unsigned int>(args.Length()));
3445 result = key->ExportPrivateKey(config.Release());
3446 }
3447
3448 if (!result.IsEmpty())
3449 args.GetReturnValue().Set(result.ToLocalChecked());
3450 }
3451
ExportSecretKey() const3452 Local<Value> KeyObjectHandle::ExportSecretKey() const {
3453 const char* buf = data_->GetSymmetricKey();
3454 unsigned int len = data_->GetSymmetricKeySize();
3455 return Buffer::Copy(env(), buf, len).ToLocalChecked();
3456 }
3457
ExportPublicKey(const PublicKeyEncodingConfig & config) const3458 MaybeLocal<Value> KeyObjectHandle::ExportPublicKey(
3459 const PublicKeyEncodingConfig& config) const {
3460 return WritePublicKey(env(), data_->GetAsymmetricKey().get(), config);
3461 }
3462
ExportPrivateKey(const PrivateKeyEncodingConfig & config) const3463 MaybeLocal<Value> KeyObjectHandle::ExportPrivateKey(
3464 const PrivateKeyEncodingConfig& config) const {
3465 return WritePrivateKey(env(), data_->GetAsymmetricKey().get(), config);
3466 }
3467
New(const FunctionCallbackInfo<Value> & args)3468 void NativeKeyObject::New(const FunctionCallbackInfo<Value>& args) {
3469 Environment* env = Environment::GetCurrent(args);
3470 CHECK_EQ(args.Length(), 1);
3471 CHECK(args[0]->IsObject());
3472 KeyObjectHandle* handle = Unwrap<KeyObjectHandle>(args[0].As<Object>());
3473 new NativeKeyObject(env, args.This(), handle->Data());
3474 }
3475
Deserialize(Environment * env,Local<Context> context,std::unique_ptr<worker::TransferData> self)3476 BaseObjectPtr<BaseObject> NativeKeyObject::KeyObjectTransferData::Deserialize(
3477 Environment* env,
3478 Local<Context> context,
3479 std::unique_ptr<worker::TransferData> self) {
3480 if (context != env->context()) {
3481 THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env);
3482 return {};
3483 }
3484
3485 Local<Value> handle = KeyObjectHandle::Create(env, data_).ToLocalChecked();
3486 Local<Function> key_ctor;
3487 Local<Value> arg = FIXED_ONE_BYTE_STRING(env->isolate(),
3488 "internal/crypto/keys");
3489 if (env->native_module_require()->
3490 Call(context, Null(env->isolate()), 1, &arg).IsEmpty())
3491 return {};
3492 switch (data_->GetKeyType()) {
3493 case kKeyTypeSecret:
3494 key_ctor = env->crypto_key_object_secret_constructor();
3495 break;
3496 case kKeyTypePublic:
3497 key_ctor = env->crypto_key_object_public_constructor();
3498 break;
3499 case kKeyTypePrivate:
3500 key_ctor = env->crypto_key_object_private_constructor();
3501 break;
3502 default:
3503 CHECK(false);
3504 }
3505
3506 Local<Value> key =
3507 key_ctor->NewInstance(context, 1, &handle).ToLocalChecked();
3508 return BaseObjectPtr<BaseObject>(Unwrap<KeyObjectHandle>(key.As<Object>()));
3509 }
3510
GetTransferMode() const3511 BaseObject::TransferMode NativeKeyObject::GetTransferMode() const {
3512 return BaseObject::TransferMode::kCloneable;
3513 }
3514
CloneForMessaging() const3515 std::unique_ptr<worker::TransferData> NativeKeyObject::CloneForMessaging()
3516 const {
3517 return std::make_unique<KeyObjectTransferData>(handle_data_);
3518 }
3519
CreateNativeKeyObjectClass(const FunctionCallbackInfo<Value> & args)3520 static void CreateNativeKeyObjectClass(
3521 const FunctionCallbackInfo<Value>& args) {
3522 Environment* env = Environment::GetCurrent(args);
3523
3524 CHECK_EQ(args.Length(), 1);
3525 Local<Value> callback = args[0];
3526 CHECK(callback->IsFunction());
3527
3528 Local<FunctionTemplate> t = env->NewFunctionTemplate(NativeKeyObject::New);
3529 t->InstanceTemplate()->SetInternalFieldCount(
3530 KeyObjectHandle::kInternalFieldCount);
3531 t->Inherit(BaseObject::GetConstructorTemplate(env));
3532
3533 Local<Value> ctor = t->GetFunction(env->context()).ToLocalChecked();
3534
3535 Local<Value> recv = Undefined(env->isolate());
3536 Local<Value> ret_v;
3537 if (!callback.As<Function>()->Call(
3538 env->context(), recv, 1, &ctor).ToLocal(&ret_v)) {
3539 return;
3540 }
3541 Local<Array> ret = ret_v.As<Array>();
3542 if (!ret->Get(env->context(), 1).ToLocal(&ctor)) return;
3543 env->set_crypto_key_object_secret_constructor(ctor.As<Function>());
3544 if (!ret->Get(env->context(), 2).ToLocal(&ctor)) return;
3545 env->set_crypto_key_object_public_constructor(ctor.As<Function>());
3546 if (!ret->Get(env->context(), 3).ToLocal(&ctor)) return;
3547 env->set_crypto_key_object_private_constructor(ctor.As<Function>());
3548 args.GetReturnValue().Set(ret);
3549 }
3550
CipherBase(Environment * env,Local<Object> wrap,CipherKind kind)3551 CipherBase::CipherBase(Environment* env,
3552 Local<Object> wrap,
3553 CipherKind kind)
3554 : BaseObject(env, wrap),
3555 ctx_(nullptr),
3556 kind_(kind),
3557 auth_tag_state_(kAuthTagUnknown),
3558 auth_tag_len_(kNoAuthTagLength),
3559 pending_auth_failed_(false) {
3560 MakeWeak();
3561 }
3562
Initialize(Environment * env,Local<Object> target)3563 void CipherBase::Initialize(Environment* env, Local<Object> target) {
3564 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
3565
3566 t->InstanceTemplate()->SetInternalFieldCount(
3567 CipherBase::kInternalFieldCount);
3568 t->Inherit(BaseObject::GetConstructorTemplate(env));
3569
3570 env->SetProtoMethod(t, "init", Init);
3571 env->SetProtoMethod(t, "initiv", InitIv);
3572 env->SetProtoMethod(t, "update", Update);
3573 env->SetProtoMethod(t, "final", Final);
3574 env->SetProtoMethod(t, "setAutoPadding", SetAutoPadding);
3575 env->SetProtoMethodNoSideEffect(t, "getAuthTag", GetAuthTag);
3576 env->SetProtoMethod(t, "setAuthTag", SetAuthTag);
3577 env->SetProtoMethod(t, "setAAD", SetAAD);
3578
3579 target->Set(env->context(),
3580 FIXED_ONE_BYTE_STRING(env->isolate(), "CipherBase"),
3581 t->GetFunction(env->context()).ToLocalChecked()).Check();
3582 }
3583
3584
New(const FunctionCallbackInfo<Value> & args)3585 void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
3586 CHECK(args.IsConstructCall());
3587 CipherKind kind = args[0]->IsTrue() ? kCipher : kDecipher;
3588 Environment* env = Environment::GetCurrent(args);
3589 new CipherBase(env, args.This(), kind);
3590 }
3591
CommonInit(const char * cipher_type,const EVP_CIPHER * cipher,const unsigned char * key,int key_len,const unsigned char * iv,int iv_len,unsigned int auth_tag_len)3592 void CipherBase::CommonInit(const char* cipher_type,
3593 const EVP_CIPHER* cipher,
3594 const unsigned char* key,
3595 int key_len,
3596 const unsigned char* iv,
3597 int iv_len,
3598 unsigned int auth_tag_len) {
3599 CHECK(!ctx_);
3600 ctx_.reset(EVP_CIPHER_CTX_new());
3601
3602 const int mode = EVP_CIPHER_mode(cipher);
3603 if (mode == EVP_CIPH_WRAP_MODE)
3604 EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3605
3606 const bool encrypt = (kind_ == kCipher);
3607 if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
3608 nullptr, nullptr, encrypt)) {
3609 return ThrowCryptoError(env(), ERR_get_error(),
3610 "Failed to initialize cipher");
3611 }
3612
3613 if (IsSupportedAuthenticatedMode(cipher)) {
3614 CHECK_GE(iv_len, 0);
3615 if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len))
3616 return;
3617 }
3618
3619 if (!EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len)) {
3620 ctx_.reset();
3621 return env()->ThrowError("Invalid key length");
3622 }
3623
3624 if (1 != EVP_CipherInit_ex(ctx_.get(), nullptr, nullptr, key, iv, encrypt)) {
3625 return ThrowCryptoError(env(), ERR_get_error(),
3626 "Failed to initialize cipher");
3627 }
3628 }
3629
Init(const char * cipher_type,const char * key_buf,int key_buf_len,unsigned int auth_tag_len)3630 void CipherBase::Init(const char* cipher_type,
3631 const char* key_buf,
3632 int key_buf_len,
3633 unsigned int auth_tag_len) {
3634 HandleScope scope(env()->isolate());
3635 MarkPopErrorOnReturn mark_pop_error_on_return;
3636
3637 if (FIPS_mode()) {
3638 return env()->ThrowError(
3639 "crypto.createCipher() is not supported in FIPS mode.");
3640 }
3641
3642 const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
3643 if (cipher == nullptr)
3644 return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
3645
3646 unsigned char key[EVP_MAX_KEY_LENGTH];
3647 unsigned char iv[EVP_MAX_IV_LENGTH];
3648
3649 int key_len = EVP_BytesToKey(cipher,
3650 EVP_md5(),
3651 nullptr,
3652 reinterpret_cast<const unsigned char*>(key_buf),
3653 key_buf_len,
3654 1,
3655 key,
3656 iv);
3657 CHECK_NE(key_len, 0);
3658
3659 const int mode = EVP_CIPHER_mode(cipher);
3660 if (kind_ == kCipher && (mode == EVP_CIPH_CTR_MODE ||
3661 mode == EVP_CIPH_GCM_MODE ||
3662 mode == EVP_CIPH_CCM_MODE)) {
3663 // Ignore the return value (i.e. possible exception) because we are
3664 // not calling back into JS anyway.
3665 ProcessEmitWarning(env(),
3666 "Use Cipheriv for counter mode of %s",
3667 cipher_type);
3668 }
3669
3670 CommonInit(cipher_type, cipher, key, key_len, iv,
3671 EVP_CIPHER_iv_length(cipher), auth_tag_len);
3672 }
3673
3674
Init(const FunctionCallbackInfo<Value> & args)3675 void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
3676 CipherBase* cipher;
3677 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3678
3679 CHECK_GE(args.Length(), 3);
3680
3681 const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
3682 ArrayBufferViewContents<char> key_buf(args[1]);
3683
3684 // Don't assign to cipher->auth_tag_len_ directly; the value might not
3685 // represent a valid length at this point.
3686 unsigned int auth_tag_len;
3687 if (args[2]->IsUint32()) {
3688 auth_tag_len = args[2].As<Uint32>()->Value();
3689 } else {
3690 CHECK(args[2]->IsInt32() && args[2].As<Int32>()->Value() == -1);
3691 auth_tag_len = kNoAuthTagLength;
3692 }
3693
3694 cipher->Init(*cipher_type, key_buf.data(), key_buf.length(), auth_tag_len);
3695 }
3696
InitIv(const char * cipher_type,const unsigned char * key,int key_len,const unsigned char * iv,int iv_len,unsigned int auth_tag_len)3697 void CipherBase::InitIv(const char* cipher_type,
3698 const unsigned char* key,
3699 int key_len,
3700 const unsigned char* iv,
3701 int iv_len,
3702 unsigned int auth_tag_len) {
3703 HandleScope scope(env()->isolate());
3704 MarkPopErrorOnReturn mark_pop_error_on_return;
3705
3706 const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
3707 if (cipher == nullptr) {
3708 return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env());
3709 }
3710
3711 const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
3712 const bool is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
3713 const bool has_iv = iv_len >= 0;
3714
3715 // Throw if no IV was passed and the cipher requires an IV
3716 if (!has_iv && expected_iv_len != 0) {
3717 char msg[128];
3718 snprintf(msg, sizeof(msg), "Missing IV for cipher %s", cipher_type);
3719 return env()->ThrowError(msg);
3720 }
3721
3722 // Throw if an IV was passed which does not match the cipher's fixed IV length
3723 if (!is_authenticated_mode && has_iv && iv_len != expected_iv_len) {
3724 return env()->ThrowError("Invalid IV length");
3725 }
3726
3727 if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
3728 CHECK(has_iv);
3729 // Check for invalid IV lengths, since OpenSSL does not under some
3730 // conditions:
3731 // https://www.openssl.org/news/secadv/20190306.txt.
3732 if (iv_len > 12) {
3733 return env()->ThrowError("Invalid IV length");
3734 }
3735 }
3736
3737 CommonInit(cipher_type, cipher, key, key_len, iv, iv_len, auth_tag_len);
3738 }
3739
3740
GetSecretKeyBytes(Environment * env,Local<Value> value)3741 static ByteSource GetSecretKeyBytes(Environment* env, Local<Value> value) {
3742 // A key can be passed as a string, buffer or KeyObject with type 'secret'.
3743 // If it is a string, we need to convert it to a buffer. We are not doing that
3744 // in JS to avoid creating an unprotected copy on the heap.
3745 return value->IsString() || Buffer::HasInstance(value) ?
3746 ByteSource::FromStringOrBuffer(env, value) :
3747 ByteSource::FromSymmetricKeyObjectHandle(value);
3748 }
3749
InitIv(const FunctionCallbackInfo<Value> & args)3750 void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
3751 CipherBase* cipher;
3752 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3753 Environment* env = cipher->env();
3754
3755 CHECK_GE(args.Length(), 4);
3756
3757 const node::Utf8Value cipher_type(env->isolate(), args[0]);
3758 const ByteSource key = GetSecretKeyBytes(env, args[1]);
3759
3760 ArrayBufferViewContents<unsigned char> iv_buf;
3761 ssize_t iv_len = -1;
3762 if (!args[2]->IsNull()) {
3763 CHECK(args[2]->IsArrayBufferView());
3764 iv_buf.Read(args[2].As<ArrayBufferView>());
3765 iv_len = iv_buf.length();
3766 }
3767
3768 // Don't assign to cipher->auth_tag_len_ directly; the value might not
3769 // represent a valid length at this point.
3770 unsigned int auth_tag_len;
3771 if (args[3]->IsUint32()) {
3772 auth_tag_len = args[3].As<Uint32>()->Value();
3773 } else {
3774 CHECK(args[3]->IsInt32() && args[3].As<Int32>()->Value() == -1);
3775 auth_tag_len = kNoAuthTagLength;
3776 }
3777
3778 cipher->InitIv(*cipher_type,
3779 reinterpret_cast<const unsigned char*>(key.get()),
3780 key.size(),
3781 iv_buf.data(),
3782 static_cast<int>(iv_len),
3783 auth_tag_len);
3784 }
3785
3786
IsValidGCMTagLength(unsigned int tag_len)3787 static bool IsValidGCMTagLength(unsigned int tag_len) {
3788 return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
3789 }
3790
InitAuthenticated(const char * cipher_type,int iv_len,unsigned int auth_tag_len)3791 bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
3792 unsigned int auth_tag_len) {
3793 CHECK(IsAuthenticatedMode());
3794 MarkPopErrorOnReturn mark_pop_error_on_return;
3795
3796 if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
3797 EVP_CTRL_AEAD_SET_IVLEN,
3798 iv_len,
3799 nullptr)) {
3800 env()->ThrowError("Invalid IV length");
3801 return false;
3802 }
3803
3804 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
3805 if (mode == EVP_CIPH_GCM_MODE) {
3806 if (auth_tag_len != kNoAuthTagLength) {
3807 if (!IsValidGCMTagLength(auth_tag_len)) {
3808 char msg[50];
3809 snprintf(msg, sizeof(msg),
3810 "Invalid authentication tag length: %u", auth_tag_len);
3811 env()->ThrowError(msg);
3812 return false;
3813 }
3814
3815 // Remember the given authentication tag length for later.
3816 auth_tag_len_ = auth_tag_len;
3817 }
3818 } else {
3819 if (auth_tag_len == kNoAuthTagLength) {
3820 char msg[128];
3821 snprintf(msg, sizeof(msg), "authTagLength required for %s", cipher_type);
3822 env()->ThrowError(msg);
3823 return false;
3824 }
3825
3826 // TODO(tniessen) Support CCM decryption in FIPS mode
3827 if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) {
3828 env()->ThrowError("CCM decryption not supported in FIPS mode");
3829 return false;
3830 }
3831
3832 // Tell OpenSSL about the desired length.
3833 if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
3834 nullptr)) {
3835 env()->ThrowError("Invalid authentication tag length");
3836 return false;
3837 }
3838
3839 // Remember the given authentication tag length for later.
3840 auth_tag_len_ = auth_tag_len;
3841
3842 if (mode == EVP_CIPH_CCM_MODE) {
3843 // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
3844 CHECK(iv_len >= 7 && iv_len <= 13);
3845 max_message_size_ = INT_MAX;
3846 if (iv_len == 12) max_message_size_ = 16777215;
3847 if (iv_len == 13) max_message_size_ = 65535;
3848 }
3849 }
3850
3851 return true;
3852 }
3853
3854
CheckCCMMessageLength(int message_len)3855 bool CipherBase::CheckCCMMessageLength(int message_len) {
3856 CHECK(ctx_);
3857 CHECK(EVP_CIPHER_CTX_mode(ctx_.get()) == EVP_CIPH_CCM_MODE);
3858
3859 if (message_len > max_message_size_) {
3860 env()->ThrowError("Message exceeds maximum size");
3861 return false;
3862 }
3863
3864 return true;
3865 }
3866
3867
IsAuthenticatedMode() const3868 bool CipherBase::IsAuthenticatedMode() const {
3869 // Check if this cipher operates in an AEAD mode that we support.
3870 CHECK(ctx_);
3871 return IsSupportedAuthenticatedMode(ctx_.get());
3872 }
3873
3874
GetAuthTag(const FunctionCallbackInfo<Value> & args)3875 void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
3876 Environment* env = Environment::GetCurrent(args);
3877 CipherBase* cipher;
3878 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3879
3880 // Only callable after Final and if encrypting.
3881 if (cipher->ctx_ ||
3882 cipher->kind_ != kCipher ||
3883 cipher->auth_tag_len_ == kNoAuthTagLength) {
3884 return args.GetReturnValue().SetUndefined();
3885 }
3886
3887 Local<Object> buf =
3888 Buffer::Copy(env, cipher->auth_tag_, cipher->auth_tag_len_)
3889 .ToLocalChecked();
3890 args.GetReturnValue().Set(buf);
3891 }
3892
3893
SetAuthTag(const FunctionCallbackInfo<Value> & args)3894 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
3895 CipherBase* cipher;
3896 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3897
3898 if (!cipher->ctx_ ||
3899 !cipher->IsAuthenticatedMode() ||
3900 cipher->kind_ != kDecipher ||
3901 cipher->auth_tag_state_ != kAuthTagUnknown) {
3902 return args.GetReturnValue().Set(false);
3903 }
3904
3905 unsigned int tag_len = Buffer::Length(args[0]);
3906 const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get());
3907 bool is_valid;
3908 if (mode == EVP_CIPH_GCM_MODE) {
3909 // Restrict GCM tag lengths according to NIST 800-38d, page 9.
3910 is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
3911 cipher->auth_tag_len_ == tag_len) &&
3912 IsValidGCMTagLength(tag_len);
3913 } else {
3914 // At this point, the tag length is already known and must match the
3915 // length of the given authentication tag.
3916 CHECK(IsSupportedAuthenticatedMode(cipher->ctx_.get()));
3917 CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
3918 is_valid = cipher->auth_tag_len_ == tag_len;
3919 }
3920
3921 if (!is_valid) {
3922 char msg[50];
3923 snprintf(msg, sizeof(msg),
3924 "Invalid authentication tag length: %u", tag_len);
3925 return cipher->env()->ThrowError(msg);
3926 }
3927
3928 cipher->auth_tag_len_ = tag_len;
3929 cipher->auth_tag_state_ = kAuthTagKnown;
3930 CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
3931
3932 memset(cipher->auth_tag_, 0, sizeof(cipher->auth_tag_));
3933 args[0].As<ArrayBufferView>()->CopyContents(
3934 cipher->auth_tag_, cipher->auth_tag_len_);
3935
3936 args.GetReturnValue().Set(true);
3937 }
3938
3939
MaybePassAuthTagToOpenSSL()3940 bool CipherBase::MaybePassAuthTagToOpenSSL() {
3941 if (auth_tag_state_ == kAuthTagKnown) {
3942 if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
3943 EVP_CTRL_AEAD_SET_TAG,
3944 auth_tag_len_,
3945 reinterpret_cast<unsigned char*>(auth_tag_))) {
3946 return false;
3947 }
3948 auth_tag_state_ = kAuthTagPassedToOpenSSL;
3949 }
3950 return true;
3951 }
3952
3953
SetAAD(const char * data,unsigned int len,int plaintext_len)3954 bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
3955 if (!ctx_ || !IsAuthenticatedMode())
3956 return false;
3957 MarkPopErrorOnReturn mark_pop_error_on_return;
3958
3959 int outlen;
3960 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
3961
3962 // When in CCM mode, we need to set the authentication tag and the plaintext
3963 // length in advance.
3964 if (mode == EVP_CIPH_CCM_MODE) {
3965 if (plaintext_len < 0) {
3966 env()->ThrowError("plaintextLength required for CCM mode with AAD");
3967 return false;
3968 }
3969
3970 if (!CheckCCMMessageLength(plaintext_len))
3971 return false;
3972
3973 if (kind_ == kDecipher) {
3974 if (!MaybePassAuthTagToOpenSSL())
3975 return false;
3976 }
3977
3978 // Specify the plaintext length.
3979 if (!EVP_CipherUpdate(ctx_.get(), nullptr, &outlen, nullptr, plaintext_len))
3980 return false;
3981 }
3982
3983 return 1 == EVP_CipherUpdate(ctx_.get(),
3984 nullptr,
3985 &outlen,
3986 reinterpret_cast<const unsigned char*>(data),
3987 len);
3988 }
3989
3990
SetAAD(const FunctionCallbackInfo<Value> & args)3991 void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
3992 CipherBase* cipher;
3993 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3994
3995 CHECK_EQ(args.Length(), 2);
3996 CHECK(args[1]->IsInt32());
3997 int plaintext_len = args[1].As<Int32>()->Value();
3998 ArrayBufferViewContents<char> buf(args[0]);
3999
4000 bool b = cipher->SetAAD(buf.data(), buf.length(), plaintext_len);
4001 args.GetReturnValue().Set(b); // Possibly report invalid state failure
4002 }
4003
Update(const char * data,int len,AllocatedBuffer * out)4004 CipherBase::UpdateResult CipherBase::Update(const char* data,
4005 int len,
4006 AllocatedBuffer* out) {
4007 if (!ctx_)
4008 return kErrorState;
4009 MarkPopErrorOnReturn mark_pop_error_on_return;
4010
4011 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
4012
4013 if (mode == EVP_CIPH_CCM_MODE) {
4014 if (!CheckCCMMessageLength(len))
4015 return kErrorMessageSize;
4016 }
4017
4018 // Pass the authentication tag to OpenSSL if possible. This will only happen
4019 // once, usually on the first update.
4020 if (kind_ == kDecipher && IsAuthenticatedMode()) {
4021 CHECK(MaybePassAuthTagToOpenSSL());
4022 }
4023
4024 int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_.get());
4025 // For key wrapping algorithms, get output size by calling
4026 // EVP_CipherUpdate() with null output.
4027 if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE &&
4028 EVP_CipherUpdate(ctx_.get(),
4029 nullptr,
4030 &buf_len,
4031 reinterpret_cast<const unsigned char*>(data),
4032 len) != 1) {
4033 return kErrorState;
4034 }
4035
4036 *out = AllocatedBuffer::AllocateManaged(env(), buf_len);
4037 int r = EVP_CipherUpdate(ctx_.get(),
4038 reinterpret_cast<unsigned char*>(out->data()),
4039 &buf_len,
4040 reinterpret_cast<const unsigned char*>(data),
4041 len);
4042
4043 CHECK_LE(static_cast<size_t>(buf_len), out->size());
4044 out->Resize(buf_len);
4045
4046 // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
4047 // invalid. In that case, remember the error and throw in final().
4048 if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
4049 pending_auth_failed_ = true;
4050 return kSuccess;
4051 }
4052 return r == 1 ? kSuccess : kErrorState;
4053 }
4054
4055
Update(const FunctionCallbackInfo<Value> & args)4056 void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
4057 Decode<CipherBase>(args, [](CipherBase* cipher,
4058 const FunctionCallbackInfo<Value>& args,
4059 const char* data, size_t size) {
4060 AllocatedBuffer out;
4061 UpdateResult r = cipher->Update(data, size, &out);
4062
4063 if (r != kSuccess) {
4064 if (r == kErrorState) {
4065 Environment* env = Environment::GetCurrent(args);
4066 ThrowCryptoError(env, ERR_get_error(),
4067 "Trying to add data in unsupported state");
4068 }
4069 return;
4070 }
4071
4072 CHECK(out.data() != nullptr || out.size() == 0);
4073 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
4074 });
4075 }
4076
4077
SetAutoPadding(bool auto_padding)4078 bool CipherBase::SetAutoPadding(bool auto_padding) {
4079 if (!ctx_)
4080 return false;
4081 MarkPopErrorOnReturn mark_pop_error_on_return;
4082 return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
4083 }
4084
4085
SetAutoPadding(const FunctionCallbackInfo<Value> & args)4086 void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
4087 CipherBase* cipher;
4088 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
4089
4090 bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue());
4091 args.GetReturnValue().Set(b); // Possibly report invalid state failure
4092 }
4093
Final(AllocatedBuffer * out)4094 bool CipherBase::Final(AllocatedBuffer* out) {
4095 if (!ctx_)
4096 return false;
4097
4098 const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
4099
4100 *out = AllocatedBuffer::AllocateManaged(
4101 env(),
4102 static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_.get())));
4103
4104 if (kind_ == kDecipher && IsSupportedAuthenticatedMode(ctx_.get())) {
4105 MaybePassAuthTagToOpenSSL();
4106 }
4107
4108 // In CCM mode, final() only checks whether authentication failed in update().
4109 // EVP_CipherFinal_ex must not be called and will fail.
4110 bool ok;
4111 if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
4112 ok = !pending_auth_failed_;
4113 *out = AllocatedBuffer::AllocateManaged(env(), 0); // Empty buffer.
4114 } else {
4115 int out_len = out->size();
4116 ok = EVP_CipherFinal_ex(ctx_.get(),
4117 reinterpret_cast<unsigned char*>(out->data()),
4118 &out_len) == 1;
4119
4120 if (out_len >= 0)
4121 out->Resize(out_len);
4122 else
4123 *out = AllocatedBuffer(); // *out will not be used.
4124
4125 if (ok && kind_ == kCipher && IsAuthenticatedMode()) {
4126 // In GCM mode, the authentication tag length can be specified in advance,
4127 // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must
4128 // always be given by the user.
4129 if (auth_tag_len_ == kNoAuthTagLength) {
4130 CHECK(mode == EVP_CIPH_GCM_MODE);
4131 auth_tag_len_ = sizeof(auth_tag_);
4132 }
4133 CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
4134 auth_tag_len_,
4135 reinterpret_cast<unsigned char*>(auth_tag_)));
4136 }
4137 }
4138
4139 ctx_.reset();
4140
4141 return ok;
4142 }
4143
4144
Final(const FunctionCallbackInfo<Value> & args)4145 void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
4146 Environment* env = Environment::GetCurrent(args);
4147
4148 CipherBase* cipher;
4149 ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
4150 if (cipher->ctx_ == nullptr) return env->ThrowError("Unsupported state");
4151
4152 AllocatedBuffer out;
4153
4154 // Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
4155 const bool is_auth_mode = cipher->IsAuthenticatedMode();
4156 bool r = cipher->Final(&out);
4157
4158 if (!r) {
4159 const char* msg = is_auth_mode
4160 ? "Unsupported state or unable to authenticate data"
4161 : "Unsupported state";
4162
4163 return ThrowCryptoError(env, ERR_get_error(), msg);
4164 }
4165
4166 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
4167 }
4168
Hmac(Environment * env,Local<Object> wrap)4169 Hmac::Hmac(Environment* env, Local<Object> wrap)
4170 : BaseObject(env, wrap),
4171 ctx_(nullptr) {
4172 MakeWeak();
4173 }
4174
Initialize(Environment * env,Local<Object> target)4175 void Hmac::Initialize(Environment* env, Local<Object> target) {
4176 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4177
4178 t->InstanceTemplate()->SetInternalFieldCount(
4179 Hmac::kInternalFieldCount);
4180 t->Inherit(BaseObject::GetConstructorTemplate(env));
4181
4182 env->SetProtoMethod(t, "init", HmacInit);
4183 env->SetProtoMethod(t, "update", HmacUpdate);
4184 env->SetProtoMethod(t, "digest", HmacDigest);
4185
4186 target->Set(env->context(),
4187 FIXED_ONE_BYTE_STRING(env->isolate(), "Hmac"),
4188 t->GetFunction(env->context()).ToLocalChecked()).Check();
4189 }
4190
4191
New(const FunctionCallbackInfo<Value> & args)4192 void Hmac::New(const FunctionCallbackInfo<Value>& args) {
4193 Environment* env = Environment::GetCurrent(args);
4194 new Hmac(env, args.This());
4195 }
4196
4197
HmacInit(const char * hash_type,const char * key,int key_len)4198 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
4199 HandleScope scope(env()->isolate());
4200
4201 const EVP_MD* md = EVP_get_digestbyname(hash_type);
4202 if (md == nullptr) {
4203 return env()->ThrowError("Unknown message digest");
4204 }
4205 if (key_len == 0) {
4206 key = "";
4207 }
4208 ctx_.reset(HMAC_CTX_new());
4209 if (!ctx_ || !HMAC_Init_ex(ctx_.get(), key, key_len, md, nullptr)) {
4210 ctx_.reset();
4211 return ThrowCryptoError(env(), ERR_get_error());
4212 }
4213 }
4214
4215
HmacInit(const FunctionCallbackInfo<Value> & args)4216 void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
4217 Hmac* hmac;
4218 ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
4219 Environment* env = hmac->env();
4220
4221 const node::Utf8Value hash_type(env->isolate(), args[0]);
4222 ByteSource key = GetSecretKeyBytes(env, args[1]);
4223 hmac->HmacInit(*hash_type, key.get(), key.size());
4224 }
4225
4226
HmacUpdate(const char * data,int len)4227 bool Hmac::HmacUpdate(const char* data, int len) {
4228 if (!ctx_)
4229 return false;
4230 int r = HMAC_Update(ctx_.get(),
4231 reinterpret_cast<const unsigned char*>(data),
4232 len);
4233 return r == 1;
4234 }
4235
4236
HmacUpdate(const FunctionCallbackInfo<Value> & args)4237 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
4238 Decode<Hmac>(args, [](Hmac* hmac, const FunctionCallbackInfo<Value>& args,
4239 const char* data, size_t size) {
4240 bool r = hmac->HmacUpdate(data, size);
4241 args.GetReturnValue().Set(r);
4242 });
4243 }
4244
4245
HmacDigest(const FunctionCallbackInfo<Value> & args)4246 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
4247 Environment* env = Environment::GetCurrent(args);
4248
4249 Hmac* hmac;
4250 ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
4251
4252 enum encoding encoding = BUFFER;
4253 if (args.Length() >= 1) {
4254 encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
4255 }
4256
4257 unsigned char md_value[EVP_MAX_MD_SIZE];
4258 unsigned int md_len = 0;
4259
4260 if (hmac->ctx_) {
4261 HMAC_Final(hmac->ctx_.get(), md_value, &md_len);
4262 hmac->ctx_.reset();
4263 }
4264
4265 Local<Value> error;
4266 MaybeLocal<Value> rc =
4267 StringBytes::Encode(env->isolate(),
4268 reinterpret_cast<const char*>(md_value),
4269 md_len,
4270 encoding,
4271 &error);
4272 if (rc.IsEmpty()) {
4273 CHECK(!error.IsEmpty());
4274 env->isolate()->ThrowException(error);
4275 return;
4276 }
4277 args.GetReturnValue().Set(rc.ToLocalChecked());
4278 }
4279
Hash(Environment * env,Local<Object> wrap)4280 Hash::Hash(Environment* env, Local<Object> wrap)
4281 : BaseObject(env, wrap),
4282 mdctx_(nullptr),
4283 has_md_(false),
4284 md_value_(nullptr) {
4285 MakeWeak();
4286 }
4287
Initialize(Environment * env,Local<Object> target)4288 void Hash::Initialize(Environment* env, Local<Object> target) {
4289 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4290
4291 t->InstanceTemplate()->SetInternalFieldCount(
4292 Hash::kInternalFieldCount);
4293 t->Inherit(BaseObject::GetConstructorTemplate(env));
4294
4295 env->SetProtoMethod(t, "update", HashUpdate);
4296 env->SetProtoMethod(t, "digest", HashDigest);
4297
4298 target->Set(env->context(),
4299 FIXED_ONE_BYTE_STRING(env->isolate(), "Hash"),
4300 t->GetFunction(env->context()).ToLocalChecked()).Check();
4301 }
4302
~Hash()4303 Hash::~Hash() {
4304 if (md_value_ != nullptr)
4305 OPENSSL_clear_free(md_value_, md_len_);
4306 }
4307
New(const FunctionCallbackInfo<Value> & args)4308 void Hash::New(const FunctionCallbackInfo<Value>& args) {
4309 Environment* env = Environment::GetCurrent(args);
4310
4311 const Hash* orig = nullptr;
4312 const EVP_MD* md = nullptr;
4313
4314 if (args[0]->IsObject()) {
4315 ASSIGN_OR_RETURN_UNWRAP(&orig, args[0].As<Object>());
4316 md = EVP_MD_CTX_md(orig->mdctx_.get());
4317 } else {
4318 const node::Utf8Value hash_type(env->isolate(), args[0]);
4319 md = EVP_get_digestbyname(*hash_type);
4320 }
4321
4322 Maybe<unsigned int> xof_md_len = Nothing<unsigned int>();
4323 if (!args[1]->IsUndefined()) {
4324 CHECK(args[1]->IsUint32());
4325 xof_md_len = Just<unsigned int>(args[1].As<Uint32>()->Value());
4326 }
4327
4328 Hash* hash = new Hash(env, args.This());
4329 if (md == nullptr || !hash->HashInit(md, xof_md_len)) {
4330 return ThrowCryptoError(env, ERR_get_error(),
4331 "Digest method not supported");
4332 }
4333
4334 if (orig != nullptr &&
4335 0 >= EVP_MD_CTX_copy(hash->mdctx_.get(), orig->mdctx_.get())) {
4336 return ThrowCryptoError(env, ERR_get_error(), "Digest copy error");
4337 }
4338 }
4339
4340
HashInit(const EVP_MD * md,Maybe<unsigned int> xof_md_len)4341 bool Hash::HashInit(const EVP_MD* md, Maybe<unsigned int> xof_md_len) {
4342 mdctx_.reset(EVP_MD_CTX_new());
4343 if (!mdctx_ || EVP_DigestInit_ex(mdctx_.get(), md, nullptr) <= 0) {
4344 mdctx_.reset();
4345 return false;
4346 }
4347
4348 md_len_ = EVP_MD_size(md);
4349 if (xof_md_len.IsJust() && xof_md_len.FromJust() != md_len_) {
4350 // This is a little hack to cause createHash to fail when an incorrect
4351 // hashSize option was passed for a non-XOF hash function.
4352 if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) == 0) {
4353 EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
4354 return false;
4355 }
4356 md_len_ = xof_md_len.FromJust();
4357 }
4358
4359 return true;
4360 }
4361
4362
HashUpdate(const char * data,int len)4363 bool Hash::HashUpdate(const char* data, int len) {
4364 if (!mdctx_)
4365 return false;
4366 EVP_DigestUpdate(mdctx_.get(), data, len);
4367 return true;
4368 }
4369
4370
HashUpdate(const FunctionCallbackInfo<Value> & args)4371 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
4372 Decode<Hash>(args, [](Hash* hash, const FunctionCallbackInfo<Value>& args,
4373 const char* data, size_t size) {
4374 bool r = hash->HashUpdate(data, size);
4375 args.GetReturnValue().Set(r);
4376 });
4377 }
4378
4379
HashDigest(const FunctionCallbackInfo<Value> & args)4380 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
4381 Environment* env = Environment::GetCurrent(args);
4382
4383 Hash* hash;
4384 ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder());
4385
4386 enum encoding encoding = BUFFER;
4387 if (args.Length() >= 1) {
4388 encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
4389 }
4390
4391 // TODO(tniessen): SHA3_squeeze does not work for zero-length outputs on all
4392 // platforms and will cause a segmentation fault if called. This workaround
4393 // causes hash.digest() to correctly return an empty buffer / string.
4394 // See https://github.com/openssl/openssl/issues/9431.
4395 if (!hash->has_md_ && hash->md_len_ == 0) {
4396 hash->has_md_ = true;
4397 }
4398
4399 if (!hash->has_md_) {
4400 // Some hash algorithms such as SHA3 do not support calling
4401 // EVP_DigestFinal_ex more than once, however, Hash._flush
4402 // and Hash.digest can both be used to retrieve the digest,
4403 // so we need to cache it.
4404 // See https://github.com/nodejs/node/issues/28245.
4405
4406 hash->md_value_ = MallocOpenSSL<unsigned char>(hash->md_len_);
4407
4408 size_t default_len = EVP_MD_CTX_size(hash->mdctx_.get());
4409 int ret;
4410 if (hash->md_len_ == default_len) {
4411 ret = EVP_DigestFinal_ex(hash->mdctx_.get(), hash->md_value_,
4412 &hash->md_len_);
4413 } else {
4414 ret = EVP_DigestFinalXOF(hash->mdctx_.get(), hash->md_value_,
4415 hash->md_len_);
4416 }
4417
4418 if (ret != 1) {
4419 OPENSSL_free(hash->md_value_);
4420 hash->md_value_ = nullptr;
4421 return ThrowCryptoError(env, ERR_get_error());
4422 }
4423
4424 hash->has_md_ = true;
4425 }
4426
4427 Local<Value> error;
4428 MaybeLocal<Value> rc =
4429 StringBytes::Encode(env->isolate(),
4430 reinterpret_cast<const char*>(hash->md_value_),
4431 hash->md_len_,
4432 encoding,
4433 &error);
4434 if (rc.IsEmpty()) {
4435 CHECK(!error.IsEmpty());
4436 env->isolate()->ThrowException(error);
4437 return;
4438 }
4439 args.GetReturnValue().Set(rc.ToLocalChecked());
4440 }
4441
4442
Init(const char * sign_type)4443 SignBase::Error SignBase::Init(const char* sign_type) {
4444 CHECK_NULL(mdctx_);
4445 // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
4446 // exposed through the public API.
4447 if (strcmp(sign_type, "dss1") == 0 ||
4448 strcmp(sign_type, "DSS1") == 0) {
4449 sign_type = "SHA1";
4450 }
4451 const EVP_MD* md = EVP_get_digestbyname(sign_type);
4452 if (md == nullptr)
4453 return kSignUnknownDigest;
4454
4455 mdctx_.reset(EVP_MD_CTX_new());
4456 if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) {
4457 mdctx_.reset();
4458 return kSignInit;
4459 }
4460
4461 return kSignOk;
4462 }
4463
4464
Update(const char * data,int len)4465 SignBase::Error SignBase::Update(const char* data, int len) {
4466 if (mdctx_ == nullptr)
4467 return kSignNotInitialised;
4468 if (!EVP_DigestUpdate(mdctx_.get(), data, len))
4469 return kSignUpdate;
4470 return kSignOk;
4471 }
4472
4473
CheckThrow(Environment * env,SignBase::Error error)4474 void CheckThrow(Environment* env, SignBase::Error error) {
4475 HandleScope scope(env->isolate());
4476
4477 switch (error) {
4478 case SignBase::Error::kSignUnknownDigest:
4479 return env->ThrowError("Unknown message digest");
4480
4481 case SignBase::Error::kSignNotInitialised:
4482 return env->ThrowError("Not initialised");
4483
4484 case SignBase::Error::kSignMalformedSignature:
4485 return env->ThrowError("Malformed signature");
4486
4487 case SignBase::Error::kSignInit:
4488 case SignBase::Error::kSignUpdate:
4489 case SignBase::Error::kSignPrivateKey:
4490 case SignBase::Error::kSignPublicKey:
4491 {
4492 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
4493 if (err)
4494 return ThrowCryptoError(env, err);
4495 switch (error) {
4496 case SignBase::Error::kSignInit:
4497 return env->ThrowError("EVP_SignInit_ex failed");
4498 case SignBase::Error::kSignUpdate:
4499 return env->ThrowError("EVP_SignUpdate failed");
4500 case SignBase::Error::kSignPrivateKey:
4501 return env->ThrowError("PEM_read_bio_PrivateKey failed");
4502 case SignBase::Error::kSignPublicKey:
4503 return env->ThrowError("PEM_read_bio_PUBKEY failed");
4504 default:
4505 ABORT();
4506 }
4507 }
4508
4509 case SignBase::Error::kSignOk:
4510 return;
4511 }
4512 }
4513
SignBase(Environment * env,Local<Object> wrap)4514 SignBase::SignBase(Environment* env, Local<Object> wrap)
4515 : BaseObject(env, wrap) {
4516 }
4517
CheckThrow(SignBase::Error error)4518 void SignBase::CheckThrow(SignBase::Error error) {
4519 node::crypto::CheckThrow(env(), error);
4520 }
4521
ApplyRSAOptions(const ManagedEVPPKey & pkey,EVP_PKEY_CTX * pkctx,int padding,const Maybe<int> & salt_len)4522 static bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
4523 EVP_PKEY_CTX* pkctx,
4524 int padding,
4525 const Maybe<int>& salt_len) {
4526 if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
4527 EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
4528 EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
4529 if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
4530 return false;
4531 if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
4532 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0)
4533 return false;
4534 }
4535 }
4536
4537 return true;
4538 }
4539
4540
Sign(Environment * env,Local<Object> wrap)4541 Sign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) {
4542 MakeWeak();
4543 }
4544
Initialize(Environment * env,Local<Object> target)4545 void Sign::Initialize(Environment* env, Local<Object> target) {
4546 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4547
4548 t->InstanceTemplate()->SetInternalFieldCount(
4549 SignBase::kInternalFieldCount);
4550 t->Inherit(BaseObject::GetConstructorTemplate(env));
4551
4552 env->SetProtoMethod(t, "init", SignInit);
4553 env->SetProtoMethod(t, "update", SignUpdate);
4554 env->SetProtoMethod(t, "sign", SignFinal);
4555
4556 target->Set(env->context(),
4557 FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"),
4558 t->GetFunction(env->context()).ToLocalChecked()).Check();
4559 }
4560
4561
New(const FunctionCallbackInfo<Value> & args)4562 void Sign::New(const FunctionCallbackInfo<Value>& args) {
4563 Environment* env = Environment::GetCurrent(args);
4564 new Sign(env, args.This());
4565 }
4566
4567
SignInit(const FunctionCallbackInfo<Value> & args)4568 void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
4569 Sign* sign;
4570 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
4571
4572 const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
4573 sign->CheckThrow(sign->Init(*sign_type));
4574 }
4575
4576
SignUpdate(const FunctionCallbackInfo<Value> & args)4577 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
4578 Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args,
4579 const char* data, size_t size) {
4580 Error err = sign->Update(data, size);
4581 sign->CheckThrow(err);
4582 });
4583 }
4584
GetDefaultSignPadding(const ManagedEVPPKey & key)4585 static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
4586 return EVP_PKEY_id(key.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
4587 RSA_PKCS1_PADDING;
4588 }
4589
4590 static const unsigned int kNoDsaSignature = static_cast<unsigned int>(-1);
4591
4592 // Returns the maximum size of each of the integers (r, s) of the DSA signature.
GetBytesOfRS(const ManagedEVPPKey & pkey)4593 static unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
4594 int bits, base_id = EVP_PKEY_base_id(pkey.get());
4595
4596 if (base_id == EVP_PKEY_DSA) {
4597 DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get());
4598 // Both r and s are computed mod q, so their width is limited by that of q.
4599 bits = BN_num_bits(DSA_get0_q(dsa_key));
4600 } else if (base_id == EVP_PKEY_EC) {
4601 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
4602 const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
4603 bits = EC_GROUP_order_bits(ec_group);
4604 } else {
4605 return kNoDsaSignature;
4606 }
4607
4608 return (bits + 7) / 8;
4609 }
4610
ConvertSignatureToP1363(Environment * env,const ManagedEVPPKey & pkey,AllocatedBuffer && signature)4611 static AllocatedBuffer ConvertSignatureToP1363(Environment* env,
4612 const ManagedEVPPKey& pkey,
4613 AllocatedBuffer&& signature) {
4614 unsigned int n = GetBytesOfRS(pkey);
4615 if (n == kNoDsaSignature)
4616 return std::move(signature);
4617
4618 const unsigned char* sig_data =
4619 reinterpret_cast<unsigned char*>(signature.data());
4620
4621 ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, signature.size()));
4622 if (!asn1_sig)
4623 return AllocatedBuffer();
4624
4625 AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, 2 * n);
4626 unsigned char* data = reinterpret_cast<unsigned char*>(buf.data());
4627
4628 const BIGNUM* r = ECDSA_SIG_get0_r(asn1_sig.get());
4629 const BIGNUM* s = ECDSA_SIG_get0_s(asn1_sig.get());
4630 CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(r, data, n)));
4631 CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(s, data + n, n)));
4632
4633 return buf;
4634 }
4635
ConvertSignatureToDER(const ManagedEVPPKey & pkey,const ArrayBufferViewContents<char> & signature)4636 static ByteSource ConvertSignatureToDER(
4637 const ManagedEVPPKey& pkey,
4638 const ArrayBufferViewContents<char>& signature) {
4639 unsigned int n = GetBytesOfRS(pkey);
4640 if (n == kNoDsaSignature)
4641 return ByteSource::Foreign(signature.data(), signature.length());
4642
4643 const unsigned char* sig_data =
4644 reinterpret_cast<const unsigned char*>(signature.data());
4645
4646 if (signature.length() != 2 * n)
4647 return ByteSource();
4648
4649 ECDSASigPointer asn1_sig(ECDSA_SIG_new());
4650 CHECK(asn1_sig);
4651 BIGNUM* r = BN_new();
4652 CHECK_NOT_NULL(r);
4653 BIGNUM* s = BN_new();
4654 CHECK_NOT_NULL(s);
4655 CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
4656 CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
4657 CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
4658
4659 unsigned char* data = nullptr;
4660 int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
4661
4662 if (len <= 0)
4663 return ByteSource();
4664
4665 CHECK_NOT_NULL(data);
4666
4667 return ByteSource::Allocated(reinterpret_cast<char*>(data), len);
4668 }
4669
Node_SignFinal(Environment * env,EVPMDPointer && mdctx,const ManagedEVPPKey & pkey,int padding,Maybe<int> pss_salt_len)4670 static AllocatedBuffer Node_SignFinal(Environment* env,
4671 EVPMDPointer&& mdctx,
4672 const ManagedEVPPKey& pkey,
4673 int padding,
4674 Maybe<int> pss_salt_len) {
4675 unsigned char m[EVP_MAX_MD_SIZE];
4676 unsigned int m_len;
4677
4678 if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
4679 return AllocatedBuffer();
4680
4681 int signed_sig_len = EVP_PKEY_size(pkey.get());
4682 CHECK_GE(signed_sig_len, 0);
4683 size_t sig_len = static_cast<size_t>(signed_sig_len);
4684 AllocatedBuffer sig = AllocatedBuffer::AllocateManaged(env, sig_len);
4685
4686 EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
4687 if (pkctx &&
4688 EVP_PKEY_sign_init(pkctx.get()) > 0 &&
4689 ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
4690 EVP_PKEY_CTX_set_signature_md(pkctx.get(),
4691 EVP_MD_CTX_md(mdctx.get())) > 0 &&
4692 EVP_PKEY_sign(pkctx.get(),
4693 reinterpret_cast<unsigned char*>(sig.data()),
4694 &sig_len,
4695 m,
4696 m_len) > 0) {
4697 sig.Resize(sig_len);
4698 return sig;
4699 }
4700
4701 return AllocatedBuffer();
4702 }
4703
ValidateDSAParameters(EVP_PKEY * key)4704 static inline bool ValidateDSAParameters(EVP_PKEY* key) {
4705 /* Validate DSA2 parameters from FIPS 186-4 */
4706 if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
4707 DSA* dsa = EVP_PKEY_get0_DSA(key);
4708 const BIGNUM* p;
4709 DSA_get0_pqg(dsa, &p, nullptr, nullptr);
4710 size_t L = BN_num_bits(p);
4711 const BIGNUM* q;
4712 DSA_get0_pqg(dsa, nullptr, &q, nullptr);
4713 size_t N = BN_num_bits(q);
4714
4715 return (L == 1024 && N == 160) ||
4716 (L == 2048 && N == 224) ||
4717 (L == 2048 && N == 256) ||
4718 (L == 3072 && N == 256);
4719 }
4720
4721 return true;
4722 }
4723
SignFinal(const ManagedEVPPKey & pkey,int padding,const Maybe<int> & salt_len,DSASigEnc dsa_sig_enc)4724 Sign::SignResult Sign::SignFinal(
4725 const ManagedEVPPKey& pkey,
4726 int padding,
4727 const Maybe<int>& salt_len,
4728 DSASigEnc dsa_sig_enc) {
4729 if (!mdctx_)
4730 return SignResult(kSignNotInitialised);
4731
4732 EVPMDPointer mdctx = std::move(mdctx_);
4733
4734 if (!ValidateDSAParameters(pkey.get()))
4735 return SignResult(kSignPrivateKey);
4736
4737 AllocatedBuffer buffer =
4738 Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len);
4739 Error error = buffer.data() == nullptr ? kSignPrivateKey : kSignOk;
4740 if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
4741 buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
4742 CHECK_NOT_NULL(buffer.data());
4743 }
4744 return SignResult(error, std::move(buffer));
4745 }
4746
4747
SignFinal(const FunctionCallbackInfo<Value> & args)4748 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
4749 Sign* sign;
4750 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
4751
4752 ClearErrorOnReturn clear_error_on_return;
4753
4754 unsigned int offset = 0;
4755 ManagedEVPPKey key = GetPrivateKeyFromJs(args, &offset, true);
4756 if (!key)
4757 return;
4758
4759 int padding = GetDefaultSignPadding(key);
4760 if (!args[offset]->IsUndefined()) {
4761 CHECK(args[offset]->IsInt32());
4762 padding = args[offset].As<Int32>()->Value();
4763 }
4764
4765 Maybe<int> salt_len = Nothing<int>();
4766 if (!args[offset + 1]->IsUndefined()) {
4767 CHECK(args[offset + 1]->IsInt32());
4768 salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
4769 }
4770
4771 CHECK(args[offset + 2]->IsInt32());
4772 DSASigEnc dsa_sig_enc =
4773 static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value());
4774
4775 SignResult ret = sign->SignFinal(
4776 key,
4777 padding,
4778 salt_len,
4779 dsa_sig_enc);
4780
4781 if (ret.error != kSignOk)
4782 return sign->CheckThrow(ret.error);
4783
4784 args.GetReturnValue().Set(ret.signature.ToBuffer().ToLocalChecked());
4785 }
4786
SignOneShot(const FunctionCallbackInfo<Value> & args)4787 void SignOneShot(const FunctionCallbackInfo<Value>& args) {
4788 ClearErrorOnReturn clear_error_on_return;
4789 Environment* env = Environment::GetCurrent(args);
4790
4791 unsigned int offset = 0;
4792 ManagedEVPPKey key = GetPrivateKeyFromJs(args, &offset, true);
4793 if (!key)
4794 return;
4795
4796 if (!ValidateDSAParameters(key.get()))
4797 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4798
4799 ArrayBufferViewContents<char> data(args[offset]);
4800
4801 const EVP_MD* md;
4802 if (args[offset + 1]->IsNullOrUndefined()) {
4803 md = nullptr;
4804 } else {
4805 const node::Utf8Value sign_type(args.GetIsolate(), args[offset + 1]);
4806 md = EVP_get_digestbyname(*sign_type);
4807 if (md == nullptr)
4808 return CheckThrow(env, SignBase::Error::kSignUnknownDigest);
4809 }
4810
4811 int rsa_padding = GetDefaultSignPadding(key);
4812 if (!args[offset + 2]->IsUndefined()) {
4813 CHECK(args[offset + 2]->IsInt32());
4814 rsa_padding = args[offset + 2].As<Int32>()->Value();
4815 }
4816
4817 Maybe<int> rsa_salt_len = Nothing<int>();
4818 if (!args[offset + 3]->IsUndefined()) {
4819 CHECK(args[offset + 3]->IsInt32());
4820 rsa_salt_len = Just<int>(args[offset + 3].As<Int32>()->Value());
4821 }
4822
4823 CHECK(args[offset + 4]->IsInt32());
4824 DSASigEnc dsa_sig_enc =
4825 static_cast<DSASigEnc>(args[offset + 4].As<Int32>()->Value());
4826
4827 EVP_PKEY_CTX* pkctx = nullptr;
4828 EVPMDPointer mdctx(EVP_MD_CTX_new());
4829 if (!mdctx ||
4830 !EVP_DigestSignInit(mdctx.get(), &pkctx, md, nullptr, key.get())) {
4831 return CheckThrow(env, SignBase::Error::kSignInit);
4832 }
4833
4834 if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len))
4835 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4836
4837 const unsigned char* input =
4838 reinterpret_cast<const unsigned char*>(data.data());
4839 size_t sig_len;
4840 if (!EVP_DigestSign(mdctx.get(), nullptr, &sig_len, input, data.length()))
4841 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4842
4843 AllocatedBuffer signature = AllocatedBuffer::AllocateManaged(env, sig_len);
4844 if (!EVP_DigestSign(mdctx.get(),
4845 reinterpret_cast<unsigned char*>(signature.data()),
4846 &sig_len,
4847 input,
4848 data.length())) {
4849 return CheckThrow(env, SignBase::Error::kSignPrivateKey);
4850 }
4851
4852 signature.Resize(sig_len);
4853
4854 if (dsa_sig_enc == kSigEncP1363) {
4855 signature = ConvertSignatureToP1363(env, key, std::move(signature));
4856 }
4857
4858 args.GetReturnValue().Set(signature.ToBuffer().ToLocalChecked());
4859 }
4860
Verify(Environment * env,Local<Object> wrap)4861 Verify::Verify(Environment* env, Local<Object> wrap)
4862 : SignBase(env, wrap) {
4863 MakeWeak();
4864 }
4865
Initialize(Environment * env,Local<Object> target)4866 void Verify::Initialize(Environment* env, Local<Object> target) {
4867 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
4868
4869 t->InstanceTemplate()->SetInternalFieldCount(
4870 SignBase::kInternalFieldCount);
4871 t->Inherit(BaseObject::GetConstructorTemplate(env));
4872
4873 env->SetProtoMethod(t, "init", VerifyInit);
4874 env->SetProtoMethod(t, "update", VerifyUpdate);
4875 env->SetProtoMethod(t, "verify", VerifyFinal);
4876
4877 target->Set(env->context(),
4878 FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
4879 t->GetFunction(env->context()).ToLocalChecked()).Check();
4880 }
4881
4882
New(const FunctionCallbackInfo<Value> & args)4883 void Verify::New(const FunctionCallbackInfo<Value>& args) {
4884 Environment* env = Environment::GetCurrent(args);
4885 new Verify(env, args.This());
4886 }
4887
4888
VerifyInit(const FunctionCallbackInfo<Value> & args)4889 void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
4890 Verify* verify;
4891 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
4892
4893 const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
4894 verify->CheckThrow(verify->Init(*verify_type));
4895 }
4896
4897
VerifyUpdate(const FunctionCallbackInfo<Value> & args)4898 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
4899 Decode<Verify>(args, [](Verify* verify,
4900 const FunctionCallbackInfo<Value>& args,
4901 const char* data, size_t size) {
4902 Error err = verify->Update(data, size);
4903 verify->CheckThrow(err);
4904 });
4905 }
4906
4907
VerifyFinal(const ManagedEVPPKey & pkey,const ByteSource & sig,int padding,const Maybe<int> & saltlen,bool * verify_result)4908 SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey,
4909 const ByteSource& sig,
4910 int padding,
4911 const Maybe<int>& saltlen,
4912 bool* verify_result) {
4913 if (!mdctx_)
4914 return kSignNotInitialised;
4915
4916 unsigned char m[EVP_MAX_MD_SIZE];
4917 unsigned int m_len;
4918 *verify_result = false;
4919 EVPMDPointer mdctx = std::move(mdctx_);
4920
4921 if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
4922 return kSignPublicKey;
4923
4924 EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
4925 if (pkctx &&
4926 EVP_PKEY_verify_init(pkctx.get()) > 0 &&
4927 ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
4928 EVP_PKEY_CTX_set_signature_md(pkctx.get(),
4929 EVP_MD_CTX_md(mdctx.get())) > 0) {
4930 const unsigned char* s = reinterpret_cast<const unsigned char*>(sig.get());
4931 const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
4932 *verify_result = r == 1;
4933 }
4934
4935 return kSignOk;
4936 }
4937
4938
VerifyFinal(const FunctionCallbackInfo<Value> & args)4939 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
4940 ClearErrorOnReturn clear_error_on_return;
4941
4942 Verify* verify;
4943 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
4944
4945 unsigned int offset = 0;
4946 ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset);
4947 if (!pkey)
4948 return;
4949
4950 ArrayBufferViewContents<char> hbuf(args[offset]);
4951
4952 int padding = GetDefaultSignPadding(pkey);
4953 if (!args[offset + 1]->IsUndefined()) {
4954 CHECK(args[offset + 1]->IsInt32());
4955 padding = args[offset + 1].As<Int32>()->Value();
4956 }
4957
4958 Maybe<int> salt_len = Nothing<int>();
4959 if (!args[offset + 2]->IsUndefined()) {
4960 CHECK(args[offset + 2]->IsInt32());
4961 salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
4962 }
4963
4964 CHECK(args[offset + 3]->IsInt32());
4965 DSASigEnc dsa_sig_enc =
4966 static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value());
4967
4968 ByteSource signature = ByteSource::Foreign(hbuf.data(), hbuf.length());
4969 if (dsa_sig_enc == kSigEncP1363) {
4970 signature = ConvertSignatureToDER(pkey, hbuf);
4971 if (signature.get() == nullptr)
4972 return verify->CheckThrow(Error::kSignMalformedSignature);
4973 }
4974
4975 bool verify_result;
4976 Error err = verify->VerifyFinal(pkey, signature, padding,
4977 salt_len, &verify_result);
4978 if (err != kSignOk)
4979 return verify->CheckThrow(err);
4980 args.GetReturnValue().Set(verify_result);
4981 }
4982
VerifyOneShot(const FunctionCallbackInfo<Value> & args)4983 void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
4984 ClearErrorOnReturn clear_error_on_return;
4985 Environment* env = Environment::GetCurrent(args);
4986
4987 unsigned int offset = 0;
4988 ManagedEVPPKey key = GetPublicOrPrivateKeyFromJs(args, &offset);
4989 if (!key)
4990 return;
4991
4992 ArrayBufferViewContents<char> sig(args[offset]);
4993
4994 ArrayBufferViewContents<char> data(args[offset + 1]);
4995
4996 const EVP_MD* md;
4997 if (args[offset + 2]->IsNullOrUndefined()) {
4998 md = nullptr;
4999 } else {
5000 const node::Utf8Value sign_type(args.GetIsolate(), args[offset + 2]);
5001 md = EVP_get_digestbyname(*sign_type);
5002 if (md == nullptr)
5003 return CheckThrow(env, SignBase::Error::kSignUnknownDigest);
5004 }
5005
5006 int rsa_padding = GetDefaultSignPadding(key);
5007 if (!args[offset + 3]->IsUndefined()) {
5008 CHECK(args[offset + 3]->IsInt32());
5009 rsa_padding = args[offset + 3].As<Int32>()->Value();
5010 }
5011
5012 Maybe<int> rsa_salt_len = Nothing<int>();
5013 if (!args[offset + 4]->IsUndefined()) {
5014 CHECK(args[offset + 4]->IsInt32());
5015 rsa_salt_len = Just<int>(args[offset + 4].As<Int32>()->Value());
5016 }
5017
5018 CHECK(args[offset + 5]->IsInt32());
5019 DSASigEnc dsa_sig_enc =
5020 static_cast<DSASigEnc>(args[offset + 5].As<Int32>()->Value());
5021
5022 EVP_PKEY_CTX* pkctx = nullptr;
5023 EVPMDPointer mdctx(EVP_MD_CTX_new());
5024 if (!mdctx ||
5025 !EVP_DigestVerifyInit(mdctx.get(), &pkctx, md, nullptr, key.get())) {
5026 return CheckThrow(env, SignBase::Error::kSignInit);
5027 }
5028
5029 if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len))
5030 return CheckThrow(env, SignBase::Error::kSignPublicKey);
5031
5032 ByteSource sig_bytes = ByteSource::Foreign(sig.data(), sig.length());
5033 if (dsa_sig_enc == kSigEncP1363) {
5034 sig_bytes = ConvertSignatureToDER(key, sig);
5035 if (!sig_bytes)
5036 return CheckThrow(env, SignBase::Error::kSignMalformedSignature);
5037 }
5038
5039 bool verify_result;
5040 const int r = EVP_DigestVerify(
5041 mdctx.get(),
5042 reinterpret_cast<const unsigned char*>(sig_bytes.get()),
5043 sig_bytes.size(),
5044 reinterpret_cast<const unsigned char*>(data.data()),
5045 data.length());
5046 switch (r) {
5047 case 1:
5048 verify_result = true;
5049 break;
5050 case 0:
5051 verify_result = false;
5052 break;
5053 default:
5054 return CheckThrow(env, SignBase::Error::kSignPublicKey);
5055 }
5056
5057 args.GetReturnValue().Set(verify_result);
5058 }
5059
5060 template <PublicKeyCipher::Operation operation,
5061 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
5062 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
Cipher(Environment * env,const ManagedEVPPKey & pkey,int padding,const EVP_MD * digest,const void * oaep_label,size_t oaep_label_len,const unsigned char * data,int len,AllocatedBuffer * out)5063 bool PublicKeyCipher::Cipher(Environment* env,
5064 const ManagedEVPPKey& pkey,
5065 int padding,
5066 const EVP_MD* digest,
5067 const void* oaep_label,
5068 size_t oaep_label_len,
5069 const unsigned char* data,
5070 int len,
5071 AllocatedBuffer* out) {
5072 EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
5073 if (!ctx)
5074 return false;
5075 if (EVP_PKEY_cipher_init(ctx.get()) <= 0)
5076 return false;
5077 if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), padding) <= 0)
5078 return false;
5079
5080 if (digest != nullptr) {
5081 if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
5082 return false;
5083 }
5084
5085 if (oaep_label_len != 0) {
5086 // OpenSSL takes ownership of the label, so we need to create a copy.
5087 void* label = OPENSSL_memdup(oaep_label, oaep_label_len);
5088 CHECK_NOT_NULL(label);
5089 if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(),
5090 reinterpret_cast<unsigned char*>(label),
5091 oaep_label_len)) {
5092 OPENSSL_free(label);
5093 return false;
5094 }
5095 }
5096
5097 size_t out_len = 0;
5098 if (EVP_PKEY_cipher(ctx.get(), nullptr, &out_len, data, len) <= 0)
5099 return false;
5100
5101 *out = AllocatedBuffer::AllocateManaged(env, out_len);
5102
5103 if (EVP_PKEY_cipher(ctx.get(),
5104 reinterpret_cast<unsigned char*>(out->data()),
5105 &out_len,
5106 data,
5107 len) <= 0) {
5108 return false;
5109 }
5110
5111 out->Resize(out_len);
5112 return true;
5113 }
5114
5115
5116 template <PublicKeyCipher::Operation operation,
5117 PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
5118 PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
Cipher(const FunctionCallbackInfo<Value> & args)5119 void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
5120 MarkPopErrorOnReturn mark_pop_error_on_return;
5121 Environment* env = Environment::GetCurrent(args);
5122
5123 unsigned int offset = 0;
5124 ManagedEVPPKey pkey = GetPublicOrPrivateKeyFromJs(args, &offset);
5125 if (!pkey)
5126 return;
5127
5128 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[offset], "Data");
5129 ArrayBufferViewContents<unsigned char> buf(args[offset]);
5130
5131 uint32_t padding;
5132 if (!args[offset + 1]->Uint32Value(env->context()).To(&padding)) return;
5133
5134 const node::Utf8Value oaep_str(env->isolate(), args[offset + 2]);
5135 const char* oaep_hash = args[offset + 2]->IsString() ? *oaep_str : nullptr;
5136 const EVP_MD* digest = nullptr;
5137 if (oaep_hash != nullptr) {
5138 digest = EVP_get_digestbyname(oaep_hash);
5139 if (digest == nullptr)
5140 return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env);
5141 }
5142
5143 ArrayBufferViewContents<unsigned char> oaep_label;
5144 if (!args[offset + 3]->IsUndefined()) {
5145 CHECK(args[offset + 3]->IsArrayBufferView());
5146 oaep_label.Read(args[offset + 3].As<ArrayBufferView>());
5147 }
5148
5149 AllocatedBuffer out;
5150
5151 bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
5152 env,
5153 pkey,
5154 padding,
5155 digest,
5156 oaep_label.data(),
5157 oaep_label.length(),
5158 buf.data(),
5159 buf.length(),
5160 &out);
5161
5162 if (!r)
5163 return ThrowCryptoError(env, ERR_get_error());
5164
5165 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
5166 }
5167
DiffieHellman(Environment * env,Local<Object> wrap)5168 DiffieHellman::DiffieHellman(Environment* env, Local<Object> wrap)
5169 : BaseObject(env, wrap), verifyError_(0) {
5170 MakeWeak();
5171 }
5172
Initialize(Environment * env,Local<Object> target)5173 void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
5174 auto make = [&] (Local<String> name, FunctionCallback callback) {
5175 Local<FunctionTemplate> t = env->NewFunctionTemplate(callback);
5176
5177 const PropertyAttribute attributes =
5178 static_cast<PropertyAttribute>(ReadOnly | DontDelete);
5179
5180 t->InstanceTemplate()->SetInternalFieldCount(
5181 DiffieHellman::kInternalFieldCount);
5182 t->Inherit(BaseObject::GetConstructorTemplate(env));
5183
5184 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
5185 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
5186 env->SetProtoMethodNoSideEffect(t, "getPrime", GetPrime);
5187 env->SetProtoMethodNoSideEffect(t, "getGenerator", GetGenerator);
5188 env->SetProtoMethodNoSideEffect(t, "getPublicKey", GetPublicKey);
5189 env->SetProtoMethodNoSideEffect(t, "getPrivateKey", GetPrivateKey);
5190 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
5191 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
5192
5193 Local<FunctionTemplate> verify_error_getter_templ =
5194 FunctionTemplate::New(env->isolate(),
5195 DiffieHellman::VerifyErrorGetter,
5196 Local<Value>(),
5197 Signature::New(env->isolate(), t),
5198 /* length */ 0,
5199 ConstructorBehavior::kThrow,
5200 SideEffectType::kHasNoSideEffect);
5201
5202 t->InstanceTemplate()->SetAccessorProperty(
5203 env->verify_error_string(),
5204 verify_error_getter_templ,
5205 Local<FunctionTemplate>(),
5206 attributes);
5207
5208 target->Set(env->context(),
5209 name,
5210 t->GetFunction(env->context()).ToLocalChecked()).Check();
5211 };
5212
5213 make(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"), New);
5214 make(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
5215 DiffieHellmanGroup);
5216 }
5217
5218
Init(int primeLength,int g)5219 bool DiffieHellman::Init(int primeLength, int g) {
5220 dh_.reset(DH_new());
5221 if (!DH_generate_parameters_ex(dh_.get(), primeLength, g, nullptr))
5222 return false;
5223 return VerifyContext();
5224 }
5225
5226
Init(const char * p,int p_len,int g)5227 bool DiffieHellman::Init(const char* p, int p_len, int g) {
5228 dh_.reset(DH_new());
5229 if (p_len <= 0) {
5230 BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
5231 return false;
5232 }
5233 if (g <= 1) {
5234 DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5235 return false;
5236 }
5237 BIGNUM* bn_p =
5238 BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
5239 BIGNUM* bn_g = BN_new();
5240 if (!BN_set_word(bn_g, g) ||
5241 !DH_set0_pqg(dh_.get(), bn_p, nullptr, bn_g)) {
5242 BN_free(bn_p);
5243 BN_free(bn_g);
5244 return false;
5245 }
5246 return VerifyContext();
5247 }
5248
5249
Init(const char * p,int p_len,const char * g,int g_len)5250 bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
5251 dh_.reset(DH_new());
5252 if (p_len <= 0) {
5253 BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
5254 return false;
5255 }
5256 if (g_len <= 0) {
5257 DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5258 return false;
5259 }
5260 BIGNUM* bn_g =
5261 BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, nullptr);
5262 if (BN_is_zero(bn_g) || BN_is_one(bn_g)) {
5263 BN_free(bn_g);
5264 DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5265 return false;
5266 }
5267 BIGNUM* bn_p =
5268 BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
5269 if (!DH_set0_pqg(dh_.get(), bn_p, nullptr, bn_g)) {
5270 BN_free(bn_p);
5271 BN_free(bn_g);
5272 return false;
5273 }
5274 return VerifyContext();
5275 }
5276
FindDiffieHellmanGroup(const char * name)5277 inline const modp_group* FindDiffieHellmanGroup(const char* name) {
5278 for (const modp_group& group : modp_groups) {
5279 if (StringEqualNoCase(name, group.name))
5280 return &group;
5281 }
5282 return nullptr;
5283 }
5284
DiffieHellmanGroup(const FunctionCallbackInfo<Value> & args)5285 void DiffieHellman::DiffieHellmanGroup(
5286 const FunctionCallbackInfo<Value>& args) {
5287 Environment* env = Environment::GetCurrent(args);
5288 DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
5289
5290 CHECK_EQ(args.Length(), 1);
5291 THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "Group name");
5292
5293 bool initialized = false;
5294
5295 const node::Utf8Value group_name(env->isolate(), args[0]);
5296 const modp_group* group = FindDiffieHellmanGroup(*group_name);
5297 if (group == nullptr)
5298 return THROW_ERR_CRYPTO_UNKNOWN_DH_GROUP(env);
5299
5300 initialized = diffieHellman->Init(group->prime,
5301 group->prime_size,
5302 group->gen);
5303 if (!initialized)
5304 env->ThrowError("Initialization failed");
5305 }
5306
5307
New(const FunctionCallbackInfo<Value> & args)5308 void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
5309 Environment* env = Environment::GetCurrent(args);
5310 DiffieHellman* diffieHellman =
5311 new DiffieHellman(env, args.This());
5312 bool initialized = false;
5313
5314 if (args.Length() == 2) {
5315 if (args[0]->IsInt32()) {
5316 if (args[1]->IsInt32()) {
5317 initialized = diffieHellman->Init(args[0].As<Int32>()->Value(),
5318 args[1].As<Int32>()->Value());
5319 }
5320 } else {
5321 ArrayBufferViewContents<char> arg0(args[0]);
5322 if (args[1]->IsInt32()) {
5323 initialized = diffieHellman->Init(arg0.data(),
5324 arg0.length(),
5325 args[1].As<Int32>()->Value());
5326 } else {
5327 ArrayBufferViewContents<char> arg1(args[1]);
5328 initialized = diffieHellman->Init(arg0.data(), arg0.length(),
5329 arg1.data(), arg1.length());
5330 }
5331 }
5332 }
5333
5334 if (!initialized) {
5335 return ThrowCryptoError(env, ERR_get_error(), "Initialization failed");
5336 }
5337 }
5338
5339
GenerateKeys(const FunctionCallbackInfo<Value> & args)5340 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
5341 Environment* env = Environment::GetCurrent(args);
5342
5343 DiffieHellman* diffieHellman;
5344 ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
5345
5346 if (!DH_generate_key(diffieHellman->dh_.get())) {
5347 return ThrowCryptoError(env, ERR_get_error(), "Key generation failed");
5348 }
5349
5350 const BIGNUM* pub_key;
5351 DH_get0_key(diffieHellman->dh_.get(), &pub_key, nullptr);
5352 const int size = BN_num_bytes(pub_key);
5353 CHECK_GE(size, 0);
5354 AllocatedBuffer data = AllocatedBuffer::AllocateManaged(env, size);
5355 CHECK_EQ(size,
5356 BN_bn2binpad(
5357 pub_key, reinterpret_cast<unsigned char*>(data.data()), size));
5358 args.GetReturnValue().Set(data.ToBuffer().ToLocalChecked());
5359 }
5360
5361
GetField(const FunctionCallbackInfo<Value> & args,const BIGNUM * (* get_field)(const DH *),const char * err_if_null)5362 void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
5363 const BIGNUM* (*get_field)(const DH*),
5364 const char* err_if_null) {
5365 Environment* env = Environment::GetCurrent(args);
5366
5367 DiffieHellman* dh;
5368 ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder());
5369
5370 const BIGNUM* num = get_field(dh->dh_.get());
5371 if (num == nullptr) return env->ThrowError(err_if_null);
5372
5373 const int size = BN_num_bytes(num);
5374 CHECK_GE(size, 0);
5375 AllocatedBuffer data = AllocatedBuffer::AllocateManaged(env, size);
5376 CHECK_EQ(
5377 size,
5378 BN_bn2binpad(num, reinterpret_cast<unsigned char*>(data.data()), size));
5379 args.GetReturnValue().Set(data.ToBuffer().ToLocalChecked());
5380 }
5381
GetPrime(const FunctionCallbackInfo<Value> & args)5382 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
5383 GetField(args, [](const DH* dh) -> const BIGNUM* {
5384 const BIGNUM* p;
5385 DH_get0_pqg(dh, &p, nullptr, nullptr);
5386 return p;
5387 }, "p is null");
5388 }
5389
5390
GetGenerator(const FunctionCallbackInfo<Value> & args)5391 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
5392 GetField(args, [](const DH* dh) -> const BIGNUM* {
5393 const BIGNUM* g;
5394 DH_get0_pqg(dh, nullptr, nullptr, &g);
5395 return g;
5396 }, "g is null");
5397 }
5398
5399
GetPublicKey(const FunctionCallbackInfo<Value> & args)5400 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
5401 GetField(args, [](const DH* dh) -> const BIGNUM* {
5402 const BIGNUM* pub_key;
5403 DH_get0_key(dh, &pub_key, nullptr);
5404 return pub_key;
5405 }, "No public key - did you forget to generate one?");
5406 }
5407
5408
GetPrivateKey(const FunctionCallbackInfo<Value> & args)5409 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5410 GetField(args, [](const DH* dh) -> const BIGNUM* {
5411 const BIGNUM* priv_key;
5412 DH_get0_key(dh, nullptr, &priv_key);
5413 return priv_key;
5414 }, "No private key - did you forget to generate one?");
5415 }
5416
ZeroPadDiffieHellmanSecret(size_t remainder_size,AllocatedBuffer * ret)5417 static void ZeroPadDiffieHellmanSecret(size_t remainder_size,
5418 AllocatedBuffer* ret) {
5419 // DH_size returns number of bytes in a prime number.
5420 // DH_compute_key returns number of bytes in a remainder of exponent, which
5421 // may have less bytes than a prime number. Therefore add 0-padding to the
5422 // allocated buffer.
5423 const size_t prime_size = ret->size();
5424 if (remainder_size != prime_size) {
5425 CHECK_LT(remainder_size, prime_size);
5426 const size_t padding = prime_size - remainder_size;
5427 memmove(ret->data() + padding, ret->data(), remainder_size);
5428 memset(ret->data(), 0, padding);
5429 }
5430 }
5431
ComputeSecret(const FunctionCallbackInfo<Value> & args)5432 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
5433 Environment* env = Environment::GetCurrent(args);
5434
5435 DiffieHellman* diffieHellman;
5436 ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
5437
5438 ClearErrorOnReturn clear_error_on_return;
5439
5440 CHECK_EQ(args.Length(), 1);
5441 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Other party's public key");
5442 ArrayBufferViewContents<unsigned char> key_buf(args[0].As<ArrayBufferView>());
5443 BignumPointer key(BN_bin2bn(key_buf.data(), key_buf.length(), nullptr));
5444
5445 AllocatedBuffer ret =
5446 AllocatedBuffer::AllocateManaged(env, DH_size(diffieHellman->dh_.get()));
5447
5448 int size = DH_compute_key(reinterpret_cast<unsigned char*>(ret.data()),
5449 key.get(),
5450 diffieHellman->dh_.get());
5451
5452 if (size == -1) {
5453 int checkResult;
5454 int checked;
5455
5456 checked = DH_check_pub_key(diffieHellman->dh_.get(),
5457 key.get(),
5458 &checkResult);
5459
5460 if (!checked) {
5461 return ThrowCryptoError(env, ERR_get_error(), "Invalid Key");
5462 } else if (checkResult) {
5463 if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
5464 return env->ThrowError("Supplied key is too small");
5465 } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
5466 return env->ThrowError("Supplied key is too large");
5467 } else {
5468 return env->ThrowError("Invalid key");
5469 }
5470 } else {
5471 return env->ThrowError("Invalid key");
5472 }
5473
5474 UNREACHABLE();
5475 }
5476
5477 CHECK_GE(size, 0);
5478 ZeroPadDiffieHellmanSecret(static_cast<size_t>(size), &ret);
5479
5480 args.GetReturnValue().Set(ret.ToBuffer().ToLocalChecked());
5481 }
5482
SetKey(const FunctionCallbackInfo<Value> & args,int (* set_field)(DH *,BIGNUM *),const char * what)5483 void DiffieHellman::SetKey(const FunctionCallbackInfo<Value>& args,
5484 int (*set_field)(DH*, BIGNUM*), const char* what) {
5485 Environment* env = Environment::GetCurrent(args);
5486
5487 DiffieHellman* dh;
5488 ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder());
5489
5490 char errmsg[64];
5491
5492 CHECK_EQ(args.Length(), 1);
5493 if (!Buffer::HasInstance(args[0])) {
5494 snprintf(errmsg, sizeof(errmsg), "%s must be a buffer", what);
5495 return THROW_ERR_INVALID_ARG_TYPE(env, errmsg);
5496 }
5497
5498 ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>());
5499 BIGNUM* num =
5500 BN_bin2bn(buf.data(), buf.length(), nullptr);
5501 CHECK_NOT_NULL(num);
5502 CHECK_EQ(1, set_field(dh->dh_.get(), num));
5503 }
5504
5505
SetPublicKey(const FunctionCallbackInfo<Value> & args)5506 void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
5507 SetKey(args,
5508 [](DH* dh, BIGNUM* num) { return DH_set0_key(dh, num, nullptr); },
5509 "Public key");
5510 }
5511
SetPrivateKey(const FunctionCallbackInfo<Value> & args)5512 void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5513 SetKey(args,
5514 [](DH* dh, BIGNUM* num) { return DH_set0_key(dh, nullptr, num); },
5515 "Private key");
5516 }
5517
5518
VerifyErrorGetter(const FunctionCallbackInfo<Value> & args)5519 void DiffieHellman::VerifyErrorGetter(const FunctionCallbackInfo<Value>& args) {
5520 HandleScope scope(args.GetIsolate());
5521
5522 DiffieHellman* diffieHellman;
5523 ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
5524
5525 args.GetReturnValue().Set(diffieHellman->verifyError_);
5526 }
5527
5528
VerifyContext()5529 bool DiffieHellman::VerifyContext() {
5530 int codes;
5531 if (!DH_check(dh_.get(), &codes))
5532 return false;
5533 verifyError_ = codes;
5534 return true;
5535 }
5536
5537
Initialize(Environment * env,Local<Object> target)5538 void ECDH::Initialize(Environment* env, Local<Object> target) {
5539 HandleScope scope(env->isolate());
5540
5541 Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
5542 t->Inherit(BaseObject::GetConstructorTemplate(env));
5543
5544 t->InstanceTemplate()->SetInternalFieldCount(ECDH::kInternalFieldCount);
5545
5546 env->SetProtoMethod(t, "generateKeys", GenerateKeys);
5547 env->SetProtoMethod(t, "computeSecret", ComputeSecret);
5548 env->SetProtoMethodNoSideEffect(t, "getPublicKey", GetPublicKey);
5549 env->SetProtoMethodNoSideEffect(t, "getPrivateKey", GetPrivateKey);
5550 env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
5551 env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
5552
5553 target->Set(env->context(),
5554 FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"),
5555 t->GetFunction(env->context()).ToLocalChecked()).Check();
5556 }
5557
ECDH(Environment * env,Local<Object> wrap,ECKeyPointer && key)5558 ECDH::ECDH(Environment* env, Local<Object> wrap, ECKeyPointer&& key)
5559 : BaseObject(env, wrap),
5560 key_(std::move(key)),
5561 group_(EC_KEY_get0_group(key_.get())) {
5562 MakeWeak();
5563 CHECK_NOT_NULL(group_);
5564 }
5565
~ECDH()5566 ECDH::~ECDH() {}
5567
New(const FunctionCallbackInfo<Value> & args)5568 void ECDH::New(const FunctionCallbackInfo<Value>& args) {
5569 Environment* env = Environment::GetCurrent(args);
5570
5571 MarkPopErrorOnReturn mark_pop_error_on_return;
5572
5573 // TODO(indutny): Support raw curves?
5574 CHECK(args[0]->IsString());
5575 node::Utf8Value curve(env->isolate(), args[0]);
5576
5577 int nid = OBJ_sn2nid(*curve);
5578 if (nid == NID_undef)
5579 return THROW_ERR_INVALID_ARG_VALUE(env,
5580 "First argument should be a valid curve name");
5581
5582 ECKeyPointer key(EC_KEY_new_by_curve_name(nid));
5583 if (!key)
5584 return env->ThrowError("Failed to create EC_KEY using curve name");
5585
5586 new ECDH(env, args.This(), std::move(key));
5587 }
5588
5589
GenerateKeys(const FunctionCallbackInfo<Value> & args)5590 void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
5591 Environment* env = Environment::GetCurrent(args);
5592
5593 ECDH* ecdh;
5594 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5595
5596 if (!EC_KEY_generate_key(ecdh->key_.get()))
5597 return env->ThrowError("Failed to generate EC_KEY");
5598 }
5599
5600
BufferToPoint(Environment * env,const EC_GROUP * group,Local<Value> buf)5601 ECPointPointer ECDH::BufferToPoint(Environment* env,
5602 const EC_GROUP* group,
5603 Local<Value> buf) {
5604 int r;
5605
5606 ECPointPointer pub(EC_POINT_new(group));
5607 if (!pub) {
5608 env->ThrowError("Failed to allocate EC_POINT for a public key");
5609 return pub;
5610 }
5611
5612 ArrayBufferViewContents<unsigned char> input(buf);
5613 r = EC_POINT_oct2point(
5614 group,
5615 pub.get(),
5616 input.data(),
5617 input.length(),
5618 nullptr);
5619 if (!r)
5620 return ECPointPointer();
5621
5622 return pub;
5623 }
5624
5625
ComputeSecret(const FunctionCallbackInfo<Value> & args)5626 void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
5627 Environment* env = Environment::GetCurrent(args);
5628
5629 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Data");
5630
5631 ECDH* ecdh;
5632 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5633
5634 MarkPopErrorOnReturn mark_pop_error_on_return;
5635
5636 if (!ecdh->IsKeyPairValid())
5637 return env->ThrowError("Invalid key pair");
5638
5639 ECPointPointer pub(
5640 ECDH::BufferToPoint(env,
5641 ecdh->group_,
5642 args[0]));
5643 if (!pub) {
5644 args.GetReturnValue().Set(
5645 FIXED_ONE_BYTE_STRING(env->isolate(),
5646 "ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY"));
5647 return;
5648 }
5649
5650 // NOTE: field_size is in bits
5651 int field_size = EC_GROUP_get_degree(ecdh->group_);
5652 size_t out_len = (field_size + 7) / 8;
5653 AllocatedBuffer out = AllocatedBuffer::AllocateManaged(env, out_len);
5654
5655 int r = ECDH_compute_key(
5656 out.data(), out_len, pub.get(), ecdh->key_.get(), nullptr);
5657 if (!r)
5658 return env->ThrowError("Failed to compute ECDH key");
5659
5660 Local<Object> buf = out.ToBuffer().ToLocalChecked();
5661 args.GetReturnValue().Set(buf);
5662 }
5663
5664
GetPublicKey(const FunctionCallbackInfo<Value> & args)5665 void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
5666 Environment* env = Environment::GetCurrent(args);
5667
5668 // Conversion form
5669 CHECK_EQ(args.Length(), 1);
5670
5671 ECDH* ecdh;
5672 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5673
5674 const EC_GROUP* group = EC_KEY_get0_group(ecdh->key_.get());
5675 const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_.get());
5676 if (pub == nullptr)
5677 return env->ThrowError("Failed to get ECDH public key");
5678
5679 CHECK(args[0]->IsUint32());
5680 uint32_t val = args[0].As<Uint32>()->Value();
5681 point_conversion_form_t form = static_cast<point_conversion_form_t>(val);
5682
5683 const char* error;
5684 Local<Object> buf;
5685 if (!ECPointToBuffer(env, group, pub, form, &error).ToLocal(&buf))
5686 return env->ThrowError(error);
5687 args.GetReturnValue().Set(buf);
5688 }
5689
5690
GetPrivateKey(const FunctionCallbackInfo<Value> & args)5691 void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5692 Environment* env = Environment::GetCurrent(args);
5693
5694 ECDH* ecdh;
5695 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5696
5697 const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_.get());
5698 if (b == nullptr)
5699 return env->ThrowError("Failed to get ECDH private key");
5700
5701 const int size = BN_num_bytes(b);
5702 AllocatedBuffer out = AllocatedBuffer::AllocateManaged(env, size);
5703 CHECK_EQ(size, BN_bn2binpad(b,
5704 reinterpret_cast<unsigned char*>(out.data()),
5705 size));
5706
5707 Local<Object> buf = out.ToBuffer().ToLocalChecked();
5708 args.GetReturnValue().Set(buf);
5709 }
5710
5711
SetPrivateKey(const FunctionCallbackInfo<Value> & args)5712 void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
5713 Environment* env = Environment::GetCurrent(args);
5714
5715 ECDH* ecdh;
5716 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5717
5718 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Private key");
5719 ArrayBufferViewContents<unsigned char> priv_buffer(args[0]);
5720
5721 BignumPointer priv(BN_bin2bn(
5722 priv_buffer.data(), priv_buffer.length(), nullptr));
5723 if (!priv)
5724 return env->ThrowError("Failed to convert Buffer to BN");
5725
5726 if (!ecdh->IsKeyValidForCurve(priv)) {
5727 return env->ThrowError("Private key is not valid for specified curve.");
5728 }
5729
5730 ECKeyPointer new_key(EC_KEY_dup(ecdh->key_.get()));
5731 CHECK(new_key);
5732
5733 int result = EC_KEY_set_private_key(new_key.get(), priv.get());
5734 priv.reset();
5735
5736 if (!result) {
5737 return env->ThrowError("Failed to convert BN to a private key");
5738 }
5739
5740 MarkPopErrorOnReturn mark_pop_error_on_return;
5741 USE(&mark_pop_error_on_return);
5742
5743 const BIGNUM* priv_key = EC_KEY_get0_private_key(new_key.get());
5744 CHECK_NOT_NULL(priv_key);
5745
5746 ECPointPointer pub(EC_POINT_new(ecdh->group_));
5747 CHECK(pub);
5748
5749 if (!EC_POINT_mul(ecdh->group_, pub.get(), priv_key,
5750 nullptr, nullptr, nullptr)) {
5751 return env->ThrowError("Failed to generate ECDH public key");
5752 }
5753
5754 if (!EC_KEY_set_public_key(new_key.get(), pub.get()))
5755 return env->ThrowError("Failed to set generated public key");
5756
5757 EC_KEY_copy(ecdh->key_.get(), new_key.get());
5758 ecdh->group_ = EC_KEY_get0_group(ecdh->key_.get());
5759 }
5760
5761
SetPublicKey(const FunctionCallbackInfo<Value> & args)5762 void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
5763 Environment* env = Environment::GetCurrent(args);
5764
5765 ECDH* ecdh;
5766 ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
5767
5768 THROW_AND_RETURN_IF_NOT_BUFFER(env, args[0], "Public key");
5769
5770 MarkPopErrorOnReturn mark_pop_error_on_return;
5771
5772 ECPointPointer pub(
5773 ECDH::BufferToPoint(env,
5774 ecdh->group_,
5775 args[0]));
5776 if (!pub)
5777 return env->ThrowError("Failed to convert Buffer to EC_POINT");
5778
5779 int r = EC_KEY_set_public_key(ecdh->key_.get(), pub.get());
5780 if (!r)
5781 return env->ThrowError("Failed to set EC_POINT as the public key");
5782 }
5783
5784
IsKeyValidForCurve(const BignumPointer & private_key)5785 bool ECDH::IsKeyValidForCurve(const BignumPointer& private_key) {
5786 CHECK(group_);
5787 CHECK(private_key);
5788 // Private keys must be in the range [1, n-1].
5789 // Ref: Section 3.2.1 - http://www.secg.org/sec1-v2.pdf
5790 if (BN_cmp(private_key.get(), BN_value_one()) < 0) {
5791 return false;
5792 }
5793 BignumPointer order(BN_new());
5794 CHECK(order);
5795 return EC_GROUP_get_order(group_, order.get(), nullptr) &&
5796 BN_cmp(private_key.get(), order.get()) < 0;
5797 }
5798
5799
IsKeyPairValid()5800 bool ECDH::IsKeyPairValid() {
5801 MarkPopErrorOnReturn mark_pop_error_on_return;
5802 USE(&mark_pop_error_on_return);
5803 return 1 == EC_KEY_check_key(key_.get());
5804 }
5805
5806
5807 // TODO(addaleax): If there is an `AsyncWrap`, it currently has no access to
5808 // this object. This makes proper reporting of memory usage impossible.
5809 struct CryptoJob : public ThreadPoolWork {
5810 std::unique_ptr<AsyncWrap> async_wrap;
CryptoJobnode::crypto::CryptoJob5811 inline explicit CryptoJob(Environment* env) : ThreadPoolWork(env) {}
5812 inline void AfterThreadPoolWork(int status) final;
5813 virtual void AfterThreadPoolWork() = 0;
5814 static inline void Run(std::unique_ptr<CryptoJob> job, Local<Value> wrap);
5815 };
5816
5817
AfterThreadPoolWork(int status)5818 void CryptoJob::AfterThreadPoolWork(int status) {
5819 CHECK(status == 0 || status == UV_ECANCELED);
5820 std::unique_ptr<CryptoJob> job(this);
5821 if (status == UV_ECANCELED) return;
5822 HandleScope handle_scope(env()->isolate());
5823 Context::Scope context_scope(env()->context());
5824 CHECK_EQ(false, async_wrap->persistent().IsWeak());
5825 AfterThreadPoolWork();
5826 }
5827
5828
Run(std::unique_ptr<CryptoJob> job,Local<Value> wrap)5829 void CryptoJob::Run(std::unique_ptr<CryptoJob> job, Local<Value> wrap) {
5830 CHECK(wrap->IsObject());
5831 CHECK_NULL(job->async_wrap);
5832 job->async_wrap.reset(Unwrap<AsyncWrap>(wrap.As<Object>()));
5833 CHECK_EQ(false, job->async_wrap->persistent().IsWeak());
5834 job->ScheduleWork();
5835 job.release(); // Run free, little job!
5836 }
5837
5838
CopyBuffer(Local<Value> buf,std::vector<char> * vec)5839 inline void CopyBuffer(Local<Value> buf, std::vector<char>* vec) {
5840 CHECK(buf->IsArrayBufferView());
5841 vec->clear();
5842 vec->resize(buf.As<ArrayBufferView>()->ByteLength());
5843 buf.As<ArrayBufferView>()->CopyContents(vec->data(), vec->size());
5844 }
5845
5846
5847 struct RandomBytesJob : public CryptoJob {
5848 unsigned char* data;
5849 size_t size;
5850 CryptoErrorVector errors;
5851 Maybe<int> rc;
5852
RandomBytesJobnode::crypto::RandomBytesJob5853 inline explicit RandomBytesJob(Environment* env)
5854 : CryptoJob(env), rc(Nothing<int>()) {}
5855
DoThreadPoolWorknode::crypto::RandomBytesJob5856 inline void DoThreadPoolWork() override {
5857 CheckEntropy(); // Ensure that OpenSSL's PRNG is properly seeded.
5858 rc = Just(RAND_bytes(data, size));
5859 if (0 == rc.FromJust()) errors.Capture();
5860 }
5861
AfterThreadPoolWorknode::crypto::RandomBytesJob5862 inline void AfterThreadPoolWork() override {
5863 Local<Value> arg = ToResult();
5864 async_wrap->MakeCallback(env()->ondone_string(), 1, &arg);
5865 }
5866
ToResultnode::crypto::RandomBytesJob5867 inline Local<Value> ToResult() const {
5868 if (errors.empty()) return Undefined(env()->isolate());
5869 return errors.ToException(env()).ToLocalChecked();
5870 }
5871 };
5872
5873
RandomBytes(const FunctionCallbackInfo<Value> & args)5874 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
5875 CHECK(args[0]->IsArrayBufferView()); // buffer; wrap object retains ref.
5876 CHECK(args[1]->IsUint32()); // offset
5877 CHECK(args[2]->IsUint32()); // size
5878 CHECK(args[3]->IsObject() || args[3]->IsUndefined()); // wrap object
5879 const uint32_t offset = args[1].As<Uint32>()->Value();
5880 const uint32_t size = args[2].As<Uint32>()->Value();
5881 CHECK_GE(offset + size, offset); // Overflow check.
5882 CHECK_LE(offset + size, Buffer::Length(args[0])); // Bounds check.
5883 Environment* env = Environment::GetCurrent(args);
5884 std::unique_ptr<RandomBytesJob> job(new RandomBytesJob(env));
5885 job->data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0])) + offset;
5886 job->size = size;
5887 if (args[3]->IsObject()) return RandomBytesJob::Run(std::move(job), args[3]);
5888 env->PrintSyncTrace();
5889 job->DoThreadPoolWork();
5890 args.GetReturnValue().Set(job->ToResult());
5891 }
5892
5893
5894 struct PBKDF2Job : public CryptoJob {
5895 unsigned char* keybuf_data;
5896 size_t keybuf_size;
5897 std::vector<char> pass;
5898 std::vector<char> salt;
5899 uint32_t iteration_count;
5900 const EVP_MD* digest;
5901 Maybe<bool> success;
5902
PBKDF2Jobnode::crypto::PBKDF2Job5903 inline explicit PBKDF2Job(Environment* env)
5904 : CryptoJob(env), success(Nothing<bool>()) {}
5905
~PBKDF2Jobnode::crypto::PBKDF2Job5906 inline ~PBKDF2Job() override {
5907 Cleanse();
5908 }
5909
DoThreadPoolWorknode::crypto::PBKDF2Job5910 inline void DoThreadPoolWork() override {
5911 auto salt_data = reinterpret_cast<const unsigned char*>(salt.data());
5912 const bool ok =
5913 PKCS5_PBKDF2_HMAC(pass.data(), pass.size(), salt_data, salt.size(),
5914 iteration_count, digest, keybuf_size, keybuf_data);
5915 success = Just(ok);
5916 Cleanse();
5917 }
5918
AfterThreadPoolWorknode::crypto::PBKDF2Job5919 inline void AfterThreadPoolWork() override {
5920 Local<Value> arg = ToResult();
5921 async_wrap->MakeCallback(env()->ondone_string(), 1, &arg);
5922 }
5923
ToResultnode::crypto::PBKDF2Job5924 inline Local<Value> ToResult() const {
5925 return Boolean::New(env()->isolate(), success.FromJust());
5926 }
5927
Cleansenode::crypto::PBKDF2Job5928 inline void Cleanse() {
5929 OPENSSL_cleanse(pass.data(), pass.size());
5930 OPENSSL_cleanse(salt.data(), salt.size());
5931 pass.clear();
5932 salt.clear();
5933 }
5934 };
5935
5936
PBKDF2(const FunctionCallbackInfo<Value> & args)5937 inline void PBKDF2(const FunctionCallbackInfo<Value>& args) {
5938 auto rv = args.GetReturnValue();
5939 Environment* env = Environment::GetCurrent(args);
5940 CHECK(args[0]->IsArrayBufferView()); // keybuf; wrap object retains ref.
5941 CHECK(args[1]->IsArrayBufferView()); // pass
5942 CHECK(args[2]->IsArrayBufferView()); // salt
5943 CHECK(args[3]->IsUint32()); // iteration_count
5944 CHECK(args[4]->IsString()); // digest_name
5945 CHECK(args[5]->IsObject() || args[5]->IsUndefined()); // wrap object
5946 std::unique_ptr<PBKDF2Job> job(new PBKDF2Job(env));
5947 job->keybuf_data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0]));
5948 job->keybuf_size = Buffer::Length(args[0]);
5949 CopyBuffer(args[1], &job->pass);
5950 CopyBuffer(args[2], &job->salt);
5951 job->iteration_count = args[3].As<Uint32>()->Value();
5952 Utf8Value digest_name(args.GetIsolate(), args[4]);
5953 job->digest = EVP_get_digestbyname(*digest_name);
5954 if (job->digest == nullptr) return rv.Set(-1);
5955 if (args[5]->IsObject()) return PBKDF2Job::Run(std::move(job), args[5]);
5956 env->PrintSyncTrace();
5957 job->DoThreadPoolWork();
5958 rv.Set(job->ToResult());
5959 }
5960
5961
5962 #ifndef OPENSSL_NO_SCRYPT
5963 struct ScryptJob : public CryptoJob {
5964 unsigned char* keybuf_data;
5965 size_t keybuf_size;
5966 std::vector<char> pass;
5967 std::vector<char> salt;
5968 uint32_t N;
5969 uint32_t r;
5970 uint32_t p;
5971 uint64_t maxmem;
5972 CryptoErrorVector errors;
5973
ScryptJobnode::crypto::ScryptJob5974 inline explicit ScryptJob(Environment* env) : CryptoJob(env) {}
5975
~ScryptJobnode::crypto::ScryptJob5976 inline ~ScryptJob() override {
5977 Cleanse();
5978 }
5979
Validatenode::crypto::ScryptJob5980 inline bool Validate() {
5981 if (1 == EVP_PBE_scrypt(nullptr, 0, nullptr, 0, N, r, p, maxmem,
5982 nullptr, 0)) {
5983 return true;
5984 } else {
5985 // Note: EVP_PBE_scrypt() does not always put errors on the error stack.
5986 errors.Capture();
5987 return false;
5988 }
5989 }
5990
DoThreadPoolWorknode::crypto::ScryptJob5991 inline void DoThreadPoolWork() override {
5992 auto salt_data = reinterpret_cast<const unsigned char*>(salt.data());
5993 if (1 != EVP_PBE_scrypt(pass.data(), pass.size(), salt_data, salt.size(),
5994 N, r, p, maxmem, keybuf_data, keybuf_size)) {
5995 errors.Capture();
5996 }
5997 }
5998
AfterThreadPoolWorknode::crypto::ScryptJob5999 inline void AfterThreadPoolWork() override {
6000 Local<Value> arg = ToResult();
6001 async_wrap->MakeCallback(env()->ondone_string(), 1, &arg);
6002 }
6003
ToResultnode::crypto::ScryptJob6004 inline Local<Value> ToResult() const {
6005 if (errors.empty()) return Undefined(env()->isolate());
6006 return errors.ToException(env()).ToLocalChecked();
6007 }
6008
Cleansenode::crypto::ScryptJob6009 inline void Cleanse() {
6010 OPENSSL_cleanse(pass.data(), pass.size());
6011 OPENSSL_cleanse(salt.data(), salt.size());
6012 pass.clear();
6013 salt.clear();
6014 }
6015 };
6016
6017
Scrypt(const FunctionCallbackInfo<Value> & args)6018 void Scrypt(const FunctionCallbackInfo<Value>& args) {
6019 Environment* env = Environment::GetCurrent(args);
6020 CHECK(args[0]->IsArrayBufferView()); // keybuf; wrap object retains ref.
6021 CHECK(args[1]->IsArrayBufferView()); // pass
6022 CHECK(args[2]->IsArrayBufferView()); // salt
6023 CHECK(args[3]->IsUint32()); // N
6024 CHECK(args[4]->IsUint32()); // r
6025 CHECK(args[5]->IsUint32()); // p
6026 CHECK(args[6]->IsNumber()); // maxmem
6027 CHECK(args[7]->IsObject() || args[7]->IsUndefined()); // wrap object
6028 std::unique_ptr<ScryptJob> job(new ScryptJob(env));
6029 job->keybuf_data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0]));
6030 job->keybuf_size = Buffer::Length(args[0]);
6031 CopyBuffer(args[1], &job->pass);
6032 CopyBuffer(args[2], &job->salt);
6033 job->N = args[3].As<Uint32>()->Value();
6034 job->r = args[4].As<Uint32>()->Value();
6035 job->p = args[5].As<Uint32>()->Value();
6036 Local<Context> ctx = env->isolate()->GetCurrentContext();
6037 job->maxmem = static_cast<uint64_t>(args[6]->IntegerValue(ctx).ToChecked());
6038 if (!job->Validate()) {
6039 // EVP_PBE_scrypt() does not always put errors on the error stack
6040 // and therefore ToResult() may or may not return an exception
6041 // object. Return a sentinel value to inform JS land it should
6042 // throw an ERR_CRYPTO_SCRYPT_INVALID_PARAMETER on our behalf.
6043 auto result = job->ToResult();
6044 if (result->IsUndefined()) result = Null(args.GetIsolate());
6045 return args.GetReturnValue().Set(result);
6046 }
6047 if (args[7]->IsObject()) return ScryptJob::Run(std::move(job), args[7]);
6048 env->PrintSyncTrace();
6049 job->DoThreadPoolWork();
6050 args.GetReturnValue().Set(job->ToResult());
6051 }
6052 #endif // OPENSSL_NO_SCRYPT
6053
6054
6055 class KeyPairGenerationConfig {
6056 public:
6057 virtual EVPKeyCtxPointer Setup() = 0;
Configure(const EVPKeyCtxPointer & ctx)6058 virtual bool Configure(const EVPKeyCtxPointer& ctx) {
6059 return true;
6060 }
6061 virtual ~KeyPairGenerationConfig() = default;
6062 };
6063
6064 class RSAKeyPairGenerationConfig : public KeyPairGenerationConfig {
6065 public:
RSAKeyPairGenerationConfig(unsigned int modulus_bits,unsigned int exponent)6066 RSAKeyPairGenerationConfig(unsigned int modulus_bits, unsigned int exponent)
6067 : modulus_bits_(modulus_bits), exponent_(exponent) {}
6068
Setup()6069 EVPKeyCtxPointer Setup() override {
6070 return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr));
6071 }
6072
Configure(const EVPKeyCtxPointer & ctx)6073 bool Configure(const EVPKeyCtxPointer& ctx) override {
6074 if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), modulus_bits_) <= 0)
6075 return false;
6076
6077 // 0x10001 is the default RSA exponent.
6078 if (exponent_ != 0x10001) {
6079 BignumPointer bn(BN_new());
6080 CHECK_NOT_NULL(bn.get());
6081 CHECK(BN_set_word(bn.get(), exponent_));
6082 // EVP_CTX acceps ownership of bn on success.
6083 if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx.get(), bn.get()) <= 0)
6084 return false;
6085 bn.release();
6086 }
6087
6088 return true;
6089 }
6090
6091 private:
6092 const unsigned int modulus_bits_;
6093 const unsigned int exponent_;
6094 };
6095
6096 class RSAPSSKeyPairGenerationConfig : public RSAKeyPairGenerationConfig {
6097 public:
RSAPSSKeyPairGenerationConfig(unsigned int modulus_bits,unsigned int exponent,const EVP_MD * md,const EVP_MD * mgf1_md,int saltlen)6098 RSAPSSKeyPairGenerationConfig(unsigned int modulus_bits,
6099 unsigned int exponent,
6100 const EVP_MD* md,
6101 const EVP_MD* mgf1_md,
6102 int saltlen)
6103 : RSAKeyPairGenerationConfig(modulus_bits, exponent),
6104 md_(md), mgf1_md_(mgf1_md), saltlen_(saltlen) {}
6105
Setup()6106 EVPKeyCtxPointer Setup() override {
6107 return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA_PSS, nullptr));
6108 }
6109
Configure(const EVPKeyCtxPointer & ctx)6110 bool Configure(const EVPKeyCtxPointer& ctx) override {
6111 if (!RSAKeyPairGenerationConfig::Configure(ctx))
6112 return false;
6113
6114 if (md_ != nullptr) {
6115 if (EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), md_) <= 0)
6116 return false;
6117 }
6118
6119 if (mgf1_md_ != nullptr) {
6120 if (EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx.get(), mgf1_md_) <= 0)
6121 return false;
6122 }
6123
6124 if (saltlen_ >= 0) {
6125 if (EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx.get(), saltlen_) <= 0)
6126 return false;
6127 }
6128
6129 return true;
6130 }
6131
6132 private:
6133 const EVP_MD* md_;
6134 const EVP_MD* mgf1_md_;
6135 const int saltlen_;
6136 };
6137
6138 class DSAKeyPairGenerationConfig : public KeyPairGenerationConfig {
6139 public:
DSAKeyPairGenerationConfig(unsigned int modulus_bits,int divisor_bits)6140 DSAKeyPairGenerationConfig(unsigned int modulus_bits, int divisor_bits)
6141 : modulus_bits_(modulus_bits), divisor_bits_(divisor_bits) {}
6142
Setup()6143 EVPKeyCtxPointer Setup() override {
6144 EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, nullptr));
6145 if (!param_ctx)
6146 return nullptr;
6147
6148 if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0)
6149 return nullptr;
6150
6151 if (EVP_PKEY_CTX_set_dsa_paramgen_bits(param_ctx.get(), modulus_bits_) <= 0)
6152 return nullptr;
6153
6154 if (divisor_bits_ != -1) {
6155 if (EVP_PKEY_CTX_ctrl(param_ctx.get(), EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
6156 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, divisor_bits_,
6157 nullptr) <= 0) {
6158 return nullptr;
6159 }
6160 }
6161
6162 EVP_PKEY* raw_params = nullptr;
6163 if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
6164 return nullptr;
6165 EVPKeyPointer params(raw_params);
6166 param_ctx.reset();
6167
6168 EVPKeyCtxPointer key_ctx(EVP_PKEY_CTX_new(params.get(), nullptr));
6169 return key_ctx;
6170 }
6171
6172 private:
6173 const unsigned int modulus_bits_;
6174 const int divisor_bits_;
6175 };
6176
6177 class ECKeyPairGenerationConfig : public KeyPairGenerationConfig {
6178 public:
ECKeyPairGenerationConfig(int curve_nid,int param_encoding)6179 ECKeyPairGenerationConfig(int curve_nid, int param_encoding)
6180 : curve_nid_(curve_nid), param_encoding_(param_encoding) {}
6181
Setup()6182 EVPKeyCtxPointer Setup() override {
6183 EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
6184 if (!param_ctx)
6185 return nullptr;
6186
6187 if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0)
6188 return nullptr;
6189
6190 if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(param_ctx.get(),
6191 curve_nid_) <= 0)
6192 return nullptr;
6193
6194 if (EVP_PKEY_CTX_set_ec_param_enc(param_ctx.get(), param_encoding_) <= 0)
6195 return nullptr;
6196
6197 EVP_PKEY* raw_params = nullptr;
6198 if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
6199 return nullptr;
6200 EVPKeyPointer params(raw_params);
6201 param_ctx.reset();
6202
6203 EVPKeyCtxPointer key_ctx(EVP_PKEY_CTX_new(params.get(), nullptr));
6204 return key_ctx;
6205 }
6206
6207 private:
6208 const int curve_nid_;
6209 const int param_encoding_;
6210 };
6211
6212 class NidKeyPairGenerationConfig : public KeyPairGenerationConfig {
6213 public:
NidKeyPairGenerationConfig(int id)6214 explicit NidKeyPairGenerationConfig(int id) : id_(id) {}
6215
Setup()6216 EVPKeyCtxPointer Setup() override {
6217 return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(id_, nullptr));
6218 }
6219
6220 private:
6221 const int id_;
6222 };
6223
6224 // TODO(tniessen): Use std::variant instead.
6225 // Diffie-Hellman can either generate keys using a fixed prime, or by first
6226 // generating a random prime of a given size (in bits). Only one of both options
6227 // may be specified.
6228 struct PrimeInfo {
6229 BignumPointer fixed_value_;
6230 unsigned int prime_size_;
6231 };
6232
6233 class DHKeyPairGenerationConfig : public KeyPairGenerationConfig {
6234 public:
DHKeyPairGenerationConfig(PrimeInfo && prime_info,unsigned int generator)6235 explicit DHKeyPairGenerationConfig(PrimeInfo&& prime_info,
6236 unsigned int generator)
6237 : prime_info_(std::move(prime_info)),
6238 generator_(generator) {}
6239
Setup()6240 EVPKeyCtxPointer Setup() override {
6241 EVPKeyPointer params;
6242 if (prime_info_.fixed_value_) {
6243 DHPointer dh(DH_new());
6244 if (!dh)
6245 return nullptr;
6246
6247 BIGNUM* prime = prime_info_.fixed_value_.get();
6248 BignumPointer bn_g(BN_new());
6249 if (!BN_set_word(bn_g.get(), generator_) ||
6250 !DH_set0_pqg(dh.get(), prime, nullptr, bn_g.get()))
6251 return nullptr;
6252
6253 prime_info_.fixed_value_.release();
6254 bn_g.release();
6255
6256 params = EVPKeyPointer(EVP_PKEY_new());
6257 CHECK(params);
6258 EVP_PKEY_assign_DH(params.get(), dh.release());
6259 } else {
6260 EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DH, nullptr));
6261 if (!param_ctx)
6262 return nullptr;
6263
6264 if (EVP_PKEY_paramgen_init(param_ctx.get()) <= 0)
6265 return nullptr;
6266
6267 if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(param_ctx.get(),
6268 prime_info_.prime_size_) <= 0)
6269 return nullptr;
6270
6271 if (EVP_PKEY_CTX_set_dh_paramgen_generator(param_ctx.get(),
6272 generator_) <= 0)
6273 return nullptr;
6274
6275 EVP_PKEY* raw_params = nullptr;
6276 if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
6277 return nullptr;
6278 params = EVPKeyPointer(raw_params);
6279 }
6280
6281 return EVPKeyCtxPointer(EVP_PKEY_CTX_new(params.get(), nullptr));
6282 }
6283
6284 private:
6285 PrimeInfo prime_info_;
6286 unsigned int generator_;
6287 };
6288
6289 class GenerateKeyPairJob : public CryptoJob {
6290 public:
GenerateKeyPairJob(Environment * env,std::unique_ptr<KeyPairGenerationConfig> config,PublicKeyEncodingConfig public_key_encoding,PrivateKeyEncodingConfig && private_key_encoding)6291 GenerateKeyPairJob(Environment* env,
6292 std::unique_ptr<KeyPairGenerationConfig> config,
6293 PublicKeyEncodingConfig public_key_encoding,
6294 PrivateKeyEncodingConfig&& private_key_encoding)
6295 : CryptoJob(env),
6296 config_(std::move(config)),
6297 public_key_encoding_(public_key_encoding),
6298 private_key_encoding_(std::forward<PrivateKeyEncodingConfig>(
6299 private_key_encoding)),
6300 pkey_(nullptr) {}
6301
DoThreadPoolWork()6302 inline void DoThreadPoolWork() override {
6303 if (!GenerateKey())
6304 errors_.Capture();
6305 }
6306
GenerateKey()6307 inline bool GenerateKey() {
6308 // Make sure that the CSPRNG is properly seeded so the results are secure.
6309 CheckEntropy();
6310
6311 // Create the key generation context.
6312 EVPKeyCtxPointer ctx = config_->Setup();
6313 if (!ctx)
6314 return false;
6315
6316 // Initialize key generation.
6317 if (EVP_PKEY_keygen_init(ctx.get()) <= 0)
6318 return false;
6319
6320 // Configure key generation.
6321 if (!config_->Configure(ctx))
6322 return false;
6323
6324 // Generate the key.
6325 EVP_PKEY* pkey = nullptr;
6326 if (EVP_PKEY_keygen(ctx.get(), &pkey) != 1)
6327 return false;
6328 pkey_ = ManagedEVPPKey(EVPKeyPointer(pkey));
6329 return true;
6330 }
6331
AfterThreadPoolWork()6332 inline void AfterThreadPoolWork() override {
6333 Local<Value> args[3];
6334 ToResult(&args[0], &args[1], &args[2]);
6335 async_wrap->MakeCallback(env()->ondone_string(), 3, args);
6336 }
6337
ToResult(Local<Value> * err,Local<Value> * pubkey,Local<Value> * privkey)6338 inline void ToResult(Local<Value>* err,
6339 Local<Value>* pubkey,
6340 Local<Value>* privkey) {
6341 if (pkey_ && EncodeKeys(pubkey, privkey)) {
6342 CHECK(errors_.empty());
6343 *err = Undefined(env()->isolate());
6344 } else {
6345 if (errors_.empty())
6346 errors_.Capture();
6347 CHECK(!errors_.empty());
6348 *err = errors_.ToException(env()).ToLocalChecked();
6349 *pubkey = Undefined(env()->isolate());
6350 *privkey = Undefined(env()->isolate());
6351 }
6352 }
6353
EncodeKeys(Local<Value> * pubkey,Local<Value> * privkey)6354 inline bool EncodeKeys(Local<Value>* pubkey, Local<Value>* privkey) {
6355 // Encode the public key.
6356 if (public_key_encoding_.output_key_object_) {
6357 // Note that this has the downside of containing sensitive data of the
6358 // private key.
6359 std::shared_ptr<KeyObjectData> data =
6360 KeyObjectData::CreateAsymmetric(kKeyTypePublic, pkey_);
6361 if (!KeyObjectHandle::Create(env(), data).ToLocal(pubkey))
6362 return false;
6363 } else {
6364 if (!WritePublicKey(env(), pkey_.get(), public_key_encoding_)
6365 .ToLocal(pubkey))
6366 return false;
6367 }
6368
6369 // Now do the same for the private key.
6370 if (private_key_encoding_.output_key_object_) {
6371 std::shared_ptr<KeyObjectData> data =
6372 KeyObjectData::CreateAsymmetric(kKeyTypePrivate, pkey_);
6373 if (!KeyObjectHandle::Create(env(), data).ToLocal(privkey))
6374 return false;
6375 } else {
6376 if (!WritePrivateKey(env(), pkey_.get(), private_key_encoding_)
6377 .ToLocal(privkey))
6378 return false;
6379 }
6380
6381 return true;
6382 }
6383
6384 private:
6385 CryptoErrorVector errors_;
6386 std::unique_ptr<KeyPairGenerationConfig> config_;
6387 PublicKeyEncodingConfig public_key_encoding_;
6388 PrivateKeyEncodingConfig private_key_encoding_;
6389 ManagedEVPPKey pkey_;
6390 };
6391
GenerateKeyPair(const FunctionCallbackInfo<Value> & args,unsigned int offset,std::unique_ptr<KeyPairGenerationConfig> config)6392 void GenerateKeyPair(const FunctionCallbackInfo<Value>& args,
6393 unsigned int offset,
6394 std::unique_ptr<KeyPairGenerationConfig> config) {
6395 Environment* env = Environment::GetCurrent(args);
6396
6397 PublicKeyEncodingConfig public_key_encoding =
6398 GetPublicKeyEncodingFromJs(args, &offset, kKeyContextGenerate);
6399 NonCopyableMaybe<PrivateKeyEncodingConfig> private_key_encoding =
6400 GetPrivateKeyEncodingFromJs(args, &offset, kKeyContextGenerate);
6401
6402 if (private_key_encoding.IsEmpty())
6403 return;
6404
6405 std::unique_ptr<GenerateKeyPairJob> job(
6406 new GenerateKeyPairJob(env, std::move(config), public_key_encoding,
6407 private_key_encoding.Release()));
6408 if (args[offset]->IsObject())
6409 return GenerateKeyPairJob::Run(std::move(job), args[offset]);
6410 env->PrintSyncTrace();
6411 job->DoThreadPoolWork();
6412 Local<Value> err, pubkey, privkey;
6413 job->ToResult(&err, &pubkey, &privkey);
6414
6415 Local<Value> ret[] = { err, pubkey, privkey };
6416 args.GetReturnValue().Set(Array::New(env->isolate(), ret, arraysize(ret)));
6417 }
6418
GenerateKeyPairRSA(const FunctionCallbackInfo<Value> & args)6419 void GenerateKeyPairRSA(const FunctionCallbackInfo<Value>& args) {
6420 CHECK(args[0]->IsUint32());
6421 const uint32_t modulus_bits = args[0].As<Uint32>()->Value();
6422 CHECK(args[1]->IsUint32());
6423 const uint32_t exponent = args[1].As<Uint32>()->Value();
6424 std::unique_ptr<KeyPairGenerationConfig> config(
6425 new RSAKeyPairGenerationConfig(modulus_bits, exponent));
6426 GenerateKeyPair(args, 2, std::move(config));
6427 }
6428
GenerateKeyPairRSAPSS(const FunctionCallbackInfo<Value> & args)6429 void GenerateKeyPairRSAPSS(const FunctionCallbackInfo<Value>& args) {
6430 Environment* env = Environment::GetCurrent(args);
6431
6432 CHECK(args[0]->IsUint32());
6433 const uint32_t modulus_bits = args[0].As<Uint32>()->Value();
6434 CHECK(args[1]->IsUint32());
6435 const uint32_t exponent = args[1].As<Uint32>()->Value();
6436
6437 const EVP_MD* md = nullptr;
6438 if (!args[2]->IsUndefined()) {
6439 CHECK(args[2]->IsString());
6440 String::Utf8Value md_name(env->isolate(), args[2].As<String>());
6441 md = EVP_get_digestbyname(*md_name);
6442 if (md == nullptr)
6443 return env->ThrowTypeError("Digest method not supported");
6444 }
6445
6446 const EVP_MD* mgf1_md = nullptr;
6447 if (!args[3]->IsUndefined()) {
6448 CHECK(args[3]->IsString());
6449 String::Utf8Value mgf1_md_name(env->isolate(), args[3].As<String>());
6450 mgf1_md = EVP_get_digestbyname(*mgf1_md_name);
6451 if (mgf1_md == nullptr)
6452 return env->ThrowTypeError("Digest method not supported");
6453 }
6454
6455 int saltlen = -1;
6456 if (!args[4]->IsUndefined()) {
6457 CHECK(args[4]->IsInt32());
6458 saltlen = args[4].As<Int32>()->Value();
6459 }
6460
6461 std::unique_ptr<KeyPairGenerationConfig> config(
6462 new RSAPSSKeyPairGenerationConfig(modulus_bits, exponent,
6463 md, mgf1_md, saltlen));
6464 GenerateKeyPair(args, 5, std::move(config));
6465 }
6466
GenerateKeyPairDSA(const FunctionCallbackInfo<Value> & args)6467 void GenerateKeyPairDSA(const FunctionCallbackInfo<Value>& args) {
6468 CHECK(args[0]->IsUint32());
6469 const uint32_t modulus_bits = args[0].As<Uint32>()->Value();
6470 CHECK(args[1]->IsInt32());
6471 const int32_t divisor_bits = args[1].As<Int32>()->Value();
6472 std::unique_ptr<KeyPairGenerationConfig> config(
6473 new DSAKeyPairGenerationConfig(modulus_bits, divisor_bits));
6474 GenerateKeyPair(args, 2, std::move(config));
6475 }
6476
GenerateKeyPairEC(const FunctionCallbackInfo<Value> & args)6477 void GenerateKeyPairEC(const FunctionCallbackInfo<Value>& args) {
6478 CHECK(args[0]->IsString());
6479 String::Utf8Value curve_name(args.GetIsolate(), args[0].As<String>());
6480 int curve_nid = EC_curve_nist2nid(*curve_name);
6481 if (curve_nid == NID_undef)
6482 curve_nid = OBJ_sn2nid(*curve_name);
6483 // TODO(tniessen): Should we also support OBJ_ln2nid? (Other APIs don't.)
6484 if (curve_nid == NID_undef) {
6485 Environment* env = Environment::GetCurrent(args);
6486 return env->ThrowTypeError("Invalid ECDH curve name");
6487 }
6488 CHECK(args[1]->IsUint32());
6489 const uint32_t param_encoding = args[1].As<Int32>()->Value();
6490 CHECK(param_encoding == OPENSSL_EC_NAMED_CURVE ||
6491 param_encoding == OPENSSL_EC_EXPLICIT_CURVE);
6492 std::unique_ptr<KeyPairGenerationConfig> config(
6493 new ECKeyPairGenerationConfig(curve_nid, param_encoding));
6494 GenerateKeyPair(args, 2, std::move(config));
6495 }
6496
GenerateKeyPairNid(const FunctionCallbackInfo<Value> & args)6497 void GenerateKeyPairNid(const FunctionCallbackInfo<Value>& args) {
6498 CHECK(args[0]->IsInt32());
6499 const int id = args[0].As<Int32>()->Value();
6500 std::unique_ptr<KeyPairGenerationConfig> config(
6501 new NidKeyPairGenerationConfig(id));
6502 GenerateKeyPair(args, 1, std::move(config));
6503 }
6504
GenerateKeyPairDH(const FunctionCallbackInfo<Value> & args)6505 void GenerateKeyPairDH(const FunctionCallbackInfo<Value>& args) {
6506 Environment* env = Environment::GetCurrent(args);
6507
6508 PrimeInfo prime_info = {};
6509 unsigned int generator;
6510 if (args[0]->IsString()) {
6511 String::Utf8Value group_name(args.GetIsolate(), args[0].As<String>());
6512 const modp_group* group = FindDiffieHellmanGroup(*group_name);
6513 if (group == nullptr)
6514 return THROW_ERR_CRYPTO_UNKNOWN_DH_GROUP(env);
6515
6516 prime_info.fixed_value_ = BignumPointer(
6517 BN_bin2bn(reinterpret_cast<const unsigned char*>(group->prime),
6518 group->prime_size, nullptr));
6519 generator = group->gen;
6520 } else {
6521 if (args[0]->IsInt32()) {
6522 prime_info.prime_size_ = args[0].As<Int32>()->Value();
6523 } else {
6524 ArrayBufferViewContents<unsigned char> input(args[0]);
6525 prime_info.fixed_value_ = BignumPointer(
6526 BN_bin2bn(input.data(), input.length(), nullptr));
6527 }
6528
6529 CHECK(args[1]->IsInt32());
6530 generator = args[1].As<Int32>()->Value();
6531 }
6532
6533 std::unique_ptr<KeyPairGenerationConfig> config(
6534 new DHKeyPairGenerationConfig(std::move(prime_info), generator));
6535 GenerateKeyPair(args, 2, std::move(config));
6536 }
6537
6538
GetSSLCiphers(const FunctionCallbackInfo<Value> & args)6539 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
6540 Environment* env = Environment::GetCurrent(args);
6541
6542 SSLCtxPointer ctx(SSL_CTX_new(TLS_method()));
6543 CHECK(ctx);
6544
6545 SSLPointer ssl(SSL_new(ctx.get()));
6546 CHECK(ssl);
6547
6548 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl.get());
6549 // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
6550 // document them, but since there are only 5, easier to just add them manually
6551 // and not have to explain their absence in the API docs. They are lower-cased
6552 // because the docs say they will be.
6553 static const char* TLS13_CIPHERS[] = {
6554 "tls_aes_256_gcm_sha384",
6555 "tls_chacha20_poly1305_sha256",
6556 "tls_aes_128_gcm_sha256",
6557 "tls_aes_128_ccm_8_sha256",
6558 "tls_aes_128_ccm_sha256"
6559 };
6560
6561 const int n = sk_SSL_CIPHER_num(ciphers);
6562 std::vector<Local<Value>> arr(n + arraysize(TLS13_CIPHERS));
6563
6564 for (int i = 0; i < n; ++i) {
6565 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
6566 arr[i] = OneByteString(env->isolate(), SSL_CIPHER_get_name(cipher));
6567 }
6568
6569 for (unsigned i = 0; i < arraysize(TLS13_CIPHERS); ++i) {
6570 const char* name = TLS13_CIPHERS[i];
6571 arr[n + i] = OneByteString(env->isolate(), name);
6572 }
6573
6574 args.GetReturnValue().Set(Array::New(env->isolate(), arr.data(), arr.size()));
6575 }
6576
6577
6578 class CipherPushContext {
6579 public:
CipherPushContext(Environment * env)6580 explicit CipherPushContext(Environment* env)
6581 : arr(Array::New(env->isolate())),
6582 env_(env) {
6583 }
6584
env() const6585 inline Environment* env() const { return env_; }
6586
6587 Local<Array> arr;
6588
6589 private:
6590 Environment* env_;
6591 };
6592
6593
6594 template <class TypeName>
array_push_back(const TypeName * md,const char * from,const char * to,void * arg)6595 static void array_push_back(const TypeName* md,
6596 const char* from,
6597 const char* to,
6598 void* arg) {
6599 CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
6600 ctx->arr->Set(ctx->env()->context(),
6601 ctx->arr->Length(),
6602 OneByteString(ctx->env()->isolate(), from)).Check();
6603 }
6604
6605
GetCiphers(const FunctionCallbackInfo<Value> & args)6606 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
6607 Environment* env = Environment::GetCurrent(args);
6608 CipherPushContext ctx(env);
6609 EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
6610 args.GetReturnValue().Set(ctx.arr);
6611 }
6612
6613
GetHashes(const FunctionCallbackInfo<Value> & args)6614 void GetHashes(const FunctionCallbackInfo<Value>& args) {
6615 Environment* env = Environment::GetCurrent(args);
6616 CipherPushContext ctx(env);
6617 EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
6618 args.GetReturnValue().Set(ctx.arr);
6619 }
6620
6621
GetCurves(const FunctionCallbackInfo<Value> & args)6622 void GetCurves(const FunctionCallbackInfo<Value>& args) {
6623 Environment* env = Environment::GetCurrent(args);
6624 const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
6625
6626 if (num_curves) {
6627 std::vector<EC_builtin_curve> curves(num_curves);
6628
6629 if (EC_get_builtin_curves(curves.data(), num_curves)) {
6630 std::vector<Local<Value>> arr(num_curves);
6631
6632 for (size_t i = 0; i < num_curves; i++)
6633 arr[i] = OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid));
6634
6635 args.GetReturnValue().Set(
6636 Array::New(env->isolate(), arr.data(), arr.size()));
6637 return;
6638 }
6639 }
6640
6641 args.GetReturnValue().Set(Array::New(env->isolate()));
6642 }
6643
6644
VerifySpkac(const char * data,unsigned int len)6645 bool VerifySpkac(const char* data, unsigned int len) {
6646 NetscapeSPKIPointer spki(NETSCAPE_SPKI_b64_decode(data, len));
6647 if (!spki)
6648 return false;
6649
6650 EVPKeyPointer pkey(X509_PUBKEY_get(spki->spkac->pubkey));
6651 if (!pkey)
6652 return false;
6653
6654 return NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0;
6655 }
6656
6657
VerifySpkac(const FunctionCallbackInfo<Value> & args)6658 void VerifySpkac(const FunctionCallbackInfo<Value>& args) {
6659 bool verify_result = false;
6660
6661 ArrayBufferViewContents<char> input(args[0]);
6662 if (input.length() == 0)
6663 return args.GetReturnValue().SetEmptyString();
6664
6665 CHECK_NOT_NULL(input.data());
6666
6667 verify_result = VerifySpkac(input.data(), input.length());
6668
6669 args.GetReturnValue().Set(verify_result);
6670 }
6671
ExportPublicKey(Environment * env,const char * data,int len,size_t * size)6672 AllocatedBuffer ExportPublicKey(Environment* env,
6673 const char* data,
6674 int len,
6675 size_t* size) {
6676 BIOPointer bio(BIO_new(BIO_s_mem()));
6677 if (!bio) return AllocatedBuffer();
6678
6679 NetscapeSPKIPointer spki(NETSCAPE_SPKI_b64_decode(data, len));
6680 if (!spki) return AllocatedBuffer();
6681
6682 EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get()));
6683 if (!pkey) return AllocatedBuffer();
6684
6685 if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0)
6686 return AllocatedBuffer();
6687
6688 BUF_MEM* ptr;
6689 BIO_get_mem_ptr(bio.get(), &ptr);
6690
6691 *size = ptr->length;
6692 AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, *size);
6693 memcpy(buf.data(), ptr->data, *size);
6694
6695 return buf;
6696 }
6697
6698
ExportPublicKey(const FunctionCallbackInfo<Value> & args)6699 void ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
6700 Environment* env = Environment::GetCurrent(args);
6701
6702 ArrayBufferViewContents<char> input(args[0]);
6703 if (input.length() == 0)
6704 return args.GetReturnValue().SetEmptyString();
6705
6706 CHECK_NOT_NULL(input.data());
6707
6708 size_t pkey_size;
6709 AllocatedBuffer pkey =
6710 ExportPublicKey(env, input.data(), input.length(), &pkey_size);
6711 if (pkey.data() == nullptr)
6712 return args.GetReturnValue().SetEmptyString();
6713
6714 args.GetReturnValue().Set(pkey.ToBuffer().ToLocalChecked());
6715 }
6716
6717
ExportChallenge(const char * data,int len)6718 OpenSSLBuffer ExportChallenge(const char* data, int len) {
6719 NetscapeSPKIPointer sp(NETSCAPE_SPKI_b64_decode(data, len));
6720 if (!sp)
6721 return nullptr;
6722
6723 unsigned char* buf = nullptr;
6724 ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
6725
6726 return OpenSSLBuffer(reinterpret_cast<char*>(buf));
6727 }
6728
6729
ExportChallenge(const FunctionCallbackInfo<Value> & args)6730 void ExportChallenge(const FunctionCallbackInfo<Value>& args) {
6731 Environment* env = Environment::GetCurrent(args);
6732
6733 ArrayBufferViewContents<char> input(args[0]);
6734 if (input.length() == 0)
6735 return args.GetReturnValue().SetEmptyString();
6736
6737 OpenSSLBuffer cert = ExportChallenge(input.data(), input.length());
6738 if (!cert)
6739 return args.GetReturnValue().SetEmptyString();
6740
6741 Local<Value> outString =
6742 Encode(env->isolate(), cert.get(), strlen(cert.get()), BUFFER);
6743
6744 args.GetReturnValue().Set(outString);
6745 }
6746
6747
6748 // Convert the input public key to compressed, uncompressed, or hybrid formats.
ConvertKey(const FunctionCallbackInfo<Value> & args)6749 void ConvertKey(const FunctionCallbackInfo<Value>& args) {
6750 MarkPopErrorOnReturn mark_pop_error_on_return;
6751 Environment* env = Environment::GetCurrent(args);
6752
6753 CHECK_EQ(args.Length(), 3);
6754 CHECK(args[0]->IsArrayBufferView());
6755
6756 size_t len = args[0].As<ArrayBufferView>()->ByteLength();
6757 if (len == 0)
6758 return args.GetReturnValue().SetEmptyString();
6759
6760 node::Utf8Value curve(env->isolate(), args[1]);
6761
6762 int nid = OBJ_sn2nid(*curve);
6763 if (nid == NID_undef)
6764 return env->ThrowTypeError("Invalid ECDH curve name");
6765
6766 ECGroupPointer group(
6767 EC_GROUP_new_by_curve_name(nid));
6768 if (group == nullptr)
6769 return env->ThrowError("Failed to get EC_GROUP");
6770
6771 ECPointPointer pub(
6772 ECDH::BufferToPoint(env,
6773 group.get(),
6774 args[0]));
6775
6776 if (pub == nullptr)
6777 return env->ThrowError("Failed to convert Buffer to EC_POINT");
6778
6779 CHECK(args[2]->IsUint32());
6780 uint32_t val = args[2].As<Uint32>()->Value();
6781 point_conversion_form_t form = static_cast<point_conversion_form_t>(val);
6782
6783 const char* error;
6784 Local<Object> buf;
6785 if (!ECPointToBuffer(env, group.get(), pub.get(), form, &error).ToLocal(&buf))
6786 return env->ThrowError(error);
6787 args.GetReturnValue().Set(buf);
6788 }
6789
StatelessDiffieHellman(Environment * env,ManagedEVPPKey our_key,ManagedEVPPKey their_key)6790 AllocatedBuffer StatelessDiffieHellman(Environment* env, ManagedEVPPKey our_key,
6791 ManagedEVPPKey their_key) {
6792 size_t out_size;
6793
6794 EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(our_key.get(), nullptr));
6795 if (!ctx ||
6796 EVP_PKEY_derive_init(ctx.get()) <= 0 ||
6797 EVP_PKEY_derive_set_peer(ctx.get(), their_key.get()) <= 0 ||
6798 EVP_PKEY_derive(ctx.get(), nullptr, &out_size) <= 0)
6799 return AllocatedBuffer();
6800
6801 AllocatedBuffer result = AllocatedBuffer::AllocateManaged(env, out_size);
6802 CHECK_NOT_NULL(result.data());
6803
6804 unsigned char* data = reinterpret_cast<unsigned char*>(result.data());
6805 if (EVP_PKEY_derive(ctx.get(), data, &out_size) <= 0)
6806 return AllocatedBuffer();
6807
6808 ZeroPadDiffieHellmanSecret(out_size, &result);
6809 return result;
6810 }
6811
StatelessDiffieHellman(const FunctionCallbackInfo<Value> & args)6812 void StatelessDiffieHellman(const FunctionCallbackInfo<Value>& args) {
6813 Environment* env = Environment::GetCurrent(args);
6814
6815 CHECK(args[0]->IsObject() && args[1]->IsObject());
6816 KeyObjectHandle* our_key_object;
6817 ASSIGN_OR_RETURN_UNWRAP(&our_key_object, args[0].As<Object>());
6818 CHECK_EQ(our_key_object->Data()->GetKeyType(), kKeyTypePrivate);
6819 KeyObjectHandle* their_key_object;
6820 ASSIGN_OR_RETURN_UNWRAP(&their_key_object, args[1].As<Object>());
6821 CHECK_NE(their_key_object->Data()->GetKeyType(), kKeyTypeSecret);
6822
6823 ManagedEVPPKey our_key = our_key_object->Data()->GetAsymmetricKey();
6824 ManagedEVPPKey their_key = their_key_object->Data()->GetAsymmetricKey();
6825
6826 AllocatedBuffer out = StatelessDiffieHellman(env, our_key, their_key);
6827 if (out.size() == 0)
6828 return ThrowCryptoError(env, ERR_get_error(), "diffieHellman failed");
6829
6830 args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
6831 }
6832
6833
TimingSafeEqual(const FunctionCallbackInfo<Value> & args)6834 void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
6835 // Moving the type checking into JS leads to test failures, most likely due
6836 // to V8 inlining certain parts of the wrapper. Therefore, keep them in C++.
6837 // Refs: https://github.com/nodejs/node/issues/34073.
6838 Environment* env = Environment::GetCurrent(args);
6839 if (!args[0]->IsArrayBufferView()) {
6840 THROW_ERR_INVALID_ARG_TYPE(
6841 env, "The \"buf1\" argument must be an instance of "
6842 "Buffer, TypedArray, or DataView.");
6843 return;
6844 }
6845 if (!args[1]->IsArrayBufferView()) {
6846 THROW_ERR_INVALID_ARG_TYPE(
6847 env, "The \"buf2\" argument must be an instance of "
6848 "Buffer, TypedArray, or DataView.");
6849 return;
6850 }
6851
6852 ArrayBufferViewContents<char> buf1(args[0].As<ArrayBufferView>());
6853 ArrayBufferViewContents<char> buf2(args[1].As<ArrayBufferView>());
6854
6855 if (buf1.length() != buf2.length()) {
6856 THROW_ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH(env);
6857 return;
6858 }
6859
6860 return args.GetReturnValue().Set(
6861 CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.length()) == 0);
6862 }
6863
InitCryptoOnce()6864 void InitCryptoOnce() {
6865 #ifndef OPENSSL_IS_BORINGSSL
6866 OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
6867
6868 // --openssl-config=...
6869 if (!per_process::cli_options->openssl_config.empty()) {
6870 const char* conf = per_process::cli_options->openssl_config.c_str();
6871 OPENSSL_INIT_set_config_filename(settings, conf);
6872 }
6873
6874 OPENSSL_init_ssl(0, settings);
6875 OPENSSL_INIT_free(settings);
6876 settings = nullptr;
6877 #endif
6878
6879 /* Override FIPS settings in cnf file, if needed. */
6880 unsigned long err = 0; // NOLINT(runtime/int)
6881 if (per_process::cli_options->enable_fips_crypto ||
6882 per_process::cli_options->force_fips_crypto) {
6883 if (0 == FIPS_mode() && !FIPS_mode_set(1)) {
6884 err = ERR_get_error();
6885 }
6886 }
6887 if (0 != err) {
6888 auto* isolate = Isolate::GetCurrent();
6889 auto* env = Environment::GetCurrent(isolate);
6890 return ThrowCryptoError(env, err);
6891 }
6892
6893
6894 // Turn off compression. Saves memory and protects against CRIME attacks.
6895 // No-op with OPENSSL_NO_COMP builds of OpenSSL.
6896 sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
6897
6898 #ifndef OPENSSL_NO_ENGINE
6899 ERR_load_ENGINE_strings();
6900 ENGINE_load_builtin_engines();
6901 #endif // !OPENSSL_NO_ENGINE
6902
6903 NodeBIO::GetMethod();
6904 }
6905
6906
6907 #ifndef OPENSSL_NO_ENGINE
SetEngine(const FunctionCallbackInfo<Value> & args)6908 void SetEngine(const FunctionCallbackInfo<Value>& args) {
6909 Environment* env = Environment::GetCurrent(args);
6910 CHECK(args.Length() >= 2 && args[0]->IsString());
6911 uint32_t flags;
6912 if (!args[1]->Uint32Value(env->context()).To(&flags)) return;
6913
6914 ClearErrorOnReturn clear_error_on_return;
6915
6916 // Load engine.
6917 const node::Utf8Value engine_id(env->isolate(), args[0]);
6918 char errmsg[1024];
6919 ENGINE* engine = LoadEngineById(*engine_id, &errmsg);
6920
6921 if (engine == nullptr) {
6922 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
6923 if (err == 0)
6924 return args.GetReturnValue().Set(false);
6925 return ThrowCryptoError(env, err);
6926 }
6927
6928 int r = ENGINE_set_default(engine, flags);
6929 ENGINE_free(engine);
6930 if (r == 0)
6931 return ThrowCryptoError(env, ERR_get_error());
6932
6933 args.GetReturnValue().Set(true);
6934 }
6935 #endif // !OPENSSL_NO_ENGINE
6936
GetFipsCrypto(const FunctionCallbackInfo<Value> & args)6937 void GetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
6938 args.GetReturnValue().Set(FIPS_mode() ? 1 : 0);
6939 }
6940
SetFipsCrypto(const FunctionCallbackInfo<Value> & args)6941 void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
6942 CHECK(!per_process::cli_options->force_fips_crypto);
6943 Environment* env = Environment::GetCurrent(args);
6944 const bool enabled = FIPS_mode();
6945 bool enable = args[0]->BooleanValue(env->isolate());
6946
6947 if (enable == enabled)
6948 return; // No action needed.
6949 if (!FIPS_mode_set(enable)) {
6950 unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
6951 return ThrowCryptoError(env, err);
6952 }
6953 }
6954
6955 namespace {
6956 // SecureBuffer uses openssl to allocate a Uint8Array using
6957 // OPENSSL_secure_malloc. Because we do not yet actually
6958 // make use of secure heap, this has the same semantics as
6959 // using OPENSSL_malloc. However, if the secure heap is
6960 // initialized, SecureBuffer will automatically use it.
SecureBuffer(const FunctionCallbackInfo<Value> & args)6961 void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
6962 CHECK(args[0]->IsUint32());
6963 Environment* env = Environment::GetCurrent(args);
6964 uint32_t len = args[0].As<Uint32>()->Value();
6965 char* data = static_cast<char*>(OPENSSL_secure_malloc(len));
6966 if (data == nullptr) {
6967 // There's no memory available for the allocation.
6968 // Return nothing.
6969 return;
6970 }
6971 memset(data, 0, len);
6972 std::shared_ptr<BackingStore> store =
6973 ArrayBuffer::NewBackingStore(
6974 data,
6975 len,
6976 [](void* data, size_t len, void* deleter_data) {
6977 OPENSSL_secure_clear_free(data, len);
6978 },
6979 data);
6980 Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
6981 args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len));
6982 }
6983 } // namespace
6984
Initialize(Local<Object> target,Local<Value> unused,Local<Context> context,void * priv)6985 void Initialize(Local<Object> target,
6986 Local<Value> unused,
6987 Local<Context> context,
6988 void* priv) {
6989 Environment* env = Environment::GetCurrent(context);
6990 static uv_once_t init_once = UV_ONCE_INIT;
6991 TryCatch try_catch{env->isolate()};
6992 uv_once(&init_once, InitCryptoOnce);
6993
6994 if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
6995 try_catch.ReThrow();
6996 return;
6997 }
6998
6999 SecureContext::Initialize(env, target);
7000 target->Set(env->context(),
7001 FIXED_ONE_BYTE_STRING(env->isolate(), "KeyObjectHandle"),
7002 KeyObjectHandle::Initialize(env)).Check();
7003 env->SetMethod(target, "createNativeKeyObjectClass",
7004 CreateNativeKeyObjectClass);
7005 CipherBase::Initialize(env, target);
7006 DiffieHellman::Initialize(env, target);
7007 ECDH::Initialize(env, target);
7008 Hmac::Initialize(env, target);
7009 Hash::Initialize(env, target);
7010 Sign::Initialize(env, target);
7011 Verify::Initialize(env, target);
7012
7013 env->SetMethodNoSideEffect(target, "certVerifySpkac", VerifySpkac);
7014 env->SetMethodNoSideEffect(target, "certExportPublicKey", ExportPublicKey);
7015 env->SetMethodNoSideEffect(target, "certExportChallenge", ExportChallenge);
7016 env->SetMethodNoSideEffect(target, "getRootCertificates",
7017 GetRootCertificates);
7018 // Exposed for testing purposes only.
7019 env->SetMethodNoSideEffect(target, "isExtraRootCertsFileLoaded",
7020 IsExtraRootCertsFileLoaded);
7021
7022 env->SetMethodNoSideEffect(target, "ECDHConvertKey", ConvertKey);
7023 #ifndef OPENSSL_NO_ENGINE
7024 env->SetMethod(target, "setEngine", SetEngine);
7025 #endif // !OPENSSL_NO_ENGINE
7026
7027 env->SetMethodNoSideEffect(target, "getFipsCrypto", GetFipsCrypto);
7028 env->SetMethod(target, "setFipsCrypto", SetFipsCrypto);
7029 env->SetMethodNoSideEffect(target, "testFipsCrypto", TestFipsCrypto);
7030
7031 env->SetMethod(target, "pbkdf2", PBKDF2);
7032 env->SetMethod(target, "generateKeyPairRSA", GenerateKeyPairRSA);
7033 env->SetMethod(target, "generateKeyPairRSAPSS", GenerateKeyPairRSAPSS);
7034 env->SetMethod(target, "generateKeyPairDSA", GenerateKeyPairDSA);
7035 env->SetMethod(target, "generateKeyPairEC", GenerateKeyPairEC);
7036 env->SetMethod(target, "generateKeyPairNid", GenerateKeyPairNid);
7037 env->SetMethod(target, "generateKeyPairDH", GenerateKeyPairDH);
7038 NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED25519);
7039 NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED448);
7040 NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
7041 NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);
7042 NODE_DEFINE_CONSTANT(target, OPENSSL_EC_NAMED_CURVE);
7043 NODE_DEFINE_CONSTANT(target, OPENSSL_EC_EXPLICIT_CURVE);
7044 NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS1);
7045 NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS8);
7046 NODE_DEFINE_CONSTANT(target, kKeyEncodingSPKI);
7047 NODE_DEFINE_CONSTANT(target, kKeyEncodingSEC1);
7048 NODE_DEFINE_CONSTANT(target, kKeyFormatDER);
7049 NODE_DEFINE_CONSTANT(target, kKeyFormatPEM);
7050 NODE_DEFINE_CONSTANT(target, kKeyTypeSecret);
7051 NODE_DEFINE_CONSTANT(target, kKeyTypePublic);
7052 NODE_DEFINE_CONSTANT(target, kKeyTypePrivate);
7053 NODE_DEFINE_CONSTANT(target, kSigEncDER);
7054 NODE_DEFINE_CONSTANT(target, kSigEncP1363);
7055 env->SetMethodNoSideEffect(target, "statelessDH", StatelessDiffieHellman);
7056 env->SetMethod(target, "randomBytes", RandomBytes);
7057 env->SetMethod(target, "signOneShot", SignOneShot);
7058 env->SetMethod(target, "verifyOneShot", VerifyOneShot);
7059 env->SetMethodNoSideEffect(target, "timingSafeEqual", TimingSafeEqual);
7060 env->SetMethodNoSideEffect(target, "getSSLCiphers", GetSSLCiphers);
7061 env->SetMethodNoSideEffect(target, "getCiphers", GetCiphers);
7062 env->SetMethodNoSideEffect(target, "getHashes", GetHashes);
7063 env->SetMethodNoSideEffect(target, "getCurves", GetCurves);
7064 env->SetMethod(target, "publicEncrypt",
7065 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
7066 EVP_PKEY_encrypt_init,
7067 EVP_PKEY_encrypt>);
7068 env->SetMethod(target, "privateDecrypt",
7069 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
7070 EVP_PKEY_decrypt_init,
7071 EVP_PKEY_decrypt>);
7072 env->SetMethod(target, "privateEncrypt",
7073 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
7074 EVP_PKEY_sign_init,
7075 EVP_PKEY_sign>);
7076 env->SetMethod(target, "publicDecrypt",
7077 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
7078 EVP_PKEY_verify_recover_init,
7079 EVP_PKEY_verify_recover>);
7080 #ifndef OPENSSL_NO_SCRYPT
7081 env->SetMethod(target, "scrypt", Scrypt);
7082 #endif // OPENSSL_NO_SCRYPT
7083
7084 env->SetMethod(target, "secureBuffer", SecureBuffer);
7085 }
7086
7087 } // namespace crypto
7088 } // namespace node
7089
7090 NODE_MODULE_CONTEXT_AWARE_INTERNAL(crypto, node::crypto::Initialize)
7091