GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/node_crypto.h Lines: 115 118 97.5 %
Date: 2017-10-21 Branches: 38 54 70.4 %

Line Branch Exec Source
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
#ifndef SRC_NODE_CRYPTO_H_
23
#define SRC_NODE_CRYPTO_H_
24
25
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26
27
#include "node.h"
28
#include "node_crypto_clienthello.h"  // ClientHelloParser
29
#include "node_crypto_clienthello-inl.h"
30
31
#include "node_buffer.h"
32
33
#include "env.h"
34
#include "async-wrap.h"
35
#include "async-wrap-inl.h"
36
#include "base-object.h"
37
#include "base-object-inl.h"
38
39
#include "v8.h"
40
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>
55
56
#define EVP_F_EVP_DECRYPTFINAL 101
57
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)
61
62
namespace node {
63
namespace crypto {
64
65
// Forcibly clear OpenSSL's error stack on return. This stops stale errors
66
// from popping up later in the lifecycle of crypto operations where they
67
// would cause spurious failures. It's a rather blunt method, though.
68
// ERR_clear_error() isn't necessarily cheap either.
69
struct ClearErrorOnReturn {
70
1963
  ~ClearErrorOnReturn() { ERR_clear_error(); }
71
};
72
73
// Pop errors from OpenSSL's error stack that were added
74
// between when this was constructed and destructed.
75
struct MarkPopErrorOnReturn {
76
10887
  MarkPopErrorOnReturn() { ERR_set_mark(); }
77
10884
  ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
78
};
79
80
enum CheckResult {
81
  CHECK_CERT_REVOKED = 0,
82
  CHECK_OK = 1
83
};
84
85
extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx);
86
87
extern void UseExtraCaCerts(const std::string& file);
88
89
class SecureContext : public BaseObject {
90
 public:
91
1356
  ~SecureContext() override {
92
452
    FreeCTXMem();
93
904
  }
94
95
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
96
97
  SSL_CTX* ctx_;
98
  X509* cert_;
99
  X509* issuer_;
100
101
  static const int kMaxSessionSize = 10 * 1024;
102
103
  // See TicketKeyCallback
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;
109
110
 protected:
111
  static const int64_t kExternalSize = sizeof(SSL_CTX);
112
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);
138
139
  template <bool primary>
140
  static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args);
141
142
  static int TicketKeyCallback(SSL* ssl,
143
                               unsigned char* name,
144
                               unsigned char* iv,
145
                               EVP_CIPHER_CTX* ectx,
146
                               HMAC_CTX* hctx,
147
                               int enc);
148
149
802
  SecureContext(Environment* env, v8::Local<v8::Object> wrap)
150
      : BaseObject(env, wrap),
151
        ctx_(nullptr),
152
        cert_(nullptr),
153
802
        issuer_(nullptr) {
154
802
    MakeWeak<SecureContext>(this);
155
802
    env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
156
802
  }
157
158
794
  void FreeCTXMem() {
159
794
    if (!ctx_) {
160
1136
      return;
161
    }
162
163
452
    env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
164
452
    SSL_CTX_free(ctx_);
165
452
    if (cert_ != nullptr)
166
78
      X509_free(cert_);
167
452
    if (issuer_ != nullptr)
168
4
      X509_free(issuer_);
169
452
    ctx_ = nullptr;
170
452
    cert_ = nullptr;
171
452
    issuer_ = nullptr;
172
  }
173
};
174
175
// SSLWrap implicitly depends on the inheriting class' handle having an
176
// internal pointer to the Base class.
177
template <class Base>
178
class SSLWrap {
179
 public:
180
  enum Kind {
181
    kClient,
182
    kServer
183
  };
184
185
10800
  SSLWrap(Environment* env, SecureContext* sc, Kind kind)
186
      : env_(env),
187
        kind_(kind),
188
        next_sess_(nullptr),
189
        session_callbacks_(false),
190
        new_session_wait_(false),
191
        cert_cb_(nullptr),
192
        cert_cb_arg_(nullptr),
193
21600
        cert_cb_running_(false) {
194
10800
    ssl_ = SSL_new(sc->ctx_);
195
10800
    env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
196
10800
    CHECK_NE(ssl_, nullptr);
197
10800
  }
198
199
10763
  virtual ~SSLWrap() {
200
10763
    DestroySSL();
201
10763
    if (next_sess_ != nullptr) {
202
      SSL_SESSION_free(next_sess_);
203
      next_sess_ = nullptr;
204
    }
205
206
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
207
10763
    sni_context_.Reset();
208
#endif
209
210
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
211
10763
    ocsp_response_.Reset();
212
#endif  // NODE__HAVE_TLSEXT_STATUS_CB
213
21526
  }
214
215
  inline SSL* ssl() const { return ssl_; }
216
10036
  inline void enable_session_callbacks() { session_callbacks_ = true; }
217
3181
  inline bool is_server() const { return kind_ == kServer; }
218
1771
  inline bool is_client() const { return kind_ == kClient; }
219
6180
  inline bool is_waiting_new_session() const { return new_session_wait_; }
220
394
  inline bool is_waiting_cert_cb() const { return cert_cb_ != nullptr; }
221
222
 protected:
223
  typedef void (*CertCb)(void* arg);
224
225
  // Size allocated by OpenSSL: one for SSL structure, one for SSL3_STATE and
226
  // some for buffers.
227
  // NOTE: Actually it is much more than this
228
  static const int64_t kExternalSize =
229
      sizeof(SSL) + sizeof(SSL3_STATE) + 42 * 1024;
230
231
  static void InitNPN(SecureContext* sc);
232
  static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t);
233
234
  static SSL_SESSION* GetSessionCallback(SSL* s,
235
                                         unsigned char* key,
236
                                         int len,
237
                                         int* copy);
238
  static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
239
  static void OnClientHello(void* arg,
240
                            const ClientHelloParser::ClientHello& hello);
241
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);
262
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
267
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,
274
                                        unsigned int* len,
275
                                        void* arg);
276
  static int SelectNextProtoCallback(SSL* s,
277
                                     unsigned char** out,
278
                                     unsigned char* outlen,
279
                                     const unsigned char* in,
280
                                     unsigned int inlen,
281
                                     void* arg);
282
#endif  // OPENSSL_NO_NEXTPROTONEG
283
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,
291
                                unsigned int inlen,
292
                                void* arg);
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);
297
298
  void DestroySSL();
299
  void WaitForCertCb(CertCb cb, void* arg);
300
  void SetSNIContext(SecureContext* sc);
301
  int SetCACerts(SecureContext* sc);
302
303
165
  inline Environment* ssl_env() const {
304
165
    return env_;
305
  }
306
307
  Environment* const env_;
308
  Kind kind_;
309
  SSL_SESSION* next_sess_;
310
  SSL* ssl_;
311
  bool session_callbacks_;
312
  bool new_session_wait_;
313
314
  // SSL_set_cert_cb
315
  CertCb cert_cb_;
316
  void* cert_cb_arg_;
317
  bool cert_cb_running_;
318
319
  ClientHelloParser hello_parser_;
320
321
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
322
  v8::Persistent<v8::Object> ocsp_response_;
323
#endif  // NODE__HAVE_TLSEXT_STATUS_CB
324
325
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
326
  v8::Persistent<v8::Value> sni_context_;
327
#endif
328
329
  friend class SecureContext;
330
};
331
332
// Connection inherits from AsyncWrap because SSLWrap makes calls to
333
// MakeCallback, but SSLWrap doesn't store the handle itself. Instead it
334
// assumes that any args.This() called will be the handle from Connection.
335
class Connection : public AsyncWrap, public SSLWrap<Connection> {
336
 public:
337
30030
  ~Connection() override {
338
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
339
10010
    sniObject_.Reset();
340
10010
    servername_.Reset();
341
#endif
342
20020
  }
343
344
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
345
  void NewSessionDoneCb();
346
347
#ifndef OPENSSL_NO_NEXTPROTONEG
348
  v8::Persistent<v8::Object> npnProtos_;
349
  v8::Persistent<v8::Value> selectedNPNProto_;
350
#endif
351
352
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
353
  v8::Persistent<v8::Object> sniObject_;
354
  v8::Persistent<v8::String> servername_;
355
#endif
356
357
  size_t self_size() const override { return sizeof(*this); }
358
359
 protected:
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);
369
370
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
371
  // SNI
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);
375
#endif
376
377
  static void OnClientHelloParseEnd(void* arg);
378
379
  int HandleBIOError(BIO* bio, const char* func, int rv);
380
381
  enum ZeroStatus {
382
    kZeroIsNotAnError,
383
    kZeroIsAnError
384
  };
385
386
  enum SyscallStatus {
387
    kIgnoreSyscall,
388
    kSyscallError
389
  };
390
391
  int HandleSSLError(const char* func, int rv, ZeroStatus zs, SyscallStatus ss);
392
393
  void SetShutdownFlags();
394
395
10016
  Connection(Environment* env,
396
             v8::Local<v8::Object> wrap,
397
             SecureContext* sc,
398
             SSLWrap<Connection>::Kind kind)
399
      : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_SSLCONNECTION),
400
        SSLWrap<Connection>(env, sc, kind),
401
        bio_read_(nullptr),
402
        bio_write_(nullptr),
403
50080
        hello_offset_(0) {
404
10016
    MakeWeak<Connection>(this);
405
10016
    Wrap(wrap, this);
406
    hello_parser_.Start(SSLWrap<Connection>::OnClientHello,
407
                        OnClientHelloParseEnd,
408
10016
                        this);
409
10016
    enable_session_callbacks();
410
10016
  }
411
412
 private:
413
  static void SSLInfoCallback(const SSL *ssl, int where, int ret);
414
415
  BIO *bio_read_;
416
  BIO *bio_write_;
417
418
  uint8_t hello_data_[18432];
419
  size_t hello_offset_;
420
421
  friend class ClientHelloParser;
422
  friend class SecureContext;
423
};
424
425
class CipherBase : public BaseObject {
426
 public:
427
78
  ~CipherBase() override {
428
26
    if (!initialised_)
429
20
      return;
430
6
    EVP_CIPHER_CTX_cleanup(&ctx_);
431
32
  }
432
433
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
434
435
 protected:
436
  enum CipherKind {
437
    kCipher,
438
    kDecipher
439
  };
440
441
  void Init(const char* cipher_type, const char* key_buf, int key_buf_len);
442
  void InitIv(const char* cipher_type,
443
              const char* key,
444
              int key_len,
445
              const char* iv,
446
              int iv_len);
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);
450
451
  bool IsAuthenticatedMode() const;
452
  bool SetAAD(const char* data, unsigned int len);
453
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);
460
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);
464
465
1021
  CipherBase(Environment* env,
466
             v8::Local<v8::Object> wrap,
467
             CipherKind kind)
468
      : BaseObject(env, wrap),
469
        initialised_(false),
470
        kind_(kind),
471
1021
        auth_tag_len_(0) {
472
1021
    MakeWeak<CipherBase>(this);
473
1021
  }
474
475
 private:
476
  EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
477
  bool initialised_;
478
  const CipherKind kind_;
479
  unsigned int auth_tag_len_;
480
  char auth_tag_[EVP_GCM_TLS_TAG_LEN];
481
};
482
483
class Hmac : public BaseObject {
484
 public:
485
132
  ~Hmac() override {
486
44
    if (!initialised_)
487
43
      return;
488
1
    HMAC_CTX_cleanup(&ctx_);
489
45
  }
490
491
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
492
493
 protected:
494
  void HmacInit(const char* hash_type, const char* key, int key_len);
495
  bool HmacUpdate(const char* data, int len);
496
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);
501
502
133
  Hmac(Environment* env, v8::Local<v8::Object> wrap)
503
      : BaseObject(env, wrap),
504
133
        initialised_(false) {
505
133
    MakeWeak<Hmac>(this);
506
133
  }
507
508
 private:
509
  HMAC_CTX ctx_; /* coverity[member_decl] */
510
  bool initialised_;
511
};
512
513
class Hash : public BaseObject {
514
 public:
515
60978
  ~Hash() override {
516
20326
    if (!initialised_)
517
1
      return;
518
20325
    EVP_MD_CTX_cleanup(&mdctx_);
519
40651
  }
520
521
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
522
523
  bool HashInit(const char* hash_type);
524
  bool HashUpdate(const char* data, int len);
525
526
 protected:
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);
530
531
20472
  Hash(Environment* env, v8::Local<v8::Object> wrap)
532
      : BaseObject(env, wrap),
533
20472
        initialised_(false) {
534
20472
    MakeWeak<Hash>(this);
535
20472
  }
536
537
 private:
538
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
539
  bool initialised_;
540
  bool finalized_;
541
};
542
543
class SignBase : public BaseObject {
544
 public:
545
  typedef enum {
546
    kSignOk,
547
    kSignUnknownDigest,
548
    kSignInit,
549
    kSignNotInitialised,
550
    kSignUpdate,
551
    kSignPrivateKey,
552
    kSignPublicKey
553
  } Error;
554
555
258
  SignBase(Environment* env, v8::Local<v8::Object> wrap)
556
      : BaseObject(env, wrap),
557
258
        initialised_(false) {
558
258
  }
559
560
40
  ~SignBase() override {
561
20
    if (!initialised_)
562
15
      return;
563
5
    EVP_MD_CTX_cleanup(&mdctx_);
564
5
  }
565
566
 protected:
567
  void CheckThrow(Error error);
568
569
  EVP_MD_CTX mdctx_; /* coverity[member_decl] */
570
  bool initialised_;
571
};
572
573
20
class Sign : public SignBase {
574
 public:
575
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
576
577
  Error SignInit(const char* sign_type);
578
  Error SignUpdate(const char* data, int len);
579
  Error SignFinal(const char* key_pem,
580
                  int key_pem_len,
581
                  const char* passphrase,
582
                  unsigned char* sig,
583
                  unsigned int *sig_len,
584
                  int padding,
585
                  int saltlen);
586
587
 protected:
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);
592
593
63
  Sign(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
594
63
    MakeWeak<Sign>(this);
595
63
  }
596
};
597
598
20
class Verify : public SignBase {
599
 public:
600
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
601
602
  Error VerifyInit(const char* verify_type);
603
  Error VerifyUpdate(const char* data, int len);
604
  Error VerifyFinal(const char* key_pem,
605
                    int key_pem_len,
606
                    const char* sig,
607
                    int siglen,
608
                    int padding,
609
                    int saltlen,
610
                    bool* verify_result);
611
612
 protected:
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);
617
618
195
  Verify(Environment* env, v8::Local<v8::Object> wrap) : SignBase(env, wrap) {
619
195
    MakeWeak<Verify>(this);
620
195
  }
621
};
622
623
class PublicKeyCipher {
624
 public:
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);
629
630
  enum Operation {
631
    kPublic,
632
    kPrivate
633
  };
634
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,
639
                     int key_pem_len,
640
                     const char* passphrase,
641
                     int padding,
642
                     const unsigned char* data,
643
                     int len,
644
                     unsigned char** out,
645
                     size_t* out_len);
646
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);
651
};
652
653
class DiffieHellman : public BaseObject {
654
 public:
655
21
  ~DiffieHellman() override {
656
7
    if (dh != nullptr) {
657
7
      DH_free(dh);
658
    }
659
14
  }
660
661
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
662
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);
666
667
 protected:
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);
682
683
35
  DiffieHellman(Environment* env, v8::Local<v8::Object> wrap)
684
      : BaseObject(env, wrap),
685
        initialised_(false),
686
        verifyError_(0),
687
35
        dh(nullptr) {
688
35
    MakeWeak<DiffieHellman>(this);
689
35
  }
690
691
 private:
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();
697
698
  bool initialised_;
699
  int verifyError_;
700
  DH* dh;
701
};
702
703
class ECDH : public BaseObject {
704
 public:
705
3
  ~ECDH() override {
706
1
    if (key_ != nullptr)
707
1
      EC_KEY_free(key_);
708
1
    key_ = nullptr;
709
1
    group_ = nullptr;
710
2
  }
711
712
  static void Initialize(Environment* env, v8::Local<v8::Object> target);
713
714
 protected:
715
8
  ECDH(Environment* env, v8::Local<v8::Object> wrap, EC_KEY* key)
716
      : BaseObject(env, wrap),
717
        key_(key),
718
8
        group_(EC_KEY_get0_group(key_)) {
719
8
    MakeWeak<ECDH>(this);
720
8
    CHECK_NE(group_, nullptr);
721
8
  }
722
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);
730
731
  EC_POINT* BufferToPoint(char* data, size_t len);
732
733
  bool IsKeyPairValid();
734
  bool IsKeyValidForCurve(const BIGNUM* private_key);
735
736
  EC_KEY* key_;
737
  const EC_GROUP* group_;
738
};
739
740
bool EntropySource(unsigned char* buffer, size_t length);
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);
745
746
}  // namespace crypto
747
}  // namespace node
748
749
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
750
751
#endif  // SRC_NODE_CRYPTO_H_