GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_sig.cc Lines: 388 473 82.0 %
Date: 2021-11-08 04:13:55 Branches: 201 336 59.8 %

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

112
  if (EVP_default_properties_is_fips_enabled(nullptr) &&
33
      EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
34
#else
35
  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
2181
bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
55
                     EVP_PKEY_CTX* pkctx,
56
                     int padding,
57
                     const Maybe<int>& salt_len) {
58
3104
  if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
59

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

2910
    if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
64
1222
      if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0)
65
12
        return false;
66
    }
67
  }
68
69
2166
  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
112
  if (pkctx &&
91
336
      EVP_PKEY_sign_init(pkctx.get()) &&
92
216
      ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
93

328
      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
1562
int GetDefaultSignPadding(const ManagedEVPPKey& m_pkey) {
103
1562
  return EVP_PKEY_id(m_pkey.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
104
1562
                                                         RSA_PKCS1_PADDING;
105
}
106
107
280
unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
108
280
  int bits, base_id = EVP_PKEY_base_id(pkey.get());
109
110
280
  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
252
  } else if (base_id == EVP_PKEY_EC) {
115
252
    const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
116
252
    const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
117
252
    bits = EC_GROUP_order_bits(ec_group);
118
  } else {
119
    return kNoDsaSignature;
120
  }
121
122
280
  return (bits + 7) / 8;
123
}
124
125
54
bool ExtractP1363(
126
    const unsigned char* sig_data,
127
    unsigned char* out,
128
    size_t len,
129
    size_t n) {
130
108
  ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len));
131
54
  if (!asn1_sig)
132
    return false;
133
134
54
  const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get());
135
54
  const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get());
136
137

54
  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
54
ByteSource ConvertSignatureToP1363(
162
    Environment* env,
163
    const ManagedEVPPKey& pkey,
164
    const ByteSource& signature) {
165
54
  unsigned int n = GetBytesOfRS(pkey);
166
54
  if (n == kNoDsaSignature)
167
    return ByteSource();
168
169
  const unsigned char* sig_data =
170
54
      reinterpret_cast<const unsigned char*>(signature.get());
171
172
54
  char* outdata = MallocOpenSSL<char>(n * 2);
173
54
  memset(outdata, 0, n * 2);
174
108
  ByteSource out = ByteSource::Allocated(outdata, n * 2);
175
54
  unsigned char* ptr = reinterpret_cast<unsigned char*>(outdata);
176
177
54
  if (!ExtractP1363(sig_data, ptr, signature.size(), n))
178
    return ByteSource();
179
180
54
  return out;
181
}
182
183
226
ByteSource ConvertSignatureToDER(
184
      const ManagedEVPPKey& pkey,
185
      ByteSource&& out) {
186
226
  unsigned int n = GetBytesOfRS(pkey);
187
226
  if (n == kNoDsaSignature)
188
    return std::move(out);
189
190
  const unsigned char* sig_data =
191
226
      reinterpret_cast<const unsigned char*>(out.get());
192
193
226
  if (out.size() != 2 * n)
194
44
    return ByteSource();
195
196
364
  ECDSASigPointer asn1_sig(ECDSA_SIG_new());
197
182
  CHECK(asn1_sig);
198
182
  BIGNUM* r = BN_new();
199
182
  CHECK_NOT_NULL(r);
200
182
  BIGNUM* s = BN_new();
201
182
  CHECK_NOT_NULL(s);
202
182
  CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
203
182
  CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
204
182
  CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
205
206
182
  unsigned char* data = nullptr;
207
182
  int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
208
209
182
  if (len <= 0)
210
    return ByteSource();
211
212
182
  CHECK_NOT_NULL(data);
213
214
182
  return ByteSource::Allocated(reinterpret_cast<char*>(data), len);
215
}
216
217
1479
void CheckThrow(Environment* env, SignBase::Error error) {
218
1479
  HandleScope scope(env->isolate());
219
220

1479
  switch (error) {
221
1
    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
28
    case SignBase::Error::kSignInit:
231
    case SignBase::Error::kSignUpdate:
232
    case SignBase::Error::kSignPrivateKey:
233
    case SignBase::Error::kSignPublicKey:
234
      {
235
28
        unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
236
28
        if (err)
237
28
          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
1450
    case SignBase::Error::kSignOk:
257
1450
      return;
258
  }
259
}
260
261
287
bool IsOneShot(const ManagedEVPPKey& key) {
262
287
  switch (EVP_PKEY_id(key.get())) {
263
35
    case EVP_PKEY_ED25519:
264
    case EVP_PKEY_ED448:
265
35
      return true;
266
252
    default:
267
252
      return false;
268
  }
269
}
270
271
1445
bool UseP1363Encoding(const ManagedEVPPKey& key,
272
                      const DSASigEnc& dsa_encoding) {
273
1445
  switch (EVP_PKEY_id(key.get())) {
274
437
    case EVP_PKEY_EC:
275
    case EVP_PKEY_DSA:
276
437
      return dsa_encoding == kSigEncP1363;
277
1008
    default:
278
1008
      return false;
279
  }
280
}
281
}  // namespace
282
283
727
SignBase::Error SignBase::Init(const char* sign_type) {
284
727
  CHECK_NULL(mdctx_);
285
  // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
286
  // exposed through the public API.
287
727
  if (strcmp(sign_type, "dss1") == 0 ||
288
727
      strcmp(sign_type, "DSS1") == 0) {
289
2
    sign_type = "SHA1";
290
  }
291
727
  const EVP_MD* md = EVP_get_digestbyname(sign_type);
292
727
  if (md == nullptr)
293
1
    return kSignUnknownDigest;
294
295
726
  mdctx_.reset(EVP_MD_CTX_new());
296

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

112
  if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
398
    buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
399
    CHECK_NOT_NULL(buffer.data());
400
  }
401
112
  return SignResult(error, std::move(buffer));
402
}
403
404
115
void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
405
115
  Environment* env = Environment::GetCurrent(args);
406
  Sign* sign;
407
133
  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
408
409
  ClearErrorOnReturn clear_error_on_return;
410
411
115
  unsigned int offset = 0;
412
115
  ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true);
413
115
  if (!key)
414
3
    return;
415
416
112
  int padding = GetDefaultSignPadding(key);
417

336
  if (!args[offset]->IsUndefined()) {
418

42
    CHECK(args[offset]->IsInt32());
419
63
    padding = args[offset].As<Int32>()->Value();
420
  }
421
422
112
  Maybe<int> salt_len = Nothing<int>();
423

336
  if (!args[offset + 1]->IsUndefined()) {
424

108
    CHECK(args[offset + 1]->IsInt32());
425
162
    salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
426
  }
427
428

224
  CHECK(args[offset + 2]->IsInt32());
429
  DSASigEnc dsa_sig_enc =
430
336
      static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value());
431
432
  SignResult ret = sign->SignFinal(
433
      key,
434
      padding,
435
      salt_len,
436
112
      dsa_sig_enc);
437
438
112
  if (ret.error != kSignOk)
439
15
    return crypto::CheckThrow(env, ret.error);
440
441
291
  args.GetReturnValue().Set(ret.signature.ToBuffer().FromMaybe(Local<Value>()));
442
}
443
444
589
Verify::Verify(Environment* env, Local<Object> wrap)
445
589
  : SignBase(env, wrap) {
446
589
  MakeWeak();
447
589
}
448
449
4316
void Verify::Initialize(Environment* env, Local<Object> target) {
450
4316
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
451
452
8632
  t->InstanceTemplate()->SetInternalFieldCount(
453
      SignBase::kInternalFieldCount);
454
4316
  t->Inherit(BaseObject::GetConstructorTemplate(env));
455
456
4316
  env->SetProtoMethod(t, "init", VerifyInit);
457
4316
  env->SetProtoMethod(t, "update", VerifyUpdate);
458
4316
  env->SetProtoMethod(t, "verify", VerifyFinal);
459
460
4316
  env->SetConstructorFunction(target, "Verify", t);
461
4316
}
462
463
4872
void Verify::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
464
4872
  registry->Register(New);
465
4872
  registry->Register(VerifyInit);
466
4872
  registry->Register(VerifyUpdate);
467
4872
  registry->Register(VerifyFinal);
468
4872
}
469
470
589
void Verify::New(const FunctionCallbackInfo<Value>& args) {
471
589
  Environment* env = Environment::GetCurrent(args);
472
589
  new Verify(env, args.This());
473
589
}
474
475
589
void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
476
589
  Environment* env = Environment::GetCurrent(args);
477
  Verify* verify;
478
589
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
479
480
1178
  const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
481
589
  crypto::CheckThrow(env, verify->Init(*verify_type));
482
}
483
484
599
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
485
599
  Decode<Verify>(args, [](Verify* verify,
486
                          const FunctionCallbackInfo<Value>& args,
487
599
                          const char* data, size_t size) {
488
599
    Environment* env = Environment::GetCurrent(args);
489
599
    if (UNLIKELY(size > INT_MAX))
490
      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
491
599
    Error err = verify->Update(data, size);
492
599
    crypto::CheckThrow(verify->env(), err);
493
  });
494
599
}
495
496
582
SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey,
497
                                    const ByteSource& sig,
498
                                    int padding,
499
                                    const Maybe<int>& saltlen,
500
                                    bool* verify_result) {
501
582
  if (!mdctx_)
502
    return kSignNotInitialised;
503
504
  unsigned char m[EVP_MAX_MD_SIZE];
505
  unsigned int m_len;
506
582
  *verify_result = false;
507
1164
  EVPMDPointer mdctx = std::move(mdctx_);
508
509
582
  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
510
    return kSignPublicKey;
511
512
582
  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
513
582
  if (pkctx &&
514
1746
      EVP_PKEY_verify_init(pkctx.get()) > 0 &&
515

1746
      ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
516
582
      EVP_PKEY_CTX_set_signature_md(pkctx.get(),
517
582
                                    EVP_MD_CTX_md(mdctx.get())) > 0) {
518
582
    const unsigned char* s = reinterpret_cast<const unsigned char*>(sig.get());
519
582
    const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
520
582
    *verify_result = r == 1;
521
  }
522
523
582
  return kSignOk;
524
}
525
526
582
void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
527
582
  Environment* env = Environment::GetCurrent(args);
528
  ClearErrorOnReturn clear_error_on_return;
529
530
  Verify* verify;
531
582
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
532
533
582
  unsigned int offset = 0;
534
  ManagedEVPPKey pkey =
535
582
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
536
582
  if (!pkey)
537
    return;
538
539
1164
  ArrayBufferOrViewContents<char> hbuf(args[offset]);
540
582
  if (UNLIKELY(!hbuf.CheckSizeInt32()))
541
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
542
543
582
  int padding = GetDefaultSignPadding(pkey);
544

1746
  if (!args[offset + 1]->IsUndefined()) {
545

744
    CHECK(args[offset + 1]->IsInt32());
546
1116
    padding = args[offset + 1].As<Int32>()->Value();
547
  }
548
549
582
  Maybe<int> salt_len = Nothing<int>();
550

1746
  if (!args[offset + 2]->IsUndefined()) {
551

924
    CHECK(args[offset + 2]->IsInt32());
552
1386
    salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
553
  }
554
555

1164
  CHECK(args[offset + 3]->IsInt32());
556
  DSASigEnc dsa_sig_enc =
557
1746
      static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value());
558
559
582
  ByteSource signature = hbuf.ToByteSource();
560
582
  if (dsa_sig_enc == kSigEncP1363) {
561
4
    signature = ConvertSignatureToDER(pkey, hbuf.ToByteSource());
562
4
    if (signature.get() == nullptr)
563
      return crypto::CheckThrow(env, Error::kSignMalformedSignature);
564
  }
565
566
  bool verify_result;
567
582
  Error err = verify->VerifyFinal(pkey, signature, padding,
568
                                  salt_len, &verify_result);
569
582
  if (err != kSignOk)
570
    return crypto::CheckThrow(env, err);
571
1164
  args.GetReturnValue().Set(verify_result);
572
}
573
574
1493
SignConfiguration::SignConfiguration(SignConfiguration&& other) noexcept
575
1493
    : job_mode(other.job_mode),
576
1493
      mode(other.mode),
577
1493
      key(std::move(other.key)),
578
1493
      data(std::move(other.data)),
579
1493
      signature(std::move(other.signature)),
580
1493
      digest(other.digest),
581
1493
      flags(other.flags),
582
1493
      padding(other.padding),
583
1493
      salt_length(other.salt_length),
584
1493
      dsa_encoding(other.dsa_encoding) {}
585
586
SignConfiguration& SignConfiguration::operator=(
587
    SignConfiguration&& other) noexcept {
588
  if (&other == this) return *this;
589
  this->~SignConfiguration();
590
  return *new (this) SignConfiguration(std::move(other));
591
}
592
593
void SignConfiguration::MemoryInfo(MemoryTracker* tracker) const {
594
  tracker->TrackField("key", key);
595
  if (job_mode == kCryptoJobAsync) {
596
    tracker->TrackFieldWithSize("data", data.size());
597
    tracker->TrackFieldWithSize("signature", signature.size());
598
  }
599
}
600
601
1501
Maybe<bool> SignTraits::AdditionalConfig(
602
    CryptoJobMode mode,
603
    const FunctionCallbackInfo<Value>& args,
604
    unsigned int offset,
605
    SignConfiguration* params) {
606
1501
  ClearErrorOnReturn clear_error_on_return;
607
1501
  Environment* env = Environment::GetCurrent(args);
608
609
1501
  params->job_mode = mode;
610
611

3002
  CHECK(args[offset]->IsUint32());  // Sign Mode
612
613
1501
  params->mode =
614
4503
      static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value());
615
616
3002
  ManagedEVPPKey key;
617
1501
  unsigned int keyParamOffset = offset + 1;
618
1501
  if (params->mode == SignConfiguration::kVerify) {
619
1193
    key = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &keyParamOffset);
620
  } else {
621
308
    key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &keyParamOffset, true);
622
  }
623
1501
  if (!key)
624
7
    return Nothing<bool>();
625
1494
  params->key = key;
626
627
4482
  ArrayBufferOrViewContents<char> data(args[offset + 5]);
628
1494
  if (UNLIKELY(!data.CheckSizeInt32())) {
629
    THROW_ERR_OUT_OF_RANGE(env, "data is too big");
630
    return Nothing<bool>();
631
  }
632
  params->data = mode == kCryptoJobAsync
633
2988
      ? data.ToCopy()
634
1494
      : data.ToByteSource();
635
636

4482
  if (args[offset + 6]->IsString()) {
637
2800
    Utf8Value digest(env->isolate(), args[offset + 6]);
638
1400
    params->digest = EVP_get_digestbyname(*digest);
639
1400
    if (params->digest == nullptr) {
640
1
      THROW_ERR_CRYPTO_INVALID_DIGEST(env);
641
1
      return Nothing<bool>();
642
    }
643
  }
644
645

2986
  if (args[offset + 7]->IsInt32()) {  // Salt length
646
706
    params->flags |= SignConfiguration::kHasSaltLength;
647
2118
    params->salt_length = args[offset + 7].As<Int32>()->Value();
648
  }
649

2986
  if (args[offset + 8]->IsUint32()) {  // Padding
650
619
    params->flags |= SignConfiguration::kHasPadding;
651
1857
    params->padding = args[offset + 8].As<Uint32>()->Value();
652
  }
653
654

2986
  if (args[offset + 9]->IsUint32()) {  // DSA Encoding
655
1237
    params->dsa_encoding =
656
3711
        static_cast<DSASigEnc>(args[offset + 9].As<Uint32>()->Value());
657
1237
    if (params->dsa_encoding != kSigEncDER &&
658
298
        params->dsa_encoding != kSigEncP1363) {
659
      THROW_ERR_OUT_OF_RANGE(env, "invalid signature encoding");
660
      return Nothing<bool>();
661
    }
662
  }
663
664
1493
  if (params->mode == SignConfiguration::kVerify) {
665
2386
    ArrayBufferOrViewContents<char> signature(args[offset + 10]);
666
1193
    if (UNLIKELY(!signature.CheckSizeInt32())) {
667
      THROW_ERR_OUT_OF_RANGE(env, "signature is too big");
668
      return Nothing<bool>();
669
    }
670
    // If this is an EC key (assuming ECDSA) we need to convert the
671
    // the signature from WebCrypto format into DER format...
672
2386
    ManagedEVPPKey m_pkey = params->key;
673
2386
    Mutex::ScopedLock lock(*m_pkey.mutex());
674
1193
    if (UseP1363Encoding(m_pkey, params->dsa_encoding)) {
675
      params->signature =
676
222
          ConvertSignatureToDER(m_pkey, signature.ToByteSource());
677
    } else {
678
      params->signature = mode == kCryptoJobAsync
679
1942
          ? signature.ToCopy()
680
971
          : signature.ToByteSource();
681
    }
682
  }
683
684
1493
  return Just(true);
685
}
686
687
1493
bool SignTraits::DeriveBits(
688
    Environment* env,
689
    const SignConfiguration& params,
690
    ByteSource* out) {
691
1493
  ClearErrorOnReturn clear_error_on_return;
692
2986
  EVPMDPointer context(EVP_MD_CTX_new());
693
1493
  EVP_PKEY_CTX* ctx = nullptr;
694
695
1493
  switch (params.mode) {
696
300
    case SignConfiguration::kSign:
697
600
      if (!EVP_DigestSignInit(
698
              context.get(),
699
              &ctx,
700
300
              params.digest,
701
              nullptr,
702
              params.key.get())) {
703
6
        crypto::CheckThrow(env, SignBase::Error::kSignInit);
704
6
        return false;
705
      }
706
294
      break;
707
1193
    case SignConfiguration::kVerify:
708
2386
      if (!EVP_DigestVerifyInit(
709
              context.get(),
710
              &ctx,
711
1193
              params.digest,
712
              nullptr,
713
              params.key.get())) {
714
        crypto::CheckThrow(env, SignBase::Error::kSignInit);
715
        return false;
716
      }
717
1193
      break;
718
  }
719
720
1487
  int padding = params.flags & SignConfiguration::kHasPadding
721
1487
      ? params.padding
722
868
      : GetDefaultSignPadding(params.key);
723
724
1487
  Maybe<int> salt_length = params.flags & SignConfiguration::kHasSaltLength
725
1487
      ? Just<int>(params.salt_length) : Nothing<int>();
726
727
1487
  if (!ApplyRSAOptions(
728
1487
          params.key,
729
          ctx,
730
          padding,
731
          salt_length)) {
732
7
    crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
733
7
    return false;
734
  }
735
736
1480
  switch (params.mode) {
737
287
    case SignConfiguration::kSign: {
738
      size_t len;
739
287
      unsigned char* data = nullptr;
740
287
      if (IsOneShot(params.key)) {
741
35
        EVP_DigestSign(
742
            context.get(),
743
            nullptr,
744
            &len,
745
            params.data.data<unsigned char>(),
746
            params.data.size());
747
35
        data = MallocOpenSSL<unsigned char>(len);
748
35
        EVP_DigestSign(
749
            context.get(),
750
            data,
751
            &len,
752
            params.data.data<unsigned char>(),
753
            params.data.size());
754
        ByteSource buf =
755
70
            ByteSource::Allocated(reinterpret_cast<char*>(data), len);
756
35
        *out = std::move(buf);
757
      } else {
758
504
        if (!EVP_DigestSignUpdate(
759
                context.get(),
760
252
                params.data.data<unsigned char>(),
761

504
                params.data.size()) ||
762
252
            !EVP_DigestSignFinal(context.get(), nullptr, &len)) {
763
          return false;
764
        }
765
252
        data = MallocOpenSSL<unsigned char>(len);
766
        ByteSource buf =
767
252
            ByteSource::Allocated(reinterpret_cast<char*>(data), len);
768
252
        if (!EVP_DigestSignFinal(context.get(), data, &len))
769
          return false;
770
771
252
        if (UseP1363Encoding(params.key, params.dsa_encoding)) {
772
54
          *out = ConvertSignatureToP1363(env, params.key, buf);
773
        } else {
774
198
          buf.Resize(len);
775
198
          *out = std::move(buf);
776
        }
777
      }
778
287
      break;
779
    }
780
1193
    case SignConfiguration::kVerify: {
781
1193
      char* data = MallocOpenSSL<char>(1);
782
1193
      data[0] = 0;
783
1193
      *out = ByteSource::Allocated(data, 1);
784
1193
      if (EVP_DigestVerify(
785
              context.get(),
786
              params.signature.data<unsigned char>(),
787
              params.signature.size(),
788
              params.data.data<unsigned char>(),
789
1193
              params.data.size()) == 1) {
790
659
        data[0] = 1;
791
      }
792
    }
793
  }
794
795
1480
  return true;
796
}
797
798
1480
Maybe<bool> SignTraits::EncodeOutput(
799
    Environment* env,
800
    const SignConfiguration& params,
801
    ByteSource* out,
802
    Local<Value>* result) {
803
1480
  switch (params.mode) {
804
287
    case SignConfiguration::kSign:
805
287
      *result = out->ToArrayBuffer(env);
806
287
      break;
807
1193
    case SignConfiguration::kVerify:
808
1193
      *result = out->get()[0] == 1
809
659
          ? v8::True(env->isolate())
810
534
          : v8::False(env->isolate());
811
1193
      break;
812
    default:
813
      UNREACHABLE();
814
  }
815
1480
  return Just(!result->IsEmpty());
816
}
817
818
}  // namespace crypto
819
}  // namespace node