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

Line Branch Exec Source
1
#include "crypto/crypto_sig.h"
2
#include "async_wrap-inl.h"
3
#include "base_object-inl.h"
4
#include "crypto/crypto_ec.h"
5
#include "crypto/crypto_keys.h"
6
#include "crypto/crypto_util.h"
7
#include "env-inl.h"
8
#include "memory_tracker-inl.h"
9
#include "threadpoolwork-inl.h"
10
#include "v8.h"
11
12
namespace node {
13
14
using v8::ArrayBuffer;
15
using v8::BackingStore;
16
using v8::FunctionCallbackInfo;
17
using v8::FunctionTemplate;
18
using v8::HandleScope;
19
using v8::Int32;
20
using v8::Just;
21
using v8::Local;
22
using v8::Maybe;
23
using v8::Nothing;
24
using v8::Object;
25
using v8::Uint32;
26
using v8::Value;
27
28
namespace crypto {
29
namespace {
30
112
bool ValidateDSAParameters(EVP_PKEY* key) {
31
  /* Validate DSA2 parameters from FIPS 186-4 */
32
#if OPENSSL_VERSION_MAJOR >= 3
33

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1758
  if (!args[offset + 1]->IsUndefined()) {
556

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

1758
  if (!args[offset + 2]->IsUndefined()) {
562

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

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

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

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

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

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

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

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