GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: crypto/crypto_sig.cc Lines: 396 486 81.5 %
Date: 2022-01-29 04:14:08 Branches: 206 344 59.9 %

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::ArrayBuffer;
16
using v8::BackingStore;
17
using v8::FunctionCallbackInfo;
18
using v8::FunctionTemplate;
19
using v8::HandleScope;
20
using v8::Int32;
21
using v8::Just;
22
using v8::Local;
23
using v8::Maybe;
24
using v8::Nothing;
25
using v8::Object;
26
using v8::Uint32;
27
using v8::Value;
28
29
namespace crypto {
30
namespace {
31
112
bool ValidateDSAParameters(EVP_PKEY* key) {
32
  /* Validate DSA2 parameters from FIPS 186-4 */
33
#if OPENSSL_VERSION_MAJOR >= 3
34

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

3105
      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
62
923
      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
63
1592
    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
64
3
      return false;
65

2911
    if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
66
1222
      if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0)
67
12
        return false;
68
    }
69
  }
70
71
2167
  return true;
72
}
73
74
112
std::unique_ptr<BackingStore> Node_SignFinal(Environment* env,
75
                                             EVPMDPointer&& mdctx,
76
                                             const ManagedEVPPKey& pkey,
77
                                             int padding,
78
                                             Maybe<int> pss_salt_len) {
79
  unsigned char m[EVP_MAX_MD_SIZE];
80
  unsigned int m_len;
81
82
112
  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
83
    return nullptr;
84
85
112
  int signed_sig_len = EVP_PKEY_size(pkey.get());
86
112
  CHECK_GE(signed_sig_len, 0);
87
112
  size_t sig_len = static_cast<size_t>(signed_sig_len);
88
112
  std::unique_ptr<BackingStore> sig;
89
  {
90
112
    NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
91
112
    sig = ArrayBuffer::NewBackingStore(env->isolate(), sig_len);
92
  }
93
224
  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
94
112
  if (pkctx &&
95
336
      EVP_PKEY_sign_init(pkctx.get()) &&
96
216
      ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
97

328
      EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) &&
98
98
      EVP_PKEY_sign(pkctx.get(), static_cast<unsigned char*>(sig->Data()),
99
                    &sig_len, m, m_len)) {
100
97
    CHECK_LE(sig_len, sig->ByteLength());
101
97
    if (sig_len == 0)
102
      sig = ArrayBuffer::NewBackingStore(env->isolate(), 0);
103
    else
104
97
      sig = BackingStore::Reallocate(env->isolate(), std::move(sig), sig_len);
105
97
    return sig;
106
  }
107
108
15
  return nullptr;
109
}
110
111
1563
int GetDefaultSignPadding(const ManagedEVPPKey& m_pkey) {
112
1563
  return EVP_PKEY_id(m_pkey.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
113
1563
                                                         RSA_PKCS1_PADDING;
114
}
115
116
280
unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
117
280
  int bits, base_id = EVP_PKEY_base_id(pkey.get());
118
119
280
  if (base_id == EVP_PKEY_DSA) {
120
28
    const DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get());
121
    // Both r and s are computed mod q, so their width is limited by that of q.
122
28
    bits = BN_num_bits(DSA_get0_q(dsa_key));
123
252
  } else if (base_id == EVP_PKEY_EC) {
124
252
    const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
125
252
    const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
126
252
    bits = EC_GROUP_order_bits(ec_group);
127
  } else {
128
    return kNoDsaSignature;
129
  }
130
131
280
  return (bits + 7) / 8;
132
}
133
134
54
bool ExtractP1363(
135
    const unsigned char* sig_data,
136
    unsigned char* out,
137
    size_t len,
138
    size_t n) {
139
108
  ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len));
140
54
  if (!asn1_sig)
141
    return false;
142
143
54
  const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get());
144
54
  const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get());
145
146

54
  return BN_bn2binpad(pr, out, n) > 0 && BN_bn2binpad(ps, out + n, n) > 0;
147
}
148
149
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
150
std::unique_ptr<BackingStore> ConvertSignatureToP1363(Environment* env,
151
    const ManagedEVPPKey& pkey, std::unique_ptr<BackingStore>&& signature) {
152
  unsigned int n = GetBytesOfRS(pkey);
153
  if (n == kNoDsaSignature)
154
    return std::move(signature);
155
156
  std::unique_ptr<BackingStore> buf;
157
  {
158
    NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
159
    buf = ArrayBuffer::NewBackingStore(env->isolate(), 2 * n);
160
  }
161
  if (!ExtractP1363(static_cast<unsigned char*>(signature->Data()),
162
                    static_cast<unsigned char*>(buf->Data()),
163
                    signature->ByteLength(), n))
164
    return std::move(signature);
165
166
  return buf;
167
}
168
169
// Returns the maximum size of each of the integers (r, s) of the DSA signature.
170
54
ByteSource ConvertSignatureToP1363(
171
    Environment* env,
172
    const ManagedEVPPKey& pkey,
173
    const ByteSource& signature) {
174
54
  unsigned int n = GetBytesOfRS(pkey);
175
54
  if (n == kNoDsaSignature)
176
    return ByteSource();
177
178
  const unsigned char* sig_data =
179
54
      reinterpret_cast<const unsigned char*>(signature.get());
180
181
54
  char* outdata = MallocOpenSSL<char>(n * 2);
182
54
  memset(outdata, 0, n * 2);
183
108
  ByteSource out = ByteSource::Allocated(outdata, n * 2);
184
54
  unsigned char* ptr = reinterpret_cast<unsigned char*>(outdata);
185
186
54
  if (!ExtractP1363(sig_data, ptr, signature.size(), n))
187
    return ByteSource();
188
189
54
  return out;
190
}
191
192
226
ByteSource ConvertSignatureToDER(
193
      const ManagedEVPPKey& pkey,
194
      ByteSource&& out) {
195
226
  unsigned int n = GetBytesOfRS(pkey);
196
226
  if (n == kNoDsaSignature)
197
    return std::move(out);
198
199
  const unsigned char* sig_data =
200
226
      reinterpret_cast<const unsigned char*>(out.get());
201
202
226
  if (out.size() != 2 * n)
203
44
    return ByteSource();
204
205
364
  ECDSASigPointer asn1_sig(ECDSA_SIG_new());
206
182
  CHECK(asn1_sig);
207
182
  BIGNUM* r = BN_new();
208
182
  CHECK_NOT_NULL(r);
209
182
  BIGNUM* s = BN_new();
210
182
  CHECK_NOT_NULL(s);
211
182
  CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
212
182
  CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
213
182
  CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
214
215
182
  unsigned char* data = nullptr;
216
182
  int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
217
218
182
  if (len <= 0)
219
    return ByteSource();
220
221
182
  CHECK_NOT_NULL(data);
222
223
182
  return ByteSource::Allocated(reinterpret_cast<char*>(data), len);
224
}
225
226
1480
void CheckThrow(Environment* env, SignBase::Error error) {
227
1480
  HandleScope scope(env->isolate());
228
229

1480
  switch (error) {
230
1
    case SignBase::Error::kSignUnknownDigest:
231
1
      return THROW_ERR_CRYPTO_INVALID_DIGEST(env);
232
233
    case SignBase::Error::kSignNotInitialised:
234
      return THROW_ERR_CRYPTO_INVALID_STATE(env, "Not initialised");
235
236
    case SignBase::Error::kSignMalformedSignature:
237
      return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Malformed signature");
238
239
29
    case SignBase::Error::kSignInit:
240
    case SignBase::Error::kSignUpdate:
241
    case SignBase::Error::kSignPrivateKey:
242
    case SignBase::Error::kSignPublicKey:
243
      {
244
29
        unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
245
29
        if (err)
246
29
          return ThrowCryptoError(env, err);
247
        switch (error) {
248
          case SignBase::Error::kSignInit:
249
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
250
                "EVP_SignInit_ex failed");
251
          case SignBase::Error::kSignUpdate:
252
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
253
                "EVP_SignUpdate failed");
254
          case SignBase::Error::kSignPrivateKey:
255
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
256
                "PEM_read_bio_PrivateKey failed");
257
          case SignBase::Error::kSignPublicKey:
258
            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
259
                "PEM_read_bio_PUBKEY failed");
260
          default:
261
            ABORT();
262
        }
263
      }
264
265
1450
    case SignBase::Error::kSignOk:
266
1450
      return;
267
  }
268
}
269
270
288
bool IsOneShot(const ManagedEVPPKey& key) {
271
288
  switch (EVP_PKEY_id(key.get())) {
272
35
    case EVP_PKEY_ED25519:
273
    case EVP_PKEY_ED448:
274
35
      return true;
275
253
    default:
276
253
      return false;
277
  }
278
}
279
280
1445
bool UseP1363Encoding(const ManagedEVPPKey& key,
281
                      const DSASigEnc& dsa_encoding) {
282
1445
  switch (EVP_PKEY_id(key.get())) {
283
437
    case EVP_PKEY_EC:
284
    case EVP_PKEY_DSA:
285
437
      return dsa_encoding == kSigEncP1363;
286
1008
    default:
287
1008
      return false;
288
  }
289
}
290
}  // namespace
291
292
727
SignBase::Error SignBase::Init(const char* sign_type) {
293
727
  CHECK_NULL(mdctx_);
294
  // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
295
  // exposed through the public API.
296
727
  if (strcmp(sign_type, "dss1") == 0 ||
297
727
      strcmp(sign_type, "DSS1") == 0) {
298
2
    sign_type = "SHA1";
299
  }
300
727
  const EVP_MD* md = EVP_get_digestbyname(sign_type);
301
727
  if (md == nullptr)
302
1
    return kSignUnknownDigest;
303
304
726
  mdctx_.reset(EVP_MD_CTX_new());
305

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

112
  if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
407
    buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
408
    CHECK_NOT_NULL(buffer->Data());
409
  }
410
112
  return SignResult(error, std::move(buffer));
411
}
412
413
115
void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
414
115
  Environment* env = Environment::GetCurrent(args);
415
  Sign* sign;
416
133
  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
417
418
  ClearErrorOnReturn clear_error_on_return;
419
420
115
  unsigned int offset = 0;
421
115
  ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true);
422
115
  if (!key)
423
3
    return;
424
425
112
  int padding = GetDefaultSignPadding(key);
426

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

42
    CHECK(args[offset]->IsInt32());
428
63
    padding = args[offset].As<Int32>()->Value();
429
  }
430
431
112
  Maybe<int> salt_len = Nothing<int>();
432

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

108
    CHECK(args[offset + 1]->IsInt32());
434
162
    salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
435
  }
436
437

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

1746
      ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
528
582
      EVP_PKEY_CTX_set_signature_md(pkctx.get(),
529
582
                                    EVP_MD_CTX_md(mdctx.get())) > 0) {
530
582
    const unsigned char* s = reinterpret_cast<const unsigned char*>(sig.get());
531
582
    const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
532
582
    *verify_result = r == 1;
533
  }
534
535
582
  return kSignOk;
536
}
537
538
582
void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
539
582
  Environment* env = Environment::GetCurrent(args);
540
  ClearErrorOnReturn clear_error_on_return;
541
542
  Verify* verify;
543
582
  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
544
545
582
  unsigned int offset = 0;
546
  ManagedEVPPKey pkey =
547
582
      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
548
582
  if (!pkey)
549
    return;
550
551
1164
  ArrayBufferOrViewContents<char> hbuf(args[offset]);
552
582
  if (UNLIKELY(!hbuf.CheckSizeInt32()))
553
    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
554
555
582
  int padding = GetDefaultSignPadding(pkey);
556

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

744
    CHECK(args[offset + 1]->IsInt32());
558
1116
    padding = args[offset + 1].As<Int32>()->Value();
559
  }
560
561
582
  Maybe<int> salt_len = Nothing<int>();
562

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

924
    CHECK(args[offset + 2]->IsInt32());
564
1386
    salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
565
  }
566
567

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

3004
  CHECK(args[offset]->IsUint32());  // Sign Mode
624
625
1502
  params->mode =
626
4506
      static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value());
627
628
3004
  ManagedEVPPKey key;
629
1502
  unsigned int keyParamOffset = offset + 1;
630
1502
  if (params->mode == SignConfiguration::kVerify) {
631
1193
    key = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &keyParamOffset);
632
  } else {
633
309
    key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &keyParamOffset, true);
634
  }
635
1502
  if (!key)
636
7
    return Nothing<bool>();
637
1495
  params->key = key;
638
639
4485
  ArrayBufferOrViewContents<char> data(args[offset + 5]);
640
1495
  if (UNLIKELY(!data.CheckSizeInt32())) {
641
    THROW_ERR_OUT_OF_RANGE(env, "data is too big");
642
    return Nothing<bool>();
643
  }
644
  params->data = mode == kCryptoJobAsync
645
2990
      ? data.ToCopy()
646
1495
      : data.ToByteSource();
647
648

4485
  if (args[offset + 6]->IsString()) {
649
2802
    Utf8Value digest(env->isolate(), args[offset + 6]);
650
1401
    params->digest = EVP_get_digestbyname(*digest);
651
1401
    if (params->digest == nullptr) {
652
1
      THROW_ERR_CRYPTO_INVALID_DIGEST(env);
653
1
      return Nothing<bool>();
654
    }
655
  }
656
657

2988
  if (args[offset + 7]->IsInt32()) {  // Salt length
658
706
    params->flags |= SignConfiguration::kHasSaltLength;
659
2118
    params->salt_length = args[offset + 7].As<Int32>()->Value();
660
  }
661

2988
  if (args[offset + 8]->IsUint32()) {  // Padding
662
619
    params->flags |= SignConfiguration::kHasPadding;
663
1857
    params->padding = args[offset + 8].As<Uint32>()->Value();
664
  }
665
666

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

506
                params.data.size()) ||
780
253
            !EVP_DigestSignFinal(context.get(), nullptr, &len)) {
781
          crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
782
1
          return false;
783
        }
784
253
        data = MallocOpenSSL<unsigned char>(len);
785
        ByteSource buf =
786
253
            ByteSource::Allocated(reinterpret_cast<char*>(data), len);
787
253
        if (!EVP_DigestSignFinal(context.get(), data, &len)) {
788
1
          crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
789
1
          return false;
790
        }
791
792
252
        if (UseP1363Encoding(params.key, params.dsa_encoding)) {
793
54
          *out = ConvertSignatureToP1363(env, params.key, buf);
794
        } else {
795
198
          buf.Resize(len);
796
198
          *out = std::move(buf);
797
        }
798
      }
799
287
      break;
800
    }
801
1193
    case SignConfiguration::kVerify: {
802
1193
      char* data = MallocOpenSSL<char>(1);
803
1193
      data[0] = 0;
804
1193
      *out = ByteSource::Allocated(data, 1);
805
1193
      if (EVP_DigestVerify(
806
              context.get(),
807
              params.signature.data<unsigned char>(),
808
              params.signature.size(),
809
              params.data.data<unsigned char>(),
810
1193
              params.data.size()) == 1) {
811
659
        data[0] = 1;
812
      }
813
    }
814
  }
815
816
1480
  return true;
817
}
818
819
1480
Maybe<bool> SignTraits::EncodeOutput(
820
    Environment* env,
821
    const SignConfiguration& params,
822
    ByteSource* out,
823
    Local<Value>* result) {
824
1480
  switch (params.mode) {
825
287
    case SignConfiguration::kSign:
826
287
      *result = out->ToArrayBuffer(env);
827
287
      break;
828
1193
    case SignConfiguration::kVerify:
829
1193
      *result = out->get()[0] == 1
830
659
          ? v8::True(env->isolate())
831
534
          : v8::False(env->isolate());
832
1193
      break;
833
    default:
834
      UNREACHABLE();
835
  }
836
1480
  return Just(!result->IsEmpty());
837
}
838
839
}  // namespace crypto
840
}  // namespace node