• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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