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: 366 438 83.6 %
Date: 2021-05-04 04:12:26 Branches: 186 304 61.2 %

Line Branch Exec Source
1
#include "crypto/crypto_sig.h"
2
#include "crypto/crypto_ec.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
112
bool ValidateDSAParameters(EVP_PKEY* key) {
30
  /* Validate DSA2 parameters from FIPS 186-4 */
31
#if OPENSSL_VERSION_MAJOR >= 3
32
  if (EVP_default_properties_is_fips_enabled(nullptr) &&
33
      EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
34
#else
35

112
  if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
36
#endif
37
    const DSA* dsa = EVP_PKEY_get0_DSA(key);
38
    const BIGNUM* p;
39
    DSA_get0_pqg(dsa, &p, nullptr, nullptr);
40
    size_t L = BN_num_bits(p);
41
    const BIGNUM* q;
42
    DSA_get0_pqg(dsa, nullptr, &q, nullptr);
43
    size_t N = BN_num_bits(q);
44
45
    return (L == 1024 && N == 160) ||
46
           (L == 2048 && N == 224) ||
47
           (L == 2048 && N == 256) ||
48
           (L == 3072 && N == 256);
49
  }
50
51
112
  return true;
52
}
53
54
1757
bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
55
                     EVP_PKEY_CTX* pkctx,
56
                     int padding,
57
                     const Maybe<int>& salt_len) {
58

4145
  if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
59

2388
      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
60
631
      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
61
1301
    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
62
3
      return false;
63

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

224
  if (pkctx &&
91
336
      EVP_PKEY_sign_init(pkctx.get()) &&
92
216
      ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
93

314
      EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) &&
94
98
      EVP_PKEY_sign(pkctx.get(), ptr, &sig_len, m, m_len)) {
95
97
    sig.Resize(sig_len);
96
97
    return sig;
97
  }
98
99
15
  return AllocatedBuffer();
100
}
101
102
1220
int GetDefaultSignPadding(const ManagedEVPPKey& m_pkey) {
103
1220
  return EVP_PKEY_id(m_pkey.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
104
1220
                                                         RSA_PKCS1_PADDING;
105
}
106
107
148
unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
108
148
  int bits, base_id = EVP_PKEY_base_id(pkey.get());
109
110
148
  if (base_id == EVP_PKEY_DSA) {
111
28
    const DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get());
112
    // Both r and s are computed mod q, so their width is limited by that of q.
113
28
    bits = BN_num_bits(DSA_get0_q(dsa_key));
114
120
  } else if (base_id == EVP_PKEY_EC) {
115
120
    const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
116
120
    const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
117
120
    bits = EC_GROUP_order_bits(ec_group);
118
  } else {
119
    return kNoDsaSignature;
120
  }
121
122
148
  return (bits + 7) / 8;
123
}
124
125
30
bool ExtractP1363(
126
    const unsigned char* sig_data,
127
    unsigned char* out,
128
    size_t len,
129
    size_t n) {
130
60
  ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len));
131
30
  if (!asn1_sig)
132
    return false;
133
134
30
  const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get());
135
30
  const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get());
136
137

30
  return BN_bn2binpad(pr, out, n) > 0 && BN_bn2binpad(ps, out + n, n) > 0;
138
}
139
140
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
141
AllocatedBuffer ConvertSignatureToP1363(Environment* env,
142
                                        const ManagedEVPPKey& pkey,
143
                                        AllocatedBuffer&& signature) {
144
  unsigned int n = GetBytesOfRS(pkey);
145
  if (n == kNoDsaSignature)
146
    return std::move(signature);
147
148
  const unsigned char* sig_data =
149
      reinterpret_cast<unsigned char*>(signature.data());
150
151
  AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, 2 * n);
152
  unsigned char* data = reinterpret_cast<unsigned char*>(buf.data());
153
154
  if (!ExtractP1363(sig_data, data, signature.size(), n))
155
    return std::move(signature);
156
157
  return buf;
158
}
159
160
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
161
30
ByteSource ConvertSignatureToP1363(
162
    Environment* env,
163
    const ManagedEVPPKey& pkey,
164
    const ByteSource& signature) {
165
30
  unsigned int n = GetBytesOfRS(pkey);
166
30
  if (n == kNoDsaSignature)
167
    return ByteSource();
168
169
  const unsigned char* sig_data =
170
30
      reinterpret_cast<const unsigned char*>(signature.get());
171
172
30
  char* outdata = MallocOpenSSL<char>(n * 2);
173
30
  memset(outdata, 0, n * 2);
174
60
  ByteSource out = ByteSource::Allocated(outdata, n * 2);
175
30
  unsigned char* ptr = reinterpret_cast<unsigned char*>(outdata);
176
177
30
  if (!ExtractP1363(sig_data, ptr, signature.size(), n))
178
    return ByteSource();
179
180
30
  return out;
181
}
182
183
118
ByteSource ConvertSignatureToDER(
184
      const ManagedEVPPKey& pkey,
185
      ByteSource&& out) {
186
118
  unsigned int n = GetBytesOfRS(pkey);
187
118
  if (n == kNoDsaSignature)
188
    return std::move(out);
189
190
  const unsigned char* sig_data =
191
118
      reinterpret_cast<const unsigned char*>(out.get());
192
193
118
  if (out.size() != 2 * n)
194
32
    return ByteSource();
195
196
172
  ECDSASigPointer asn1_sig(ECDSA_SIG_new());
197
86
  CHECK(asn1_sig);
198
86
  BIGNUM* r = BN_new();
199
86
  CHECK_NOT_NULL(r);
200
86
  BIGNUM* s = BN_new();
201
86
  CHECK_NOT_NULL(s);
202
86
  CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
203
86
  CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
204
86
  CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
205
206
86
  unsigned char* data = nullptr;
207
86
  int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
208
209
86
  if (len <= 0)
210
    return ByteSource();
211
212
86
  CHECK_NOT_NULL(data);
213
214
86
  return ByteSource::Allocated(reinterpret_cast<char*>(data), len);
215
}
216
217
1468
void CheckThrow(Environment* env, SignBase::Error error) {
218
1468
  HandleScope scope(env->isolate());
219
220

1468
  switch (error) {
221
    case SignBase::Error::kSignUnknownDigest:
222
1
      return THROW_ERR_CRYPTO_INVALID_DIGEST(env);
223
224
    case SignBase::Error::kSignNotInitialised:
225
      return THROW_ERR_CRYPTO_INVALID_STATE(env, "Not initialised");
226
227
    case SignBase::Error::kSignMalformedSignature:
228
      return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Malformed signature");
229
230
    case SignBase::Error::kSignInit:
231
    case SignBase::Error::kSignUpdate:
232
    case SignBase::Error::kSignPrivateKey:
233
    case SignBase::Error::kSignPublicKey:
234
      {
235
16
        unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
236
16
        if (err)
237
16
          return ThrowCryptoError(env, err);
238
        switch (error) {
239
          case SignBase::Error::kSignInit:
240
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
241
                "EVP_SignInit_ex failed");
242
          case SignBase::Error::kSignUpdate:
243
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
244
                "EVP_SignUpdate failed");
245
          case SignBase::Error::kSignPrivateKey:
246
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
247
                "PEM_read_bio_PrivateKey failed");
248
          case SignBase::Error::kSignPublicKey:
249
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
250
                "PEM_read_bio_PUBKEY failed");
251
          default:
252
            ABORT();
253
        }
254
      }
255
256
    case SignBase::Error::kSignOk:
257
1451
      return;
258
  }
259
}
260
261
182
bool IsOneShot(const ManagedEVPPKey& key) {
262
182
  switch (EVP_PKEY_id(key.get())) {
263
    case EVP_PKEY_ED25519:
264
    case EVP_PKEY_ED448:
265
33
      return true;
266
    default:
267
149
      return false;
268
  }
269
}
270
271
1030
bool UseP1363Encoding(const ManagedEVPPKey& key,
272
                      const DSASigEnc& dsa_encoding) {
273
1030
  switch (EVP_PKEY_id(key.get())) {
274
    case EVP_PKEY_EC:
275
    case EVP_PKEY_DSA:
276
305
      return dsa_encoding == kSigEncP1363;
277
    default:
278
725
      return false;
279
  }
280
}
281
}  // namespace
282
283
728
SignBase::Error SignBase::Init(const char* sign_type) {
284
728
  CHECK_NULL(mdctx_);
285
  // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
286
  // exposed through the public API.
287

1456
  if (strcmp(sign_type, "dss1") == 0 ||
288
728
      strcmp(sign_type, "DSS1") == 0) {
289
2
    sign_type = "SHA1";
290
  }
291
728
  const EVP_MD* md = EVP_get_digestbyname(sign_type);
292
728
  if (md == nullptr)
293
1
    return kSignUnknownDigest;
294
295
727
  mdctx_.reset(EVP_MD_CTX_new());
296

727
  if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) {
297
    mdctx_.reset();
298
    return kSignInit;
299
  }
300
301
727
  return kSignOk;
302
}
303
304
724
SignBase::Error SignBase::Update(const char* data, size_t len) {
305
724
  if (mdctx_ == nullptr)
306
    return kSignNotInitialised;
307
724
  if (!EVP_DigestUpdate(mdctx_.get(), data, len))
308
    return kSignUpdate;
309
724
  return kSignOk;
310
}
311
312
728
SignBase::SignBase(Environment* env, Local<Object> wrap)
313
728
    : BaseObject(env, wrap) {}
314
315
void SignBase::MemoryInfo(MemoryTracker* tracker) const {
316
  tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0);
317
}
318
319
139
Sign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) {
320
139
  MakeWeak();
321
139
}
322
323
4155
void Sign::Initialize(Environment* env, Local<Object> target) {
324
4155
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
325
326
12465
  t->InstanceTemplate()->SetInternalFieldCount(
327
4155
      SignBase::kInternalFieldCount);
328
8310
  t->Inherit(BaseObject::GetConstructorTemplate(env));
329
330
4155
  env->SetProtoMethod(t, "init", SignInit);
331
4155
  env->SetProtoMethod(t, "update", SignUpdate);
332
4155
  env->SetProtoMethod(t, "sign", SignFinal);
333
334
4155
  env->SetConstructorFunction(target, "Sign", t);
335
336
4155
  SignJob::Initialize(env, target);
337
338
4155
  constexpr int kSignJobModeSign = SignConfiguration::kSign;
339
4155
  constexpr int kSignJobModeVerify = SignConfiguration::kVerify;
340
341
16620
  NODE_DEFINE_CONSTANT(target, kSignJobModeSign);
342
4155
  NODE_DEFINE_CONSTANT(target, kSignJobModeVerify);
343
12465
  NODE_DEFINE_CONSTANT(target, kSigEncDER);
344
20775
  NODE_DEFINE_CONSTANT(target, kSigEncP1363);
345
37395
  NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING);
346
37395
}
347
29085
348
20914
void Sign::New(const FunctionCallbackInfo<Value>& args) {
349
8449
  Environment* env = Environment::GetCurrent(args);
350
139
  new Sign(env, args.This());
351
139
}
352
353
139
void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
354
139
  Environment* env = Environment::GetCurrent(args);
355
  Sign* sign;
356
139
  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
357
358
278
  const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
359
139
  crypto::CheckThrow(env, sign->Init(*sign_type));
360
}
361
362
125
void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
363
250
  Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args,
364
375
                        const char* data, size_t size) {
365
125
    Environment* env = Environment::GetCurrent(args);
366
125
    if (UNLIKELY(size > INT_MAX))
367
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
368
125
    Error err = sign->Update(data, size);
369
125
    crypto::CheckThrow(sign->env(), err);
370
375
  });
371
125
}
372
373
112
Sign::SignResult Sign::SignFinal(
374
    const ManagedEVPPKey& pkey,
375
    int padding,
376
    const Maybe<int>& salt_len,
377
    DSASigEnc dsa_sig_enc) {
378
112
  if (!mdctx_)
379
    return SignResult(kSignNotInitialised);
380
381
224
  EVPMDPointer mdctx = std::move(mdctx_);
382
383
112
  if (!ValidateDSAParameters(pkey.get()))
384
    return SignResult(kSignPrivateKey);
385
386
  AllocatedBuffer buffer =
387
224
      Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len);
388
112
  Error error = buffer.data() == nullptr ? kSignPrivateKey : kSignOk;
389

112
  if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
390
    buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
391
    CHECK_NOT_NULL(buffer.data());
392
  }
393
112
  return SignResult(error, std::move(buffer));
394
}
395
396
116
void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
397
116
  Environment* env = Environment::GetCurrent(args);
398
  Sign* sign;
399
135
  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
400
401
97
  ClearErrorOnReturn clear_error_on_return;
402
403
116
  unsigned int offset = 0;
404
213
  ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true);
405
116
  if (!key)
406
4
    return;
407
408
112
  int padding = GetDefaultSignPadding(key);
409
448
  if (!args[offset]->IsUndefined()) {
410
63
    CHECK(args[offset]->IsInt32());
411
84
    padding = args[offset].As<Int32>()->Value();
412
  }
413
414
112
  Maybe<int> salt_len = Nothing<int>();
415
448
  if (!args[offset + 1]->IsUndefined()) {
416
162
    CHECK(args[offset + 1]->IsInt32());
417
216
    salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
418
  }
419
420
336
  CHECK(args[offset + 2]->IsInt32());
421
  DSASigEnc dsa_sig_enc =
422
448
      static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value());
423
424
  SignResult ret = sign->SignFinal(
425
      key,
426
      padding,
427
      salt_len,
428
209
      dsa_sig_enc);
429
430
112
  if (ret.error != kSignOk)
431
15
    return crypto::CheckThrow(env, ret.error);
432
433
291
  args.GetReturnValue().Set(ret.signature.ToBuffer().FromMaybe(Local<Value>()));
434
}
435
436
589
Verify::Verify(Environment* env, Local<Object> wrap)
437
589
  : SignBase(env, wrap) {
438
589
  MakeWeak();
439
589
}
440
441
4155
void Verify::Initialize(Environment* env, Local<Object> target) {
442
4155
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
443
444
12465
  t->InstanceTemplate()->SetInternalFieldCount(
445
4155
      SignBase::kInternalFieldCount);
446
8310
  t->Inherit(BaseObject::GetConstructorTemplate(env));
447
448
4155
  env->SetProtoMethod(t, "init", VerifyInit);
449
4155
  env->SetProtoMethod(t, "update", VerifyUpdate);
450
4155
  env->SetProtoMethod(t, "verify", VerifyFinal);
451
452
4155
  env->SetConstructorFunction(target, "Verify", t);
453
4155
}
454
455
589
void Verify::New(const FunctionCallbackInfo<Value>& args) {
456
589
  Environment* env = Environment::GetCurrent(args);
457
589
  new Verify(env, args.This());
458
589
}
459
460
589
void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
461
589
  Environment* env = Environment::GetCurrent(args);
462
  Verify* verify;
463
589
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
464
465
1178
  const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
466
589
  crypto::CheckThrow(env, verify->Init(*verify_type));
467
}
468
469
599
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
470
1198
  Decode<Verify>(args, [](Verify* verify,
471
                          const FunctionCallbackInfo<Value>& args,
472
1797
                          const char* data, size_t size) {
473
599
    Environment* env = Environment::GetCurrent(args);
474
599
    if (UNLIKELY(size > INT_MAX))
475
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
476
599
    Error err = verify->Update(data, size);
477
599
    crypto::CheckThrow(verify->env(), err);
478
1797
  });
479
599
}
480
481
582
SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey,
482
                                    const ByteSource& sig,
483
                                    int padding,
484
                                    const Maybe<int>& saltlen,
485
                                    bool* verify_result) {
486
582
  if (!mdctx_)
487
    return kSignNotInitialised;
488
489
  unsigned char m[EVP_MAX_MD_SIZE];
490
  unsigned int m_len;
491
582
  *verify_result = false;
492
1164
  EVPMDPointer mdctx = std::move(mdctx_);
493
494
582
  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
495
    return kSignPublicKey;
496
497
1164
  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
498

1164
  if (pkctx &&
499
1746
      EVP_PKEY_verify_init(pkctx.get()) > 0 &&
500

1746
      ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
501
582
      EVP_PKEY_CTX_set_signature_md(pkctx.get(),
502
                                    EVP_MD_CTX_md(mdctx.get())) > 0) {
503
582
    const unsigned char* s = reinterpret_cast<const unsigned char*>(sig.get());
504
582
    const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
505
582
    *verify_result = r == 1;
506
  }
507
508
582
  return kSignOk;
509
}
510
511
582
void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
512
582
  Environment* env = Environment::GetCurrent(args);
513
582
  ClearErrorOnReturn clear_error_on_return;
514
515
  Verify* verify;
516
582
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
517
518
582
  unsigned int offset = 0;
519
  ManagedEVPPKey pkey =
520
1164
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
521
582
  if (!pkey)
522
    return;
523
524
1746
  ArrayBufferOrViewContents<char> hbuf(args[offset]);
525
582
  if (UNLIKELY(!hbuf.CheckSizeInt32()))
526
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
527
528
582
  int padding = GetDefaultSignPadding(pkey);
529
2328
  if (!args[offset + 1]->IsUndefined()) {
530
1116
    CHECK(args[offset + 1]->IsInt32());
531
1488
    padding = args[offset + 1].As<Int32>()->Value();
532
  }
533
534
582
  Maybe<int> salt_len = Nothing<int>();
535
2328
  if (!args[offset + 2]->IsUndefined()) {
536
1386
    CHECK(args[offset + 2]->IsInt32());
537
1848
    salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
538
  }
539
540
1746
  CHECK(args[offset + 3]->IsInt32());
541
  DSASigEnc dsa_sig_enc =
542
2328
      static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value());
543
544
1164
  ByteSource signature = hbuf.ToByteSource();
545
582
  if (dsa_sig_enc == kSigEncP1363) {
546
4
    signature = ConvertSignatureToDER(pkey, hbuf.ToByteSource());
547
4
    if (signature.get() == nullptr)
548
      return crypto::CheckThrow(env, Error::kSignMalformedSignature);
549
  }
550
551
  bool verify_result;
552
582
  Error err = verify->VerifyFinal(pkey, signature, padding,
553
582
                                  salt_len, &verify_result);
554
582
  if (err != kSignOk)
555
    return crypto::CheckThrow(env, err);
556
1746
  args.GetReturnValue().Set(verify_result);
557
}
558
559
1063
SignConfiguration::SignConfiguration(SignConfiguration&& other) noexcept
560
1063
    : job_mode(other.job_mode),
561
1063
      mode(other.mode),
562
1063
      key(std::move(other.key)),
563
1063
      data(std::move(other.data)),
564
1063
      signature(std::move(other.signature)),
565
1063
      digest(other.digest),
566
1063
      flags(other.flags),
567
1063
      padding(other.padding),
568
1063
      salt_length(other.salt_length),
569
10630
      dsa_encoding(other.dsa_encoding) {}
570
571
SignConfiguration& SignConfiguration::operator=(
572
    SignConfiguration&& other) noexcept {
573
  if (&other == this) return *this;
574
  this->~SignConfiguration();
575
  return *new (this) SignConfiguration(std::move(other));
576
}
577
578
void SignConfiguration::MemoryInfo(MemoryTracker* tracker) const {
579
  tracker->TrackField("key", key);
580
  if (job_mode == kCryptoJobAsync) {
581
    tracker->TrackFieldWithSize("data", data.size());
582
    tracker->TrackFieldWithSize("signature", signature.size());
583
  }
584
}
585
586
1073
Maybe<bool> SignTraits::AdditionalConfig(
587
    CryptoJobMode mode,
588
    const FunctionCallbackInfo<Value>& args,
589
    unsigned int offset,
590
    SignConfiguration* params) {
591
1073
  ClearErrorOnReturn clear_error_on_return;
592
1073
  Environment* env = Environment::GetCurrent(args);
593
594
1073
  params->job_mode = mode;
595
596
3219
  CHECK(args[offset]->IsUint32());  // Sign Mode
597
598
1073
  params->mode =
599
5365
      static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value());
600
601
2146
  ManagedEVPPKey key;
602
1073
  unsigned int keyParamOffset = offset + 1;
603
1073
  if (params->mode == SignConfiguration::kVerify) {
604
881
    key = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &keyParamOffset);
605
  } else {
606
192
    key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &keyParamOffset, true);
607
  }
608
1073
  if (!key)
609
9
    return Nothing<bool>();
610
1064
  params->key = key;
611
612
3192
  ArrayBufferOrViewContents<char> data(args[offset + 5]);
613
1064
  if (UNLIKELY(!data.CheckSizeInt32())) {
614
    THROW_ERR_OUT_OF_RANGE(env, "data is too big");
615
    return Nothing<bool>();
616
  }
617
  params->data = mode == kCryptoJobAsync
618
2128
      ? data.ToCopy()
619
1064
      : data.ToByteSource();
620
621
4256
  if (args[offset + 6]->IsString()) {
622
2915
    Utf8Value digest(env->isolate(), args[offset + 6]);
623
972
    params->digest = EVP_get_digestbyname(*digest);
624
972
    if (params->digest == nullptr) {
625
1
      THROW_ERR_CRYPTO_INVALID_DIGEST(env);
626
1
      return Nothing<bool>();
627
    }
628
  }
629
630
3189
  if (args[offset + 7]->IsInt32()) {  // Salt length
631
498
    params->flags |= SignConfiguration::kHasSaltLength;
632
1992
    params->salt_length = args[offset + 7].As<Int32>()->Value();
633
  }
634
3189
  if (args[offset + 8]->IsUint32()) {  // Padding
635
537
    params->flags |= SignConfiguration::kHasPadding;
636
2148
    params->padding = args[offset + 8].As<Uint32>()->Value();
637
  }
638
639
3189
  if (args[offset + 9]->IsUint32()) {  // DSA Encoding
640
939
    params->dsa_encoding =
641
4695
        static_cast<DSASigEnc>(args[offset + 9].As<Uint32>()->Value());
642

1103
    if (params->dsa_encoding != kSigEncDER &&
643
164
        params->dsa_encoding != kSigEncP1363) {
644
      THROW_ERR_OUT_OF_RANGE(env, "invalid signature encoding");
645
      return Nothing<bool>();
646
    }
647
  }
648
649
1063
  if (params->mode == SignConfiguration::kVerify) {
650
2643
    ArrayBufferOrViewContents<char> signature(args[offset + 10]);
651
881
    if (UNLIKELY(!signature.CheckSizeInt32())) {
652
      THROW_ERR_OUT_OF_RANGE(env, "signature is too big");
653
      return Nothing<bool>();
654
    }
655
    // If this is an EC key (assuming ECDSA) we need to convert the
656
    // the signature from WebCrypto format into DER format...
657
1762
    ManagedEVPPKey m_pkey = params->key;
658
1762
    Mutex::ScopedLock lock(*m_pkey.mutex());
659
881
    if (UseP1363Encoding(m_pkey, params->dsa_encoding)) {
660
      params->signature =
661
114
          ConvertSignatureToDER(m_pkey, signature.ToByteSource());
662
    } else {
663
      params->signature = mode == kCryptoJobAsync
664
1534
          ? signature.ToCopy()
665
767
          : signature.ToByteSource();
666
    }
667
  }
668
669
1063
  return Just(true);
670
}
671
672
1063
bool SignTraits::DeriveBits(
673
    Environment* env,
674
    const SignConfiguration& params,
675
    ByteSource* out) {
676
1063
  ClearErrorOnReturn clear_error_on_return;
677
2126
  EVPMDPointer context(EVP_MD_CTX_new());
678
1063
  EVP_PKEY_CTX* ctx = nullptr;
679
680
1063
  switch (params.mode) {
681
    case SignConfiguration::kSign:
682
364
      if (!EVP_DigestSignInit(
683
              context.get(),
684
              &ctx,
685
182
              params.digest,
686
              nullptr,
687
              params.key.get())) {
688
        crypto::CheckThrow(env, SignBase::Error::kSignInit);
689
      }
690
182
      break;
691
    case SignConfiguration::kVerify:
692
1762
      if (!EVP_DigestVerifyInit(
693
              context.get(),
694
              &ctx,
695
881
              params.digest,
696
              nullptr,
697
              params.key.get())) {
698
        crypto::CheckThrow(env, SignBase::Error::kSignInit);
699
      }
700
881
      break;
701
  }
702
703
1063
  int padding = params.flags & SignConfiguration::kHasPadding
704
1589
      ? params.padding
705
1589
      : GetDefaultSignPadding(params.key);
706
707
1063
  Maybe<int> salt_length = params.flags & SignConfiguration::kHasSaltLength
708
1063
      ? Just<int>(params.salt_length) : Nothing<int>();
709
710
1063
  if (!ApplyRSAOptions(
711
          params.key,
712
          ctx,
713
          padding,
714
          salt_length)) {
715
1
    crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
716
  }
717
718
1063
  switch (params.mode) {
719
    case SignConfiguration::kSign: {
720
      size_t len;
721
182
      unsigned char* data = nullptr;
722
182
      if (IsOneShot(params.key)) {
723
33
        EVP_DigestSign(
724
            context.get(),
725
            nullptr,
726
            &len,
727
            params.data.data<unsigned char>(),
728
33
            params.data.size());
729
33
        data = MallocOpenSSL<unsigned char>(len);
730
33
        EVP_DigestSign(
731
            context.get(),
732
            data,
733
            &len,
734
            params.data.data<unsigned char>(),
735
33
            params.data.size());
736
        ByteSource buf =
737
66
            ByteSource::Allocated(reinterpret_cast<char*>(data), len);
738
33
        *out = std::move(buf);
739
      } else {
740
298
        if (!EVP_DigestSignUpdate(
741
                context.get(),
742
                params.data.data<unsigned char>(),
743

298
                params.data.size()) ||
744
149
            !EVP_DigestSignFinal(context.get(), nullptr, &len)) {
745
          return false;
746
        }
747
149
        data = MallocOpenSSL<unsigned char>(len);
748
        ByteSource buf =
749
298
            ByteSource::Allocated(reinterpret_cast<char*>(data), len);
750
149
        if (!EVP_DigestSignFinal(context.get(), data, &len))
751
          return false;
752
753
149
        if (UseP1363Encoding(params.key, params.dsa_encoding)) {
754
30
          *out = ConvertSignatureToP1363(env, params.key, buf);
755
        } else {
756
119
          buf.Resize(len);
757
119
          *out = std::move(buf);
758
        }
759
      }
760
182
      break;
761
    }
762
    case SignConfiguration::kVerify: {
763
881
      char* data = MallocOpenSSL<char>(1);
764
881
      data[0] = 0;
765
881
      *out = ByteSource::Allocated(data, 1);
766
881
      if (EVP_DigestVerify(
767
              context.get(),
768
              params.signature.data<unsigned char>(),
769
              params.signature.size(),
770
              params.data.data<unsigned char>(),
771
              params.data.size()) == 1) {
772
419
        data[0] = 1;
773
      }
774
    }
775
  }
776
777
1063
  return true;
778
}
779
780
1063
Maybe<bool> SignTraits::EncodeOutput(
781
    Environment* env,
782
    const SignConfiguration& params,
783
    ByteSource* out,
784
    Local<Value>* result) {
785
1063
  switch (params.mode) {
786
    case SignConfiguration::kSign:
787
364
      *result = out->ToArrayBuffer(env);
788
182
      break;
789
    case SignConfiguration::kVerify:
790
1762
      *result = out->get()[0] == 1
791
419
          ? v8::True(env->isolate())
792
2224
          : v8::False(env->isolate());
793
881
      break;
794
    default:
795
      UNREACHABLE();
796
  }
797
1063
  return Just(!result->IsEmpty());
798
}
799
800
}  // namespace crypto
801

14490
}  // namespace node