GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/src/node_crypto.h Lines: 101 114 88.6 %
Date: 2016-07-26 Branches: 20 34 58.8 %

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