22 #ifndef SRC_NODE_CRYPTO_H_ 23 #define SRC_NODE_CRYPTO_H_ 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 41 #include <openssl/ssl.h> 42 #include <openssl/ec.h> 43 #include <openssl/ecdh.h> 44 #ifndef OPENSSL_NO_ENGINE 45 # include <openssl/engine.h> 46 #endif // !OPENSSL_NO_ENGINE 47 #include <openssl/err.h> 48 #include <openssl/evp.h> 49 #include <openssl/pem.h> 50 #include <openssl/x509.h> 51 #include <openssl/x509v3.h> 52 #include <openssl/hmac.h> 53 #include <openssl/rand.h> 54 #include <openssl/pkcs12.h> 56 #define EVP_F_EVP_DECRYPTFINAL 101 58 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb) 59 # define NODE__HAVE_TLSEXT_STATUS_CB 60 #endif // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb) 69 struct ClearErrorOnReturn {
70 ~ClearErrorOnReturn() { ERR_clear_error(); }
75 struct MarkPopErrorOnReturn {
76 MarkPopErrorOnReturn() { ERR_set_mark(); }
77 ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
81 CHECK_CERT_REVOKED = 0,
89 class SecureContext :
public BaseObject {
91 ~SecureContext()
override {
95 static void Initialize(Environment* env, v8::Local<v8::Object> target);
101 static const int kMaxSessionSize = 10 * 1024;
104 static const int kTicketKeyReturnIndex = 0;
105 static const int kTicketKeyHMACIndex = 1;
106 static const int kTicketKeyAESIndex = 2;
107 static const int kTicketKeyNameIndex = 3;
108 static const int kTicketKeyIVIndex = 4;
111 static const int64_t kExternalSize =
sizeof(SSL_CTX);
113 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
114 static void Init(
const v8::FunctionCallbackInfo<v8::Value>& args);
115 static void SetKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
116 static void SetCert(
const v8::FunctionCallbackInfo<v8::Value>& args);
117 static void AddCACert(
const v8::FunctionCallbackInfo<v8::Value>& args);
118 static void AddCRL(
const v8::FunctionCallbackInfo<v8::Value>& args);
119 static void AddRootCerts(
const v8::FunctionCallbackInfo<v8::Value>& args);
120 static void SetCiphers(
const v8::FunctionCallbackInfo<v8::Value>& args);
121 static void SetECDHCurve(
const v8::FunctionCallbackInfo<v8::Value>& args);
122 static void SetDHParam(
const v8::FunctionCallbackInfo<v8::Value>& args);
123 static void SetOptions(
const v8::FunctionCallbackInfo<v8::Value>& args);
124 static void SetSessionIdContext(
125 const v8::FunctionCallbackInfo<v8::Value>& args);
126 static void SetSessionTimeout(
127 const v8::FunctionCallbackInfo<v8::Value>& args);
128 static void Close(
const v8::FunctionCallbackInfo<v8::Value>& args);
129 static void LoadPKCS12(
const v8::FunctionCallbackInfo<v8::Value>& args);
130 static void GetTicketKeys(
const v8::FunctionCallbackInfo<v8::Value>& args);
131 static void SetTicketKeys(
const v8::FunctionCallbackInfo<v8::Value>& args);
132 static void SetFreeListLength(
133 const v8::FunctionCallbackInfo<v8::Value>& args);
134 static void EnableTicketKeyCallback(
135 const v8::FunctionCallbackInfo<v8::Value>& args);
136 static void CtxGetter(v8::Local<v8::String> property,
137 const v8::PropertyCallbackInfo<v8::Value>& info);
139 template <
bool primary>
140 static void GetCertificate(
const v8::FunctionCallbackInfo<v8::Value>& args);
142 static int TicketKeyCallback(SSL* ssl,
145 EVP_CIPHER_CTX* ectx,
149 SecureContext(Environment* env, v8::Local<v8::Object>
wrap)
150 : BaseObject(env, wrap),
154 MakeWeak<SecureContext>(
this);
155 env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
163 env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
165 if (cert_ !=
nullptr)
167 if (issuer_ !=
nullptr)
177 template <
class Base>
185 SSLWrap(Environment* env, SecureContext* sc, Kind kind)
189 session_callbacks_(false),
190 new_session_wait_(false),
193 cert_cb_running_(false) {
194 ssl_ = SSL_new(sc->ctx_);
195 env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
196 CHECK_NE(ssl_,
nullptr);
201 if (next_sess_ !=
nullptr) {
202 SSL_SESSION_free(next_sess_);
203 next_sess_ =
nullptr;
206 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 207 sni_context_.Reset();
210 #ifdef NODE__HAVE_TLSEXT_STATUS_CB 211 ocsp_response_.Reset();
212 #endif // NODE__HAVE_TLSEXT_STATUS_CB 215 inline SSL* ssl()
const {
return ssl_; }
216 inline void enable_session_callbacks() { session_callbacks_ =
true; }
217 inline bool is_server()
const {
return kind_ == kServer; }
218 inline bool is_client()
const {
return kind_ == kClient; }
219 inline bool is_waiting_new_session()
const {
return new_session_wait_; }
220 inline bool is_waiting_cert_cb()
const {
return cert_cb_ !=
nullptr; }
223 typedef void (*CertCb)(
void* arg);
228 static const int64_t kExternalSize =
229 sizeof(SSL) +
sizeof(SSL3_STATE) + 42 * 1024;
231 static void InitNPN(SecureContext* sc);
232 static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate>
t);
234 static SSL_SESSION* GetSessionCallback(SSL*
s,
238 static int NewSessionCallback(SSL*
s, SSL_SESSION* sess);
239 static void OnClientHello(
void* arg,
240 const ClientHelloParser::ClientHello& hello);
242 static void GetPeerCertificate(
243 const v8::FunctionCallbackInfo<v8::Value>& args);
244 static void GetSession(
const v8::FunctionCallbackInfo<v8::Value>& args);
245 static void SetSession(
const v8::FunctionCallbackInfo<v8::Value>& args);
246 static void LoadSession(
const v8::FunctionCallbackInfo<v8::Value>& args);
247 static void IsSessionReused(
const v8::FunctionCallbackInfo<v8::Value>& args);
248 static void IsInitFinished(
const v8::FunctionCallbackInfo<v8::Value>& args);
249 static void VerifyError(
const v8::FunctionCallbackInfo<v8::Value>& args);
250 static void GetCurrentCipher(
const v8::FunctionCallbackInfo<v8::Value>& args);
251 static void EndParser(
const v8::FunctionCallbackInfo<v8::Value>& args);
252 static void CertCbDone(
const v8::FunctionCallbackInfo<v8::Value>& args);
253 static void Renegotiate(
const v8::FunctionCallbackInfo<v8::Value>& args);
254 static void Shutdown(
const v8::FunctionCallbackInfo<v8::Value>& args);
255 static void GetTLSTicket(
const v8::FunctionCallbackInfo<v8::Value>& args);
256 static void NewSessionDone(
const v8::FunctionCallbackInfo<v8::Value>& args);
257 static void SetOCSPResponse(
const v8::FunctionCallbackInfo<v8::Value>& args);
258 static void RequestOCSP(
const v8::FunctionCallbackInfo<v8::Value>& args);
259 static void GetEphemeralKeyInfo(
260 const v8::FunctionCallbackInfo<v8::Value>& args);
261 static void GetProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args);
263 #ifdef SSL_set_max_send_fragment 264 static void SetMaxSendFragment(
265 const v8::FunctionCallbackInfo<v8::Value>& args);
266 #endif // SSL_set_max_send_fragment 268 #ifndef OPENSSL_NO_NEXTPROTONEG 269 static void GetNegotiatedProto(
270 const v8::FunctionCallbackInfo<v8::Value>& args);
271 static void SetNPNProtocols(
const v8::FunctionCallbackInfo<v8::Value>& args);
272 static int AdvertiseNextProtoCallback(SSL*
s,
273 const unsigned char**
data,
276 static int SelectNextProtoCallback(SSL*
s,
278 unsigned char* outlen,
279 const unsigned char* in,
282 #endif // OPENSSL_NO_NEXTPROTONEG 284 static void GetALPNNegotiatedProto(
285 const v8::FunctionCallbackInfo<v8::Value>& args);
286 static void SetALPNProtocols(
const v8::FunctionCallbackInfo<v8::Value>& args);
287 static int SelectALPNCallback(SSL*
s,
288 const unsigned char** out,
289 unsigned char* outlen,
290 const unsigned char* in,
293 static int TLSExtStatusCallback(SSL*
s,
void* arg);
294 static int SSLCertCallback(SSL*
s,
void* arg);
295 static void SSLGetter(v8::Local<v8::String> property,
296 const v8::PropertyCallbackInfo<v8::Value>& info);
299 void WaitForCertCb(CertCb cb,
void* arg);
300 void SetSNIContext(SecureContext* sc);
301 int SetCACerts(SecureContext* sc);
303 inline Environment* ssl_env()
const {
307 Environment*
const env_;
309 SSL_SESSION* next_sess_;
311 bool session_callbacks_;
312 bool new_session_wait_;
317 bool cert_cb_running_;
319 ClientHelloParser hello_parser_;
321 #ifdef NODE__HAVE_TLSEXT_STATUS_CB 322 v8::Persistent<v8::Object> ocsp_response_;
323 #endif // NODE__HAVE_TLSEXT_STATUS_CB 325 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 326 v8::Persistent<v8::Value> sni_context_;
329 friend class SecureContext;
335 class Connection :
public AsyncWrap,
public SSLWrap<Connection> {
337 ~Connection()
override {
338 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 344 static void Initialize(Environment* env, v8::Local<v8::Object> target);
345 void NewSessionDoneCb();
347 #ifndef OPENSSL_NO_NEXTPROTONEG 348 v8::Persistent<v8::Object> npnProtos_;
349 v8::Persistent<v8::Value> selectedNPNProto_;
352 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 353 v8::Persistent<v8::Object> sniObject_;
354 v8::Persistent<v8::String> servername_;
357 size_t self_size()
const override {
return sizeof(*this); }
360 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
361 static void EncIn(
const v8::FunctionCallbackInfo<v8::Value>& args);
362 static void ClearOut(
const v8::FunctionCallbackInfo<v8::Value>& args);
363 static void ClearPending(
const v8::FunctionCallbackInfo<v8::Value>& args);
364 static void EncPending(
const v8::FunctionCallbackInfo<v8::Value>& args);
365 static void EncOut(
const v8::FunctionCallbackInfo<v8::Value>& args);
366 static void ClearIn(
const v8::FunctionCallbackInfo<v8::Value>& args);
367 static void Start(
const v8::FunctionCallbackInfo<v8::Value>& args);
368 static void Close(
const v8::FunctionCallbackInfo<v8::Value>& args);
370 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 372 static void GetServername(
const v8::FunctionCallbackInfo<v8::Value>& args);
373 static void SetSNICallback(
const v8::FunctionCallbackInfo<v8::Value>& args);
374 static int SelectSNIContextCallback_(SSL*
s,
int* ad,
void* arg);
377 static void OnClientHelloParseEnd(
void* arg);
379 int HandleBIOError(BIO* bio,
const char*
func,
int rv);
391 int HandleSSLError(
const char*
func,
int rv, ZeroStatus zs, SyscallStatus ss);
393 void SetShutdownFlags();
395 Connection(Environment* env,
396 v8::Local<v8::Object> wrap,
398 SSLWrap<Connection>::Kind kind)
399 : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_SSLCONNECTION),
400 SSLWrap<Connection>(env, sc, kind),
404 MakeWeak<Connection>(
this);
406 hello_parser_.Start(SSLWrap<Connection>::OnClientHello,
407 OnClientHelloParseEnd,
409 enable_session_callbacks();
413 static void SSLInfoCallback(
const SSL *ssl,
int where,
int ret);
418 uint8_t hello_data_[18432];
419 size_t hello_offset_;
421 friend class ClientHelloParser;
422 friend class SecureContext;
425 class CipherBase :
public BaseObject {
427 ~CipherBase()
override {
430 EVP_CIPHER_CTX_cleanup(&ctx_);
433 static void Initialize(Environment* env, v8::Local<v8::Object> target);
441 void Init(
const char* cipher_type,
const char* key_buf,
int key_buf_len);
442 void InitIv(
const char* cipher_type,
447 bool Update(
const char*
data,
int len,
unsigned char** out,
int* out_len);
448 bool Final(
unsigned char** out,
int *out_len);
449 bool SetAutoPadding(
bool auto_padding);
451 bool IsAuthenticatedMode()
const;
452 bool SetAAD(
const char*
data,
unsigned int len);
454 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
455 static void Init(
const v8::FunctionCallbackInfo<v8::Value>& args);
456 static void InitIv(
const v8::FunctionCallbackInfo<v8::Value>& args);
457 static void Update(
const v8::FunctionCallbackInfo<v8::Value>& args);
458 static void Final(
const v8::FunctionCallbackInfo<v8::Value>& args);
459 static void SetAutoPadding(
const v8::FunctionCallbackInfo<v8::Value>& args);
461 static void GetAuthTag(
const v8::FunctionCallbackInfo<v8::Value>& args);
462 static void SetAuthTag(
const v8::FunctionCallbackInfo<v8::Value>& args);
463 static void SetAAD(
const v8::FunctionCallbackInfo<v8::Value>& args);
465 CipherBase(Environment* env,
466 v8::Local<v8::Object> wrap,
468 : BaseObject(env, wrap),
472 MakeWeak<CipherBase>(
this);
478 const CipherKind kind_;
479 unsigned int auth_tag_len_;
480 char auth_tag_[EVP_GCM_TLS_TAG_LEN];
483 class Hmac :
public BaseObject {
488 HMAC_CTX_cleanup(&ctx_);
491 static void Initialize(Environment* env, v8::Local<v8::Object> target);
494 void HmacInit(
const char* hash_type,
const char* key,
int key_len);
495 bool HmacUpdate(
const char*
data,
int len);
497 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
498 static void HmacInit(
const v8::FunctionCallbackInfo<v8::Value>& args);
499 static void HmacUpdate(
const v8::FunctionCallbackInfo<v8::Value>& args);
500 static void HmacDigest(
const v8::FunctionCallbackInfo<v8::Value>& args);
502 Hmac(Environment* env, v8::Local<v8::Object> wrap)
503 : BaseObject(env, wrap),
504 initialised_(false) {
505 MakeWeak<Hmac>(
this);
513 class Hash :
public BaseObject {
518 EVP_MD_CTX_cleanup(&mdctx_);
521 static void Initialize(Environment* env, v8::Local<v8::Object> target);
523 bool HashInit(
const char* hash_type);
524 bool HashUpdate(
const char*
data,
int len);
527 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
528 static void HashUpdate(
const v8::FunctionCallbackInfo<v8::Value>& args);
529 static void HashDigest(
const v8::FunctionCallbackInfo<v8::Value>& args);
531 Hash(Environment* env, v8::Local<v8::Object> wrap)
532 : BaseObject(env, wrap),
533 initialised_(false) {
534 MakeWeak<Hash>(
this);
543 class SignBase :
public BaseObject {
555 SignBase(Environment* env, v8::Local<v8::Object> wrap)
556 : BaseObject(env, wrap),
557 initialised_(false) {
560 ~SignBase()
override {
563 EVP_MD_CTX_cleanup(&mdctx_);
567 void CheckThrow(Error error);
573 class Sign :
public SignBase {
575 static void Initialize(Environment* env, v8::Local<v8::Object> target);
577 Error SignInit(
const char* sign_type);
578 Error SignUpdate(
const char*
data,
int len);
579 Error SignFinal(
const char* key_pem,
581 const char* passphrase,
583 unsigned int *sig_len,
588 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
589 static void SignInit(
const v8::FunctionCallbackInfo<v8::Value>& args);
590 static void SignUpdate(
const v8::FunctionCallbackInfo<v8::Value>& args);
591 static void SignFinal(
const v8::FunctionCallbackInfo<v8::Value>& args);
593 Sign(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
594 MakeWeak<Sign>(
this);
598 class Verify :
public SignBase {
600 static void Initialize(Environment* env, v8::Local<v8::Object> target);
602 Error VerifyInit(
const char* verify_type);
603 Error VerifyUpdate(
const char*
data,
int len);
604 Error VerifyFinal(
const char* key_pem,
610 bool* verify_result);
613 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
614 static void VerifyInit(
const v8::FunctionCallbackInfo<v8::Value>& args);
615 static void VerifyUpdate(
const v8::FunctionCallbackInfo<v8::Value>& args);
616 static void VerifyFinal(
const v8::FunctionCallbackInfo<v8::Value>& args);
618 Verify(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
619 MakeWeak<Verify>(
this);
623 class PublicKeyCipher {
625 typedef int (*EVP_PKEY_cipher_init_t)(EVP_PKEY_CTX *
ctx);
626 typedef int (*EVP_PKEY_cipher_t)(EVP_PKEY_CTX *
ctx,
627 unsigned char *out,
size_t *outlen,
628 const unsigned char *in,
size_t inlen);
635 template <Operation operation,
636 EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
637 EVP_PKEY_cipher_t EVP_PKEY_cipher>
638 static bool Cipher(
const char* key_pem,
640 const char* passphrase,
642 const unsigned char*
data,
647 template <Operation operation,
648 EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
649 EVP_PKEY_cipher_t EVP_PKEY_cipher>
650 static void Cipher(
const v8::FunctionCallbackInfo<v8::Value>& args);
653 class DiffieHellman :
public BaseObject {
655 ~DiffieHellman()
override {
661 static void Initialize(Environment* env, v8::Local<v8::Object> target);
663 bool Init(
int primeLength,
int g);
664 bool Init(
const char*
p,
int p_len,
int g);
665 bool Init(
const char*
p,
int p_len,
const char* g,
int g_len);
668 static void DiffieHellmanGroup(
669 const v8::FunctionCallbackInfo<v8::Value>& args);
670 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
671 static void GenerateKeys(
const v8::FunctionCallbackInfo<v8::Value>& args);
672 static void GetPrime(
const v8::FunctionCallbackInfo<v8::Value>& args);
673 static void GetGenerator(
const v8::FunctionCallbackInfo<v8::Value>& args);
674 static void GetPublicKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
675 static void GetPrivateKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
676 static void ComputeSecret(
const v8::FunctionCallbackInfo<v8::Value>& args);
677 static void SetPublicKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
678 static void SetPrivateKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
679 static void VerifyErrorGetter(
680 v8::Local<v8::String> property,
681 const v8::PropertyCallbackInfo<v8::Value>& args);
683 DiffieHellman(Environment* env, v8::Local<v8::Object> wrap)
684 : BaseObject(env, wrap),
688 MakeWeak<DiffieHellman>(
this);
692 static void GetField(
const v8::FunctionCallbackInfo<v8::Value>& args,
693 BIGNUM* (DH::*field),
const char* err_if_null);
694 static void SetKey(
const v8::FunctionCallbackInfo<v8::Value>& args,
695 BIGNUM* (DH::*field),
const char* what);
696 bool VerifyContext();
703 class ECDH :
public BaseObject {
712 static void Initialize(Environment* env, v8::Local<v8::Object> target);
715 ECDH(Environment* env, v8::Local<v8::Object> wrap, EC_KEY* key)
716 : BaseObject(env, wrap),
718 group_(EC_KEY_get0_group(key_)) {
719 MakeWeak<ECDH>(
this);
720 CHECK_NE(group_,
nullptr);
723 static void New(
const v8::FunctionCallbackInfo<v8::Value>& args);
724 static void GenerateKeys(
const v8::FunctionCallbackInfo<v8::Value>& args);
725 static void ComputeSecret(
const v8::FunctionCallbackInfo<v8::Value>& args);
726 static void GetPrivateKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
727 static void SetPrivateKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
728 static void GetPublicKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
729 static void SetPublicKey(
const v8::FunctionCallbackInfo<v8::Value>& args);
731 EC_POINT* BufferToPoint(
char*
data,
size_t len);
733 bool IsKeyPairValid();
734 bool IsKeyValidForCurve(
const BIGNUM* private_key);
737 const EC_GROUP* group_;
741 #ifndef OPENSSL_NO_ENGINE 742 void SetEngine(
const v8::FunctionCallbackInfo<v8::Value>& args);
743 #endif // !OPENSSL_NO_ENGINE 744 void InitCrypto(v8::Local<v8::Object> target);
749 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 751 #endif // SRC_NODE_CRYPTO_H_
void SetEngine(const FunctionCallbackInfo< Value > &args)
union node::cares_wrap::@8::CaresAsyncData::@0 data
void InitCrypto(Local< Object > target, Local< Value > unused, Local< Context > context, void *priv)
void UseExtraCaCerts(const std::string &file)
void Initialize(Local< Object > target, Local< Value > unused, Local< Context > context, void *priv)
int VerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
bool EntropySource(unsigned char *buffer, size_t length)
int Start(Isolate *isolate, IsolateData *isolate_data, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)
void Init(int *argc, const char **argv, int *exec_argc, const char ***exec_argv)