GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/out/../src/node_crypto.h Lines: 92 107 86.0 %
Date: 2016-11-20 Branches: 18 30 60.0 %

Line Branch Exec Source
1
#ifndef SRC_NODE_CRYPTO_H_
2
#define SRC_NODE_CRYPTO_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "node.h"
7
#include "node_crypto_clienthello.h"  // ClientHelloParser
8
#include "node_crypto_clienthello-inl.h"
9
10
#include "node_buffer.h"
11
12
#include "env.h"
13
#include "async-wrap.h"
14
#include "async-wrap-inl.h"
15
#include "base-object.h"
16
#include "base-object-inl.h"
17
18
#include "v8.h"
19
20
#include <openssl/ssl.h>
21
#include <openssl/ec.h>
22
#include <openssl/ecdh.h>
23
#ifndef OPENSSL_NO_ENGINE
24
# include <openssl/engine.h>
25
#endif  // !OPENSSL_NO_ENGINE
26
#include <openssl/err.h>
27
#include <openssl/evp.h>
28
#include <openssl/pem.h>
29
#include <openssl/x509.h>
30
#include <openssl/x509v3.h>
31
#include <openssl/hmac.h>
32
#include <openssl/rand.h>
33
#include <openssl/pkcs12.h>
34
35
#define EVP_F_EVP_DECRYPTFINAL 101
36
37
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
38
# define NODE__HAVE_TLSEXT_STATUS_CB
39
#endif  // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
40
41
namespace node {
42
namespace crypto {
43
44
// Forcibly clear OpenSSL's error stack on return. This stops stale errors
45
// from popping up later in the lifecycle of crypto operations where they
46
// would cause spurious failures. It's a rather blunt method, though.
47
// ERR_clear_error() isn't necessarily cheap either.
48
struct ClearErrorOnReturn {
49
1192
  ~ClearErrorOnReturn() { ERR_clear_error(); }
50
};
51
52
// Pop errors from OpenSSL's error stack that were added
53
// between when this was constructed and destructed.
54
struct MarkPopErrorOnReturn {
55
8963
  MarkPopErrorOnReturn() { ERR_set_mark(); }
56
6574
  ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
57
};
58
59
enum CheckResult {
60
  CHECK_CERT_REVOKED = 0,
61
  CHECK_OK = 1
62
};
63
64
extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx);
65
66
extern X509_STORE* root_cert_store;
67
68
// Forward declaration
69
class Connection;
70
71
class SecureContext : public BaseObject {
72
 public:
73
124
  ~SecureContext() override {
74
31
    FreeCTXMem();
75
62
  }
76
77
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
78
79
  SSL_CTX* ctx_;
80
  X509* cert_;
81
  X509* issuer_;
82
83
  static const int kMaxSessionSize = 10 * 1024;
84
85
  // See TicketKeyCallback
86
  static const int kTicketKeyReturnIndex = 0;
87
  static const int kTicketKeyHMACIndex = 1;
88
  static const int kTicketKeyAESIndex = 2;
89
  static const int kTicketKeyNameIndex = 3;
90
  static const int kTicketKeyIVIndex = 4;
91
92
 protected:
93
  static const int64_t kExternalSize = sizeof(SSL_CTX);
94
95
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
96
  static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
97
  static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args);
98
  static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args);
99
  static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args);
100
  static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args);
101
  static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args);
102
  static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args);
103
  static void SetECDHCurve(const v8::FunctionCallbackInfo<v8::Value>& args);
104
  static void SetDHParam(const v8::FunctionCallbackInfo<v8::Value>& args);
105
  static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
106
  static void SetSessionIdContext(
107
      const v8::FunctionCallbackInfo<v8::Value>& args);
108
  static void SetSessionTimeout(
109
      const v8::FunctionCallbackInfo<v8::Value>& args);
110
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
111
  static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args);
112
  static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
113
  static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
114
  static void SetFreeListLength(
115
      const v8::FunctionCallbackInfo<v8::Value>& args);
116
  static void EnableTicketKeyCallback(
117
      const v8::FunctionCallbackInfo<v8::Value>& args);
118
  static void CtxGetter(v8::Local<v8::String> property,
119
                        const v8::PropertyCallbackInfo<v8::Value>& info);
120
121
  template <bool primary>
122
  static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args);
123
124
  static int TicketKeyCallback(SSL* ssl,
125
                               unsigned char* name,
126
                               unsigned char* iv,
127
                               EVP_CIPHER_CTX* ectx,
128
                               HMAC_CTX* hctx,
129
                               int enc);
130
131
514
  SecureContext(Environment* env, v8::Local<v8::Object> wrap)
132
      : BaseObject(env, wrap),
133
        ctx_(nullptr),
134
        cert_(nullptr),
135
514
        issuer_(nullptr) {
136
514
    MakeWeak<SecureContext>(this);
137
1028
    env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
138
514
  }
139
140
302
  void FreeCTXMem() {
141
302
    if (!ctx_) {
142
      return;
143
    }
144
145
542
    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
146
271
    SSL_CTX_free(ctx_);
147
271
    if (cert_ != nullptr)
148
26
      X509_free(cert_);
149
271
    if (issuer_ != nullptr)
150
2
      X509_free(issuer_);
151
271
    ctx_ = nullptr;
152
271
    cert_ = nullptr;
153
271
    issuer_ = nullptr;
154
  }
155
};
156
157
// SSLWrap implicitly depends on the inheriting class' handle having an
158
// internal pointer to the Base class.
159
template <class Base>
160
class SSLWrap {
161
 public:
162
  enum Kind {
163
    kClient,
164
    kServer
165
  };
166
167
608
  SSLWrap(Environment* env, SecureContext* sc, Kind kind)
168
      : env_(env),
169
        kind_(kind),
170
        next_sess_(nullptr),
171
        session_callbacks_(false),
172
        new_session_wait_(false),
173
        cert_cb_(nullptr),
174
        cert_cb_arg_(nullptr),
175
2432
        cert_cb_running_(false) {
176
608
    ssl_ = SSL_new(sc->ctx_);
177
1216
    env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
178

608
    CHECK_NE(ssl_, nullptr);
179
608
  }
180
181
60
  virtual ~SSLWrap() {
182
60
    DestroySSL();
183

60
    if (next_sess_ != nullptr) {
184
      SSL_SESSION_free(next_sess_);
185
      next_sess_ = nullptr;
186
    }
187
188
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
189
120
    sni_context_.Reset();
190
#endif
191
192
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
193
120
    ocsp_response_.Reset();
194
#endif  // NODE__HAVE_TLSEXT_STATUS_CB
195
240
  }
196
197
  inline SSL* ssl() const { return ssl_; }
198
20
  inline void enable_session_callbacks() { session_callbacks_ = true; }
199
603
  inline bool is_server() const { return kind_ == kServer; }
200
699
  inline bool is_client() const { return kind_ == kClient; }
201
  inline bool is_waiting_new_session() const { return new_session_wait_; }
202
304
  inline bool is_waiting_cert_cb() const { return cert_cb_ != nullptr; }
203
204
 protected:
205
  typedef void (*CertCb)(void* arg);
206
207
  // Size allocated by OpenSSL: one for SSL structure, one for SSL3_STATE and
208
  // some for buffers.
209
  // NOTE: Actually it is much more than this
210
  static const int64_t kExternalSize =
211
      sizeof(SSL) + sizeof(SSL3_STATE) + 42 * 1024;
212
213
  static void InitNPN(SecureContext* sc);
214
  static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t);
215
216
  static SSL_SESSION* GetSessionCallback(SSL* s,
217
                                         unsigned char* key,
218
                                         int len,
219
                                         int* copy);
220
  static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
221
  static void OnClientHello(void* arg,
222
                            const ClientHelloParser::ClientHello& hello);
223
224
  static void GetPeerCertificate(
225
      const v8::FunctionCallbackInfo<v8::Value>& args);
226
  static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
227
  static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args);
228
  static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args);
229
  static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args);
230
  static void IsInitFinished(const v8::FunctionCallbackInfo<v8::Value>& args);
231
  static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args);
232
  static void GetCurrentCipher(const v8::FunctionCallbackInfo<v8::Value>& args);
233
  static void EndParser(const v8::FunctionCallbackInfo<v8::Value>& args);
234
  static void CertCbDone(const v8::FunctionCallbackInfo<v8::Value>& args);
235
  static void Renegotiate(const v8::FunctionCallbackInfo<v8::Value>& args);
236
  static void Shutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
237
  static void GetTLSTicket(const v8::FunctionCallbackInfo<v8::Value>& args);
238
  static void NewSessionDone(const v8::FunctionCallbackInfo<v8::Value>& args);
239
  static void SetOCSPResponse(const v8::FunctionCallbackInfo<v8::Value>& args);
240
  static void RequestOCSP(const v8::FunctionCallbackInfo<v8::Value>& args);
241
  static void GetEphemeralKeyInfo(
242
      const v8::FunctionCallbackInfo<v8::Value>& args);
243
  static void GetProtocol(const v8::FunctionCallbackInfo<v8::Value>& args);
244
245
#ifdef SSL_set_max_send_fragment
246
  static void SetMaxSendFragment(
247
      const v8::FunctionCallbackInfo<v8::Value>& args);
248
#endif  // SSL_set_max_send_fragment
249
250
#ifdef OPENSSL_NPN_NEGOTIATED
251
  static void GetNegotiatedProto(
252
      const v8::FunctionCallbackInfo<v8::Value>& args);
253
  static void SetNPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args);
254
  static int AdvertiseNextProtoCallback(SSL* s,
255
                                        const unsigned char** data,
256
                                        unsigned int* len,
257
                                        void* arg);
258
  static int SelectNextProtoCallback(SSL* s,
259
                                     unsigned char** out,
260
                                     unsigned char* outlen,
261
                                     const unsigned char* in,
262
                                     unsigned int inlen,
263
                                     void* arg);
264
#endif  // OPENSSL_NPN_NEGOTIATED
265
266
  static void GetALPNNegotiatedProto(
267
      const v8::FunctionCallbackInfo<v8::Value>& args);
268
  static void SetALPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args);
269
  static int SelectALPNCallback(SSL* s,
270
                                const unsigned char** out,
271
                                unsigned char* outlen,
272
                                const unsigned char* in,
273
                                unsigned int inlen,
274
                                void* arg);
275
  static int TLSExtStatusCallback(SSL* s, void* arg);
276
  static int SSLCertCallback(SSL* s, void* arg);
277
  static void SSLGetter(v8::Local<v8::String> property,
278
                        const v8::PropertyCallbackInfo<v8::Value>& info);
279
280
  void DestroySSL();
281
  void WaitForCertCb(CertCb cb, void* arg);
282
  void SetSNIContext(SecureContext* sc);
283
  int SetCACerts(SecureContext* sc);
284
285
  inline Environment* ssl_env() const {
286
89
    return env_;
287
  }
288
289
  Environment* const env_;
290
  Kind kind_;
291
  SSL_SESSION* next_sess_;
292
  SSL* ssl_;
293
  bool session_callbacks_;
294
  bool new_session_wait_;
295
296
  // SSL_set_cert_cb
297
  CertCb cert_cb_;
298
  void* cert_cb_arg_;
299
  bool cert_cb_running_;
300
301
  ClientHelloParser hello_parser_;
302
303
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
304
  v8::Persistent<v8::Object> ocsp_response_;
305
#endif  // NODE__HAVE_TLSEXT_STATUS_CB
306
307
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
308
  v8::Persistent<v8::Value> sni_context_;
309
#endif
310
311
  friend class SecureContext;
312
};
313
314
// Connection inherits from AsyncWrap because SSLWrap makes calls to
315
// MakeCallback, but SSLWrap doesn't store the handle itself. Instead it
316
// assumes that any args.This() called will be the handle from Connection.
317
class Connection : public AsyncWrap, public SSLWrap<Connection> {
318
 public:
319
  ~Connection() override {
320
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
321
    sniObject_.Reset();
322
    servername_.Reset();
323
#endif
324
  }
325
326
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
327
  void NewSessionDoneCb();
328
329
#ifdef OPENSSL_NPN_NEGOTIATED
330
  v8::Persistent<v8::Object> npnProtos_;
331
  v8::Persistent<v8::Value> selectedNPNProto_;
332
#endif
333
334
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
335
  v8::Persistent<v8::Object> sniObject_;
336
  v8::Persistent<v8::String> servername_;
337
#endif
338
339
  size_t self_size() const override { return sizeof(*this); }
340
341
 protected:
342
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
343
  static void EncIn(const v8::FunctionCallbackInfo<v8::Value>& args);
344
  static void ClearOut(const v8::FunctionCallbackInfo<v8::Value>& args);
345
  static void ClearPending(const v8::FunctionCallbackInfo<v8::Value>& args);
346
  static void EncPending(const v8::FunctionCallbackInfo<v8::Value>& args);
347
  static void EncOut(const v8::FunctionCallbackInfo<v8::Value>& args);
348
  static void ClearIn(const v8::FunctionCallbackInfo<v8::Value>& args);
349
  static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
350
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
351
352
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
353
  // SNI
354
  static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
355
  static void SetSNICallback(const v8::FunctionCallbackInfo<v8::Value>& args);
356
  static int SelectSNIContextCallback_(SSL* s, int* ad, void* arg);
357
#endif
358
359
  static void OnClientHelloParseEnd(void* arg);
360
361
  int HandleBIOError(BIO* bio, const char* func, int rv);
362
363
  enum ZeroStatus {
364
    kZeroIsNotAnError,
365
    kZeroIsAnError
366
  };
367
368
  enum SyscallStatus {
369
    kIgnoreSyscall,
370
    kSyscallError
371
  };
372
373
  int HandleSSLError(const char* func, int rv, ZeroStatus zs, SyscallStatus ss);
374
375
  void ClearError();
376
  void SetShutdownFlags();
377
378
6
  Connection(Environment* env,
379
             v8::Local<v8::Object> wrap,
380
             SecureContext* sc,
381
             SSLWrap<Connection>::Kind kind)
382
      : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_CRYPTO),
383
        SSLWrap<Connection>(env, sc, kind),
384
        bio_read_(nullptr),
385
        bio_write_(nullptr),
386
30
        hello_offset_(0) {
387
6
    MakeWeak<Connection>(this);
388
6
    hello_parser_.Start(SSLWrap<Connection>::OnClientHello,
389
                        OnClientHelloParseEnd,
390
6
                        this);
391
6
    enable_session_callbacks();
392
6
  }
393
394
 private:
395
  static void SSLInfoCallback(const SSL *ssl, int where, int ret);
396
397
  BIO *bio_read_;
398
  BIO *bio_write_;
399
400
  uint8_t hello_data_[18432];
401
  size_t hello_offset_;
402
403
  friend class ClientHelloParser;
404
  friend class SecureContext;
405
};
406
407
class CipherBase : public BaseObject {
408
 public:
409
2078
  ~CipherBase() override {
410
668
    if (!initialised_)
411
      return;
412
74
    delete[] auth_tag_;
413
74
    EVP_CIPHER_CTX_cleanup(&ctx_);
414
1336
  }
415
416
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
417
418
 protected:
419
  enum CipherKind {
420
    kCipher,
421
    kDecipher
422
  };
423
424
  void Init(const char* cipher_type, const char* key_buf, int key_buf_len);
425
  void InitIv(const char* cipher_type,
426
              const char* key,
427
              int key_len,
428
              const char* iv,
429
              int iv_len);
430
  bool Update(const char* data, int len, unsigned char** out, int* out_len);
431
  bool Final(unsigned char** out, int *out_len);
432
  bool SetAutoPadding(bool auto_padding);
433
434
  bool IsAuthenticatedMode() const;
435
  bool GetAuthTag(char** out, unsigned int* out_len) const;
436
  bool SetAuthTag(const char* data, unsigned int len);
437
  bool SetAAD(const char* data, unsigned int len);
438
439
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
440
  static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
441
  static void InitIv(const v8::FunctionCallbackInfo<v8::Value>& args);
442
  static void Update(const v8::FunctionCallbackInfo<v8::Value>& args);
443
  static void Final(const v8::FunctionCallbackInfo<v8::Value>& args);
444
  static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args);
445
446
  static void GetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args);
447
  static void SetAuthTag(const v8::FunctionCallbackInfo<v8::Value>& args);
448
  static void SetAAD(const v8::FunctionCallbackInfo<v8::Value>& args);
449
450
1001
  CipherBase(Environment* env,
451
             v8::Local<v8::Object> wrap,
452
             CipherKind kind)
453
      : BaseObject(env, wrap),
454
        cipher_(nullptr),
455
        initialised_(false),
456
        kind_(kind),
457
        auth_tag_(nullptr),
458
1001
        auth_tag_len_(0) {
459
1001
    MakeWeak<CipherBase>(this);
460
1001
  }
461
462
 private:
463
  EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
464
  const EVP_CIPHER* cipher_; /* coverity[member_decl] */
465
  bool initialised_;
466
  CipherKind kind_;
467
  char* auth_tag_;
468
  unsigned int auth_tag_len_;
469
};
470
471
class Hmac : public BaseObject {
472
 public:
473
165
  ~Hmac() override {
474
55
    if (!initialised_)
475
      return;
476
    HMAC_CTX_cleanup(&ctx_);
477
110
  }
478
479
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
480
481
 protected:
482
  void HmacInit(const char* hash_type, const char* key, int key_len);
483
  bool HmacUpdate(const char* data, int len);
484
  bool HmacDigest(unsigned char** md_value, unsigned int* md_len);
485
486
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
487
  static void HmacInit(const v8::FunctionCallbackInfo<v8::Value>& args);
488
  static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
489
  static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
490
491
  Hmac(Environment* env, v8::Local<v8::Object> wrap)
492
      : BaseObject(env, wrap),
493
126
        initialised_(false) {
494
126
    MakeWeak<Hmac>(this);
495
  }
496
497
 private:
498
  HMAC_CTX ctx_; /* coverity[member_decl] */
499
  bool initialised_;
500
};
501
502
class Hash : public BaseObject {
503
 public:
504
91
  ~Hash() override {
505
23
    if (!initialised_)
506
      return;
507
22
    EVP_MD_CTX_cleanup(&mdctx_);
508
46
  }
509
510
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
511
512
  bool HashInit(const char* hash_type);
513
  bool HashUpdate(const char* data, int len);
514
515
 protected:
516
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
517
  static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
518
  static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);
519
520
  Hash(Environment* env, v8::Local<v8::Object> wrap)
521
      : BaseObject(env, wrap),
522
228
        initialised_(false) {
523
228
    MakeWeak<Hash>(this);
524
  }
525
526
 private:
527
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
528
  bool initialised_;
529
  bool finalized_;
530
};
531
532
class SignBase : public BaseObject {
533
 public:
534
  typedef enum {
535
    kSignOk,
536
    kSignUnknownDigest,
537
    kSignInit,
538
    kSignNotInitialised,
539
    kSignUpdate,
540
    kSignPrivateKey,
541
    kSignPublicKey
542
  } Error;
543
544
  SignBase(Environment* env, v8::Local<v8::Object> wrap)
545
      : BaseObject(env, wrap),
546
40
        initialised_(false) {
547
  }
548
549
  ~SignBase() override {
550
    if (!initialised_)
551
      return;
552
    EVP_MD_CTX_cleanup(&mdctx_);
553
  }
554
555
 protected:
556
  void CheckThrow(Error error);
557
558
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
559
  bool initialised_;
560
};
561
562
class Sign : public SignBase {
563
 public:
564
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
565
566
  Error SignInit(const char* sign_type);
567
  Error SignUpdate(const char* data, int len);
568
  Error SignFinal(const char* key_pem,
569
                  int key_pem_len,
570
                  const char* passphrase,
571
                  unsigned char** sig,
572
                  unsigned int *sig_len);
573
574
 protected:
575
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
576
  static void SignInit(const v8::FunctionCallbackInfo<v8::Value>& args);
577
  static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
578
  static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
579
580
42
  Sign(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
581
21
    MakeWeak<Sign>(this);
582
21
  }
583
};
584
585
class Verify : public SignBase {
586
 public:
587
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
588
589
  Error VerifyInit(const char* verify_type);
590
  Error VerifyUpdate(const char* data, int len);
591
  Error VerifyFinal(const char* key_pem,
592
                    int key_pem_len,
593
                    const char* sig,
594
                    int siglen,
595
                    bool* verify_result);
596
597
 protected:
598
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
599
  static void VerifyInit(const v8::FunctionCallbackInfo<v8::Value>& args);
600
  static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
601
  static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args);
602
603
38
  Verify(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
604
19
    MakeWeak<Verify>(this);
605
19
  }
606
};
607
608
class PublicKeyCipher {
609
 public:
610
  typedef int (*EVP_PKEY_cipher_init_t)(EVP_PKEY_CTX *ctx);
611
  typedef int (*EVP_PKEY_cipher_t)(EVP_PKEY_CTX *ctx,
612
                                   unsigned char *out, size_t *outlen,
613
                                   const unsigned char *in, size_t inlen);
614
615
  enum Operation {
616
    kPublic,
617
    kPrivate
618
  };
619
620
  template <Operation operation,
621
            EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
622
            EVP_PKEY_cipher_t EVP_PKEY_cipher>
623
  static bool Cipher(const char* key_pem,
624
                     int key_pem_len,
625
                     const char* passphrase,
626
                     int padding,
627
                     const unsigned char* data,
628
                     int len,
629
                     unsigned char** out,
630
                     size_t* out_len);
631
632
  template <Operation operation,
633
            EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
634
            EVP_PKEY_cipher_t EVP_PKEY_cipher>
635
  static void Cipher(const v8::FunctionCallbackInfo<v8::Value>& args);
636
};
637
638
class DiffieHellman : public BaseObject {
639
 public:
640
52
  ~DiffieHellman() override {
641
13
    if (dh != nullptr) {
642
13
      DH_free(dh);
643
    }
644
26
  }
645
646
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
647
648
  bool Init(int primeLength, int g);
649
  bool Init(const char* p, int p_len, int g);
650
  bool Init(const char* p, int p_len, const char* g, int g_len);
651
652
 protected:
653
  static void DiffieHellmanGroup(
654
      const v8::FunctionCallbackInfo<v8::Value>& args);
655
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
656
  static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
657
  static void GetPrime(const v8::FunctionCallbackInfo<v8::Value>& args);
658
  static void GetGenerator(const v8::FunctionCallbackInfo<v8::Value>& args);
659
  static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
660
  static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
661
  static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args);
662
  static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
663
  static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
664
  static void VerifyErrorGetter(
665
      v8::Local<v8::String> property,
666
      const v8::PropertyCallbackInfo<v8::Value>& args);
667
668
18
  DiffieHellman(Environment* env, v8::Local<v8::Object> wrap)
669
      : BaseObject(env, wrap),
670
        initialised_(false),
671
        verifyError_(0),
672
18
        dh(nullptr) {
673
18
    MakeWeak<DiffieHellman>(this);
674
18
  }
675
676
 private:
677
  bool VerifyContext();
678
679
  bool initialised_;
680
  int verifyError_;
681
  DH* dh;
682
};
683
684
class ECDH : public BaseObject {
685
 public:
686
8
  ~ECDH() override {
687
2
    if (key_ != nullptr)
688
2
      EC_KEY_free(key_);
689
2
    key_ = nullptr;
690
2
    group_ = nullptr;
691
4
  }
692
693
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
694
695
 protected:
696
6
  ECDH(Environment* env, v8::Local<v8::Object> wrap, EC_KEY* key)
697
      : BaseObject(env, wrap),
698
        key_(key),
699
6
        group_(EC_KEY_get0_group(key_)) {
700
6
    MakeWeak<ECDH>(this);
701
6
    ASSERT_NE(group_, nullptr);
702
6
  }
703
704
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
705
  static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
706
  static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args);
707
  static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
708
  static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
709
  static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
710
  static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
711
712
  EC_POINT* BufferToPoint(char* data, size_t len);
713
714
  bool IsKeyPairValid();
715
  bool IsKeyValidForCurve(const BIGNUM* private_key);
716
717
  EC_KEY* key_;
718
  const EC_GROUP* group_;
719
};
720
721
bool EntropySource(unsigned char* buffer, size_t length);
722
#ifndef OPENSSL_NO_ENGINE
723
void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
724
#endif  // !OPENSSL_NO_ENGINE
725
void InitCrypto(v8::Local<v8::Object> target);
726
727
}  // namespace crypto
728
}  // namespace node
729
730
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
731
732
#endif  // SRC_NODE_CRYPTO_H_