GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/crypto/crypto_sig.cc Lines: 427 489 87.3 %
Date: 2020-11-20 19:51:53 Branches: 244 367 66.5 %

Line Branch Exec Source
1
#include "crypto/crypto_sig.h"
2
#include "crypto/crypto_ecdh.h"
3
#include "crypto/crypto_keys.h"
4
#include "crypto/crypto_util.h"
5
#include "allocated_buffer-inl.h"
6
#include "async_wrap-inl.h"
7
#include "base_object-inl.h"
8
#include "env-inl.h"
9
#include "memory_tracker-inl.h"
10
#include "threadpoolwork-inl.h"
11
#include "v8.h"
12
13
namespace node {
14
15
using v8::FunctionCallbackInfo;
16
using v8::FunctionTemplate;
17
using v8::HandleScope;
18
using v8::Int32;
19
using v8::Just;
20
using v8::Local;
21
using v8::Maybe;
22
using v8::Nothing;
23
using v8::Object;
24
using v8::Uint32;
25
using v8::Value;
26
27
namespace crypto {
28
namespace {
29
180
bool ValidateDSAParameters(EVP_PKEY* key) {
30
#ifdef NODE_FIPS_MODE
31
  /* Validate DSA2 parameters from FIPS 186-4 */
32
  if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
33
    DSA* dsa = EVP_PKEY_get0_DSA(key);
34
    const BIGNUM* p;
35
    DSA_get0_pqg(dsa, &p, nullptr, nullptr);
36
    size_t L = BN_num_bits(p);
37
    const BIGNUM* q;
38
    DSA_get0_pqg(dsa, nullptr, &q, nullptr);
39
    size_t N = BN_num_bits(q);
40
41
    return (L == 1024 && N == 160) ||
42
           (L == 2048 && N == 224) ||
43
           (L == 2048 && N == 256) ||
44
           (L == 3072 && N == 256);
45
  }
46
#endif  // NODE_FIPS_MODE
47
48
180
  return true;
49
}
50
51
1486
bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
52
                     EVP_PKEY_CTX* pkctx,
53
                     int padding,
54
                     const Maybe<int>& salt_len) {
55

3427
  if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
56

1941
      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
57
455
      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
58
1206
    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
59
3
      return false;
60

2228
    if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
61
976
      if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0)
62
6
        return false;
63
    }
64
  }
65
66
1477
  return true;
67
}
68
69
112
AllocatedBuffer Node_SignFinal(Environment* env,
70
                               EVPMDPointer&& mdctx,
71
                               const ManagedEVPPKey& pkey,
72
                               int padding,
73
                               Maybe<int> pss_salt_len) {
74
  unsigned char m[EVP_MAX_MD_SIZE];
75
  unsigned int m_len;
76
77
112
  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
78
    return AllocatedBuffer();
79
80
112
  int signed_sig_len = EVP_PKEY_size(pkey.get());
81
112
  CHECK_GE(signed_sig_len, 0);
82
112
  size_t sig_len = static_cast<size_t>(signed_sig_len);
83
224
  AllocatedBuffer sig = AllocatedBuffer::AllocateManaged(env, sig_len);
84
112
  unsigned char* ptr = reinterpret_cast<unsigned char*>(sig.data());
85
86
224
  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
87

224
  if (pkctx &&
88
336
      EVP_PKEY_sign_init(pkctx.get()) &&
89
216
      ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
90

314
      EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) &&
91
98
      EVP_PKEY_sign(pkctx.get(), ptr, &sig_len, m, m_len)) {
92
97
    sig.Resize(sig_len);
93
97
    return sig;
94
  }
95
96
15
  return AllocatedBuffer();
97
}
98
99
1404
int GetDefaultSignPadding(const ManagedEVPPKey& key) {
100
1404
  return EVP_PKEY_id(key.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
101
1404
                                                      RSA_PKCS1_PADDING;
102
}
103
104
24
unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
105
24
  int bits, base_id = EVP_PKEY_base_id(pkey.get());
106
107
24
  if (base_id == EVP_PKEY_DSA) {
108
9
    DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get());
109
    // Both r and s are computed mod q, so their width is limited by that of q.
110
9
    bits = BN_num_bits(DSA_get0_q(dsa_key));
111
15
  } else if (base_id == EVP_PKEY_EC) {
112
13
    EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
113
13
    const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
114
13
    bits = EC_GROUP_order_bits(ec_group);
115
  } else {
116
2
    return kNoDsaSignature;
117
  }
118
119
22
  return (bits + 7) / 8;
120
}
121
122
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
123
3
AllocatedBuffer ConvertSignatureToP1363(Environment* env,
124
                                        const ManagedEVPPKey& pkey,
125
                                        AllocatedBuffer&& signature) {
126
3
  unsigned int n = GetBytesOfRS(pkey);
127
3
  if (n == kNoDsaSignature)
128
1
    return std::move(signature);
129
130
  const unsigned char* sig_data =
131
2
      reinterpret_cast<unsigned char*>(signature.data());
132
133
4
  ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, signature.size()));
134
2
  if (!asn1_sig)
135
    return AllocatedBuffer();
136
137
4
  AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, 2 * n);
138
2
  unsigned char* data = reinterpret_cast<unsigned char*>(buf.data());
139
140
2
  const BIGNUM* r = ECDSA_SIG_get0_r(asn1_sig.get());
141
2
  const BIGNUM* s = ECDSA_SIG_get0_s(asn1_sig.get());
142
2
  CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(r, data, n)));
143
2
  CHECK_EQ(n, static_cast<unsigned int>(BN_bn2binpad(s, data + n, n)));
144
145
2
  return buf;
146
}
147
148
149
21
ByteSource ConvertSignatureToDER(
150
      const ManagedEVPPKey& pkey,
151
      const ArrayBufferOrViewContents<char>& signature) {
152
21
  unsigned int n = GetBytesOfRS(pkey);
153
21
  if (n == kNoDsaSignature)
154
1
    return signature.ToByteSource();
155
156
  const unsigned char* sig_data =
157
20
      reinterpret_cast<const  unsigned char*>(signature.data());
158
159
20
  if (signature.size() != 2 * n)
160
12
    return ByteSource();
161
162
16
  ECDSASigPointer asn1_sig(ECDSA_SIG_new());
163
8
  CHECK(asn1_sig);
164
8
  BIGNUM* r = BN_new();
165
8
  CHECK_NOT_NULL(r);
166
8
  BIGNUM* s = BN_new();
167
8
  CHECK_NOT_NULL(s);
168
8
  CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
169
8
  CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
170
8
  CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
171
172
8
  unsigned char* data = nullptr;
173
8
  int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
174
175
8
  if (len <= 0)
176
    return ByteSource();
177
178
8
  CHECK_NOT_NULL(data);
179
180
8
  return ByteSource::Allocated(reinterpret_cast<char*>(data), len);
181
}
182
183
1481
void CheckThrow(Environment* env, SignBase::Error error) {
184
1481
  HandleScope scope(env->isolate());
185
186

1481
  switch (error) {
187
    case SignBase::Error::kSignUnknownDigest:
188
2
      return THROW_ERR_CRYPTO_INVALID_DIGEST(env);
189
190
    case SignBase::Error::kSignNotInitialised:
191
      return THROW_ERR_CRYPTO_INVALID_STATE(env, "Not initialised");
192
193
    case SignBase::Error::kSignMalformedSignature:
194
12
      return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Malformed signature");
195
196
    case SignBase::Error::kSignInit:
197
    case SignBase::Error::kSignUpdate:
198
    case SignBase::Error::kSignPrivateKey:
199
    case SignBase::Error::kSignPublicKey:
200
      {
201
16
        unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
202
16
        if (err)
203
16
          return ThrowCryptoError(env, err);
204
        switch (error) {
205
          case SignBase::Error::kSignInit:
206
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
207
                "EVP_SignInit_ex failed");
208
          case SignBase::Error::kSignUpdate:
209
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
210
                "EVP_SignUpdate failed");
211
          case SignBase::Error::kSignPrivateKey:
212
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
213
                "PEM_read_bio_PrivateKey failed");
214
          case SignBase::Error::kSignPublicKey:
215
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
216
                "PEM_read_bio_PUBKEY failed");
217
          default:
218
            ABORT();
219
        }
220
      }
221
222
    case SignBase::Error::kSignOk:
223
1451
      return;
224
  }
225
}
226
}  // namespace
227
228
728
SignBase::Error SignBase::Init(const char* sign_type) {
229
728
  CHECK_NULL(mdctx_);
230
  // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
231
  // exposed through the public API.
232

1456
  if (strcmp(sign_type, "dss1") == 0 ||
233
728
      strcmp(sign_type, "DSS1") == 0) {
234
2
    sign_type = "SHA1";
235
  }
236
728
  const EVP_MD* md = EVP_get_digestbyname(sign_type);
237
728
  if (md == nullptr)
238
1
    return kSignUnknownDigest;
239
240
727
  mdctx_.reset(EVP_MD_CTX_new());
241

727
  if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) {
242
    mdctx_.reset();
243
    return kSignInit;
244
  }
245
246
727
  return kSignOk;
247
}
248
249
724
SignBase::Error SignBase::Update(const char* data, size_t len) {
250
724
  if (mdctx_ == nullptr)
251
    return kSignNotInitialised;
252
724
  if (!EVP_DigestUpdate(mdctx_.get(), data, len))
253
    return kSignUpdate;
254
724
  return kSignOk;
255
}
256
257
728
SignBase::SignBase(Environment* env, Local<Object> wrap)
258
728
    : BaseObject(env, wrap) {}
259
260
void SignBase::MemoryInfo(MemoryTracker* tracker) const {
261
  tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0);
262
}
263
264
139
Sign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) {
265
139
  MakeWeak();
266
139
}
267
268
653
void Sign::Initialize(Environment* env, Local<Object> target) {
269
653
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
270
271
1962
  t->InstanceTemplate()->SetInternalFieldCount(
272
654
      SignBase::kInternalFieldCount);
273
1308
  t->Inherit(BaseObject::GetConstructorTemplate(env));
274
275
654
  env->SetProtoMethod(t, "init", SignInit);
276
654
  env->SetProtoMethod(t, "update", SignUpdate);
277
654
  env->SetProtoMethod(t, "sign", SignFinal);
278
279
1308
  target->Set(env->context(),
280
              FIXED_ONE_BYTE_STRING(env->isolate(), "Sign"),
281
3924
              t->GetFunction(env->context()).ToLocalChecked()).Check();
282
283
654
  env->SetMethod(target, "signOneShot", Sign::SignSync);
284
285
654
  SignJob::Initialize(env, target);
286
287
654
  constexpr int kSignJobModeSign = SignConfiguration::kSign;
288
654
  constexpr int kSignJobModeVerify = SignConfiguration::kVerify;
289
290
2616
  NODE_DEFINE_CONSTANT(target, kSignJobModeSign);
291
654
  NODE_DEFINE_CONSTANT(target, kSignJobModeVerify);
292
1962
  NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING);
293
3270
}
294
4578
295
3409
void Sign::New(const FunctionCallbackInfo<Value>& args) {
296
1447
  Environment* env = Environment::GetCurrent(args);
297
139
  new Sign(env, args.This());
298
139
}
299
300
139
void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
301
139
  Environment* env = Environment::GetCurrent(args);
302
  Sign* sign;
303
139
  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
304
305
278
  const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
306
139
  crypto::CheckThrow(env, sign->Init(*sign_type));
307
}
308
309
125
void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
310
250
  Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args,
311
375
                        const char* data, size_t size) {
312
125
    Environment* env = Environment::GetCurrent(args);
313
125
    if (UNLIKELY(size > INT_MAX))
314
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
315
125
    Error err = sign->Update(data, size);
316
125
    crypto::CheckThrow(sign->env(), err);
317
375
  });
318
125
}
319
320
112
Sign::SignResult Sign::SignFinal(
321
    const ManagedEVPPKey& pkey,
322
    int padding,
323
    const Maybe<int>& salt_len,
324
    DSASigEnc dsa_sig_enc) {
325
112
  if (!mdctx_)
326
    return SignResult(kSignNotInitialised);
327
328
224
  EVPMDPointer mdctx = std::move(mdctx_);
329
330
112
  if (!ValidateDSAParameters(pkey.get()))
331
    return SignResult(kSignPrivateKey);
332
333
  AllocatedBuffer buffer =
334
224
      Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len);
335
112
  Error error = buffer.data() == nullptr ? kSignPrivateKey : kSignOk;
336

112
  if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
337
    buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
338
    CHECK_NOT_NULL(buffer.data());
339
  }
340
112
  return SignResult(error, std::move(buffer));
341
}
342
343
116
void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
344
116
  Environment* env = Environment::GetCurrent(args);
345
  Sign* sign;
346
135
  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
347
348
97
  ClearErrorOnReturn clear_error_on_return;
349
350
116
  unsigned int offset = 0;
351
213
  ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true);
352
116
  if (!key)
353
4
    return;
354
355
112
  int padding = GetDefaultSignPadding(key);
356
448
  if (!args[offset]->IsUndefined()) {
357
63
    CHECK(args[offset]->IsInt32());
358
84
    padding = args[offset].As<Int32>()->Value();
359
  }
360
361
112
  Maybe<int> salt_len = Nothing<int>();
362
448
  if (!args[offset + 1]->IsUndefined()) {
363
162
    CHECK(args[offset + 1]->IsInt32());
364
216
    salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
365
  }
366
367
336
  CHECK(args[offset + 2]->IsInt32());
368
  DSASigEnc dsa_sig_enc =
369
448
      static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value());
370
371
  SignResult ret = sign->SignFinal(
372
      key,
373
      padding,
374
      salt_len,
375
209
      dsa_sig_enc);
376
377
112
  if (ret.error != kSignOk)
378
15
    return crypto::CheckThrow(env, ret.error);
379
380
291
  args.GetReturnValue().Set(ret.signature.ToBuffer().FromMaybe(Local<Value>()));
381
}
382
383
589
Verify::Verify(Environment* env, Local<Object> wrap)
384
589
  : SignBase(env, wrap) {
385
589
  MakeWeak();
386
589
}
387
388
653
void Verify::Initialize(Environment* env, Local<Object> target) {
389
653
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
390
391
1962
  t->InstanceTemplate()->SetInternalFieldCount(
392
654
      SignBase::kInternalFieldCount);
393
1307
  t->Inherit(BaseObject::GetConstructorTemplate(env));
394
395
654
  env->SetProtoMethod(t, "init", VerifyInit);
396
654
  env->SetProtoMethod(t, "update", VerifyUpdate);
397
654
  env->SetProtoMethod(t, "verify", VerifyFinal);
398
399
1307
  target->Set(env->context(),
400
              FIXED_ONE_BYTE_STRING(env->isolate(), "Verify"),
401
3923
              t->GetFunction(env->context()).ToLocalChecked()).Check();
402
403
654
  env->SetMethod(target, "verifyOneShot", Verify::VerifySync);
404
654
}
405
406
589
void Verify::New(const FunctionCallbackInfo<Value>& args) {
407
589
  Environment* env = Environment::GetCurrent(args);
408
589
  new Verify(env, args.This());
409
589
}
410
411
589
void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
412
589
  Environment* env = Environment::GetCurrent(args);
413
  Verify* verify;
414
589
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
415
416
1178
  const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
417
589
  crypto::CheckThrow(env, verify->Init(*verify_type));
418
}
419
420
599
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
421
1198
  Decode<Verify>(args, [](Verify* verify,
422
                          const FunctionCallbackInfo<Value>& args,
423
1797
                          const char* data, size_t size) {
424
599
    Environment* env = Environment::GetCurrent(args);
425
599
    if (UNLIKELY(size > INT_MAX))
426
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
427
599
    Error err = verify->Update(data, size);
428
599
    crypto::CheckThrow(verify->env(), err);
429
1797
  });
430
599
}
431
432
582
SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey,
433
                                    const ByteSource& sig,
434
                                    int padding,
435
                                    const Maybe<int>& saltlen,
436
                                    bool* verify_result) {
437
582
  if (!mdctx_)
438
    return kSignNotInitialised;
439
440
  unsigned char m[EVP_MAX_MD_SIZE];
441
  unsigned int m_len;
442
582
  *verify_result = false;
443
1164
  EVPMDPointer mdctx = std::move(mdctx_);
444
445
582
  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
446
    return kSignPublicKey;
447
448
1164
  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
449

1164
  if (pkctx &&
450
1746
      EVP_PKEY_verify_init(pkctx.get()) > 0 &&
451

1746
      ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
452
582
      EVP_PKEY_CTX_set_signature_md(pkctx.get(),
453
                                    EVP_MD_CTX_md(mdctx.get())) > 0) {
454
582
    const unsigned char* s = reinterpret_cast<const unsigned char*>(sig.get());
455
582
    const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
456
582
    *verify_result = r == 1;
457
  }
458
459
582
  return kSignOk;
460
}
461
462
582
void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
463
582
  Environment* env = Environment::GetCurrent(args);
464
582
  ClearErrorOnReturn clear_error_on_return;
465
466
  Verify* verify;
467
582
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
468
469
582
  unsigned int offset = 0;
470
  ManagedEVPPKey pkey =
471
1164
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
472
582
  if (!pkey)
473
    return;
474
475
1746
  ArrayBufferOrViewContents<char> hbuf(args[offset]);
476
582
  if (UNLIKELY(!hbuf.CheckSizeInt32()))
477
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
478
479
582
  int padding = GetDefaultSignPadding(pkey);
480
2328
  if (!args[offset + 1]->IsUndefined()) {
481
1116
    CHECK(args[offset + 1]->IsInt32());
482
1488
    padding = args[offset + 1].As<Int32>()->Value();
483
  }
484
485
582
  Maybe<int> salt_len = Nothing<int>();
486
2328
  if (!args[offset + 2]->IsUndefined()) {
487
1386
    CHECK(args[offset + 2]->IsInt32());
488
1848
    salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
489
  }
490
491
1746
  CHECK(args[offset + 3]->IsInt32());
492
  DSASigEnc dsa_sig_enc =
493
2328
      static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value());
494
495
1164
  ByteSource signature = hbuf.ToByteSource();
496
582
  if (dsa_sig_enc == kSigEncP1363) {
497
4
    signature = ConvertSignatureToDER(pkey, hbuf);
498
4
    if (signature.get() == nullptr)
499
      return crypto::CheckThrow(env, Error::kSignMalformedSignature);
500
  }
501
502
  bool verify_result;
503
582
  Error err = verify->VerifyFinal(pkey, signature, padding,
504
582
                                  salt_len, &verify_result);
505
582
  if (err != kSignOk)
506
    return crypto::CheckThrow(env, err);
507
1746
  args.GetReturnValue().Set(verify_result);
508
}
509
510
77
void Sign::SignSync(const FunctionCallbackInfo<Value>& args) {
511
66
  ClearErrorOnReturn clear_error_on_return;
512
77
  Environment* env = Environment::GetCurrent(args);
513
514
77
  unsigned int offset = 0;
515
143
  ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true);
516
77
  if (!key)
517
9
    return;
518
519
68
  if (!ValidateDSAParameters(key.get()))
520
    return crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
521
522
202
  ArrayBufferOrViewContents<char> data(args[offset]);
523
68
  if (UNLIKELY(!data.CheckSizeInt32()))
524
    return THROW_ERR_OUT_OF_RANGE(env, "data is too big");
525
526
  const EVP_MD* md;
527
272
  if (args[offset + 1]->IsNullOrUndefined()) {
528
16
    md = nullptr;
529
  } else {
530
155
    const node::Utf8Value sign_type(args.GetIsolate(), args[offset + 1]);
531
52
    md = EVP_get_digestbyname(*sign_type);
532
52
    if (md == nullptr)
533
1
      return crypto::CheckThrow(env, SignBase::Error::kSignUnknownDigest);
534
  }
535
536
67
  int rsa_padding = GetDefaultSignPadding(key);
537
268
  if (!args[offset + 2]->IsUndefined()) {
538
57
    CHECK(args[offset + 2]->IsInt32());
539
76
    rsa_padding = args[offset + 2].As<Int32>()->Value();
540
  }
541
542
67
  Maybe<int> rsa_salt_len = Nothing<int>();
543
268
  if (!args[offset + 3]->IsUndefined()) {
544
54
    CHECK(args[offset + 3]->IsInt32());
545
72
    rsa_salt_len = Just<int>(args[offset + 3].As<Int32>()->Value());
546
  }
547
548
201
  CHECK(args[offset + 4]->IsInt32());
549
  DSASigEnc dsa_sig_enc =
550
268
      static_cast<DSASigEnc>(args[offset + 4].As<Int32>()->Value());
551
552
67
  EVP_PKEY_CTX* pkctx = nullptr;
553
133
  EVPMDPointer mdctx(EVP_MD_CTX_new());
554
555

134
  if (!mdctx ||
556
67
      !EVP_DigestSignInit(mdctx.get(), &pkctx, md, nullptr, key.get())) {
557
    return crypto::CheckThrow(env, SignBase::Error::kSignInit);
558
  }
559
560
67
  if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len))
561
1
    return crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
562
563
  const unsigned char* input =
564
66
    reinterpret_cast<const unsigned char*>(data.data());
565
  size_t sig_len;
566
66
  if (!EVP_DigestSign(mdctx.get(), nullptr, &sig_len, input, data.size()))
567
    return crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
568
569
132
  AllocatedBuffer signature = AllocatedBuffer::AllocateManaged(env, sig_len);
570
132
  if (!EVP_DigestSign(mdctx.get(),
571
66
                      reinterpret_cast<unsigned char*>(signature.data()),
572
                      &sig_len,
573
                      input,
574
                      data.size())) {
575
    return crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
576
  }
577
578
66
  signature.Resize(sig_len);
579
580
66
  if (dsa_sig_enc == kSigEncP1363) {
581
3
    signature = ConvertSignatureToP1363(env, key, std::move(signature));
582
  }
583
584
198
  args.GetReturnValue().Set(signature.ToBuffer().FromMaybe(Local<Value>()));
585
}
586
587
479
void Verify::VerifySync(const FunctionCallbackInfo<Value>& args) {
588
467
  ClearErrorOnReturn clear_error_on_return;
589
479
  Environment* env = Environment::GetCurrent(args);
590
591
479
  unsigned int offset = 0;
592
  ManagedEVPPKey key =
593
946
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
594
479
  if (!key)
595
    return;
596
597
1425
  ArrayBufferOrViewContents<char> sig(args[offset]);
598
1425
  ArrayBufferOrViewContents<char> data(args[offset + 1]);
599
600
479
  if (UNLIKELY(!sig.CheckSizeInt32()))
601
    return THROW_ERR_OUT_OF_RANGE(env, "sig is too big");
602
479
  if (UNLIKELY(!data.CheckSizeInt32()))
603
    return THROW_ERR_OUT_OF_RANGE(env, "data is too big");
604
605
  const EVP_MD* md;
606
1916
  if (args[offset + 2]->IsNullOrUndefined()) {
607
20
    md = nullptr;
608
  } else {
609
1377
    const node::Utf8Value sign_type(args.GetIsolate(), args[offset + 2]);
610
459
    md = EVP_get_digestbyname(*sign_type);
611
459
    if (md == nullptr)
612
      return crypto::CheckThrow(env, SignBase::Error::kSignUnknownDigest);
613
  }
614
615
479
  int rsa_padding = GetDefaultSignPadding(key);
616
1916
  if (!args[offset + 3]->IsUndefined()) {
617
1080
    CHECK(args[offset + 3]->IsInt32());
618
1440
    rsa_padding = args[offset + 3].As<Int32>()->Value();
619
  }
620
621
479
  Maybe<int> rsa_salt_len = Nothing<int>();
622
1916
  if (!args[offset + 4]->IsUndefined()) {
623
1080
    CHECK(args[offset + 4]->IsInt32());
624
1440
    rsa_salt_len = Just<int>(args[offset + 4].As<Int32>()->Value());
625
  }
626
627
1437
  CHECK(args[offset + 5]->IsInt32());
628
  DSASigEnc dsa_sig_enc =
629
1916
      static_cast<DSASigEnc>(args[offset + 5].As<Int32>()->Value());
630
631
479
  EVP_PKEY_CTX* pkctx = nullptr;
632
946
  EVPMDPointer mdctx(EVP_MD_CTX_new());
633

958
  if (!mdctx ||
634
479
      !EVP_DigestVerifyInit(mdctx.get(), &pkctx, md, nullptr, key.get())) {
635
    return crypto::CheckThrow(env, SignBase::Error::kSignInit);
636
  }
637
638
479
  if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len))
639
    return crypto::CheckThrow(env, SignBase::Error::kSignPublicKey);
640
641
946
  ByteSource sig_bytes = ByteSource::Foreign(sig.data(), sig.size());
642
479
  if (dsa_sig_enc == kSigEncP1363) {
643
17
    sig_bytes = ConvertSignatureToDER(key, sig);
644
17
    if (!sig_bytes)
645
12
      return crypto::CheckThrow(env, SignBase::Error::kSignMalformedSignature);
646
  }
647
648
  bool verify_result;
649
934
  const int r = EVP_DigestVerify(
650
    mdctx.get(),
651
    sig_bytes.data<unsigned char>(),
652
    sig_bytes.size(),
653
467
    reinterpret_cast<const unsigned char*>(data.data()),
654
467
    data.size());
655
467
  switch (r) {
656
    case 1:
657
191
      verify_result = true;
658
191
      break;
659
    case 0:
660
276
      verify_result = false;
661
276
      break;
662
    default:
663
      return crypto::CheckThrow(env, SignBase::Error::kSignPublicKey);
664
  }
665
666
1401
  args.GetReturnValue().Set(verify_result);
667
}
668
669
246
SignConfiguration::SignConfiguration(SignConfiguration&& other) noexcept
670
246
    : job_mode(other.job_mode),
671
246
      mode(other.mode),
672
246
      key(std::move(other.key)),
673
246
      data(std::move(other.data)),
674
246
      signature(std::move(other.signature)),
675
246
      digest(other.digest),
676
246
      flags(other.flags),
677
246
      padding(other.padding),
678
2214
      salt_length(other.salt_length) {}
679
680
SignConfiguration& SignConfiguration::operator=(
681
    SignConfiguration&& other) noexcept {
682
  if (&other == this) return *this;
683
  this->~SignConfiguration();
684
  return *new (this) SignConfiguration(std::move(other));
685
}
686
687
void SignConfiguration::MemoryInfo(MemoryTracker* tracker) const {
688
  tracker->TrackField("key", key.get());
689
  if (job_mode == kCryptoJobAsync) {
690
    tracker->TrackFieldWithSize("data", data.size());
691
    tracker->TrackFieldWithSize("signature", signature.size());
692
  }
693
}
694
695
246
Maybe<bool> SignTraits::AdditionalConfig(
696
    CryptoJobMode mode,
697
    const FunctionCallbackInfo<Value>& args,
698
    unsigned int offset,
699
    SignConfiguration* params) {
700
246
  Environment* env = Environment::GetCurrent(args);
701
702
246
  params->job_mode = mode;
703
704
738
  CHECK(args[offset]->IsUint32());  // Sign Mode
705
738
  CHECK(args[offset + 1]->IsObject());  // Key
706
707
246
  params->mode =
708
1230
      static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value());
709
710
  KeyObjectHandle* key;
711
492
  ASSIGN_OR_RETURN_UNWRAP(&key, args[offset + 1], Nothing<bool>());
712
246
  params->key = key->Data();
713
714
738
  ArrayBufferOrViewContents<char> data(args[offset + 2]);
715
246
  if (UNLIKELY(!data.CheckSizeInt32())) {
716
    THROW_ERR_OUT_OF_RANGE(env, "data is too big");
717
    return Nothing<bool>();
718
  }
719
  params->data = mode == kCryptoJobAsync
720
492
      ? data.ToCopy()
721
246
      : data.ToByteSource();
722
723
984
  if (args[offset + 3]->IsString()) {
724
738
    Utf8Value digest(env->isolate(), args[offset + 3]);
725
246
    params->digest = EVP_get_digestbyname(*digest);
726
246
    if (params->digest == nullptr) {
727
      THROW_ERR_CRYPTO_INVALID_DIGEST(env);
728
      return Nothing<bool>();
729
    }
730
  }
731
732
738
  if (args[offset + 4]->IsUint32()) {  // Salt length
733
82
    params->flags |= SignConfiguration::kHasSaltLength;
734
328
    params->salt_length = args[offset + 4].As<Uint32>()->Value();
735
  }
736
738
  if (args[offset + 5]->IsUint32()) {  // Padding
737
82
    params->flags |= SignConfiguration::kHasPadding;
738
328
    params->padding = args[offset + 5].As<Uint32>()->Value();
739
  }
740
741
246
  if (params->mode == SignConfiguration::kVerify) {
742
585
    ArrayBufferOrViewContents<char> signature(args[offset + 6]);
743
195
    if (UNLIKELY(!signature.CheckSizeInt32())) {
744
      THROW_ERR_OUT_OF_RANGE(env, "signature is too big");
745
      return Nothing<bool>();
746
    }
747
    // If this is an EC key (assuming ECDSA) we need to convert the
748
    // the signature from WebCrypto format into DER format...
749
195
    if (EVP_PKEY_id(params->key->GetAsymmetricKey().get()) == EVP_PKEY_EC) {
750
      params->signature =
751
130
          ConvertFromWebCryptoSignature(
752
130
              params->key->GetAsymmetricKey(),
753
195
              signature.ToByteSource());
754
    } else {
755
      params->signature = mode == kCryptoJobAsync
756

260
          ? signature.ToCopy()
757
130
          : signature.ToByteSource();
758
    }
759
  }
760
761
246
  return Just(true);
762
}
763
764
246
bool SignTraits::DeriveBits(
765
    Environment* env,
766
    const SignConfiguration& params,
767
    ByteSource* out) {
768
492
  EVPMDPointer context(EVP_MD_CTX_new());
769
246
  EVP_PKEY_CTX* ctx = nullptr;
770
771
246
  switch (params.mode) {
772
    case SignConfiguration::kSign:
773
51
      CHECK_EQ(params.key->GetKeyType(), kKeyTypePrivate);
774
153
      if (!EVP_DigestSignInit(
775
              context.get(),
776
              &ctx,
777
51
              params.digest,
778
              nullptr,
779
102
              params.key->GetAsymmetricKey().get())) {
780
        return false;
781
      }
782
51
      break;
783
    case SignConfiguration::kVerify:
784
195
      CHECK_EQ(params.key->GetKeyType(), kKeyTypePublic);
785
585
      if (!EVP_DigestVerifyInit(
786
              context.get(),
787
              &ctx,
788
195
              params.digest,
789
              nullptr,
790
390
              params.key->GetAsymmetricKey().get())) {
791
        return false;
792
      }
793
195
      break;
794
  }
795
796
246
  int padding = params.flags & SignConfiguration::kHasPadding
797
410
      ? params.padding
798
410
      : GetDefaultSignPadding(params.key->GetAsymmetricKey());
799
800
246
  Maybe<int> salt_length = params.flags & SignConfiguration::kHasSaltLength
801
246
      ? Just<int>(params.salt_length) : Nothing<int>();
802
803
738
  if (!ApplyRSAOptions(
804
492
          params.key->GetAsymmetricKey(),
805
          ctx,
806
          padding,
807
          salt_length)) {
808
    return false;
809
  }
810
811
246
  switch (params.mode) {
812
    case SignConfiguration::kSign: {
813
      size_t len;
814
102
      if (!EVP_DigestSignUpdate(
815
              context.get(),
816
              params.data.data<unsigned char>(),
817

102
              params.data.size()) ||
818
51
          !EVP_DigestSignFinal(context.get(), nullptr, &len)) {
819
        return false;
820
      }
821
51
      char* data = MallocOpenSSL<char>(len);
822
51
      ByteSource buf = ByteSource::Allocated(data, len);
823
51
      unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
824
51
      if (!EVP_DigestSignFinal(context.get(), ptr, &len))
825
        return false;
826
827
      // If this is an EC key (assuming ECDSA) we have to
828
      // convert the signature in to the proper format.
829
51
      if (EVP_PKEY_id(params.key->GetAsymmetricKey().get()) == EVP_PKEY_EC) {
830
17
        *out = ConvertToWebCryptoSignature(params.key->GetAsymmetricKey(), buf);
831
      } else {
832
34
        buf.Resize(len);
833
34
        *out = std::move(buf);
834
      }
835
51
      break;
836
    }
837
    case SignConfiguration::kVerify: {
838
195
      char* data = MallocOpenSSL<char>(1);
839
195
      data[0] = 0;
840
195
      *out = ByteSource::Allocated(data, 1);
841
195
      if (!EVP_DigestVerifyUpdate(
842
              context.get(),
843
              params.data.data<unsigned char>(),
844
              params.data.size())) {
845
        return false;
846
      }
847
848
195
      if (EVP_DigestVerifyFinal(
849
              context.get(),
850
              params.signature.data<unsigned char>(),
851
              params.signature.size()) == 1) {
852
99
        data[0] = 1;
853
      }
854
    }
855
  }
856
857
246
  return true;
858
}
859
860
246
Maybe<bool> SignTraits::EncodeOutput(
861
    Environment* env,
862
    const SignConfiguration& params,
863
    ByteSource* out,
864
    Local<Value>* result) {
865
246
  switch (params.mode) {
866
    case SignConfiguration::kSign:
867
102
      *result = out->ToArrayBuffer(env);
868
51
      break;
869
    case SignConfiguration::kVerify:
870
390
      *result = out->get()[0] == 1
871
99
          ? v8::True(env->isolate())
872
486
          : v8::False(env->isolate());
873
195
      break;
874
    default:
875
      UNREACHABLE();
876
  }
877
246
  return Just(!result->IsEmpty());
878
}
879
880
}  // namespace crypto
881

14034
}  // namespace node