xref: /third_party/node/src/crypto/crypto_sig.cc (revision 1cb0ef41)
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
12namespace node {
13
14using v8::ArrayBuffer;
15using v8::BackingStore;
16using v8::Boolean;
17using v8::FunctionCallbackInfo;
18using v8::FunctionTemplate;
19using v8::HandleScope;
20using v8::Int32;
21using v8::Isolate;
22using v8::Just;
23using v8::Local;
24using v8::Maybe;
25using v8::Nothing;
26using v8::Object;
27using v8::Uint32;
28using v8::Value;
29
30namespace crypto {
31namespace {
32bool ValidateDSAParameters(EVP_PKEY* key) {
33  /* Validate DSA2 parameters from FIPS 186-4 */
34#if OPENSSL_VERSION_MAJOR >= 3
35  if (EVP_default_properties_is_fips_enabled(nullptr) &&
36      EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
37#else
38  if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) {
39#endif
40    const DSA* dsa = EVP_PKEY_get0_DSA(key);
41    const BIGNUM* p;
42    DSA_get0_pqg(dsa, &p, nullptr, nullptr);
43    size_t L = BN_num_bits(p);
44    const BIGNUM* q;
45    DSA_get0_pqg(dsa, nullptr, &q, nullptr);
46    size_t N = BN_num_bits(q);
47
48    return (L == 1024 && N == 160) ||
49           (L == 2048 && N == 224) ||
50           (L == 2048 && N == 256) ||
51           (L == 3072 && N == 256);
52  }
53
54  return true;
55}
56
57bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
58                     EVP_PKEY_CTX* pkctx,
59                     int padding,
60                     const Maybe<int>& salt_len) {
61  if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
62      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
63      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
64    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
65      return false;
66    if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
67      if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0)
68        return false;
69    }
70  }
71
72  return true;
73}
74
75std::unique_ptr<BackingStore> Node_SignFinal(Environment* env,
76                                             EVPMDPointer&& mdctx,
77                                             const ManagedEVPPKey& pkey,
78                                             int padding,
79                                             Maybe<int> pss_salt_len) {
80  unsigned char m[EVP_MAX_MD_SIZE];
81  unsigned int m_len;
82
83  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
84    return nullptr;
85
86  int signed_sig_len = EVP_PKEY_size(pkey.get());
87  CHECK_GE(signed_sig_len, 0);
88  size_t sig_len = static_cast<size_t>(signed_sig_len);
89  std::unique_ptr<BackingStore> sig;
90  {
91    NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
92    sig = ArrayBuffer::NewBackingStore(env->isolate(), sig_len);
93  }
94  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
95  if (pkctx &&
96      EVP_PKEY_sign_init(pkctx.get()) &&
97      ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) &&
98      EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) &&
99      EVP_PKEY_sign(pkctx.get(), static_cast<unsigned char*>(sig->Data()),
100                    &sig_len, m, m_len)) {
101    CHECK_LE(sig_len, sig->ByteLength());
102    if (sig_len == 0)
103      sig = ArrayBuffer::NewBackingStore(env->isolate(), 0);
104    else
105      sig = BackingStore::Reallocate(env->isolate(), std::move(sig), sig_len);
106    return sig;
107  }
108
109  return nullptr;
110}
111
112int GetDefaultSignPadding(const ManagedEVPPKey& m_pkey) {
113  return EVP_PKEY_id(m_pkey.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
114                                                         RSA_PKCS1_PADDING;
115}
116
117unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) {
118  int bits, base_id = EVP_PKEY_base_id(pkey.get());
119
120  if (base_id == EVP_PKEY_DSA) {
121    const DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get());
122    // Both r and s are computed mod q, so their width is limited by that of q.
123    bits = BN_num_bits(DSA_get0_q(dsa_key));
124  } else if (base_id == EVP_PKEY_EC) {
125    const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
126    const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
127    bits = EC_GROUP_order_bits(ec_group);
128  } else {
129    return kNoDsaSignature;
130  }
131
132  return (bits + 7) / 8;
133}
134
135bool ExtractP1363(
136    const unsigned char* sig_data,
137    unsigned char* out,
138    size_t len,
139    size_t n) {
140  ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len));
141  if (!asn1_sig)
142    return false;
143
144  const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get());
145  const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get());
146
147  return BN_bn2binpad(pr, out, n) > 0 && BN_bn2binpad(ps, out + n, n) > 0;
148}
149
150// Returns the maximum size of each of the integers (r, s) of the DSA signature.
151std::unique_ptr<BackingStore> ConvertSignatureToP1363(Environment* env,
152    const ManagedEVPPKey& pkey, std::unique_ptr<BackingStore>&& signature) {
153  unsigned int n = GetBytesOfRS(pkey);
154  if (n == kNoDsaSignature)
155    return std::move(signature);
156
157  std::unique_ptr<BackingStore> buf;
158  {
159    NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
160    buf = ArrayBuffer::NewBackingStore(env->isolate(), 2 * n);
161  }
162  if (!ExtractP1363(static_cast<unsigned char*>(signature->Data()),
163                    static_cast<unsigned char*>(buf->Data()),
164                    signature->ByteLength(), n))
165    return std::move(signature);
166
167  return buf;
168}
169
170// Returns the maximum size of each of the integers (r, s) of the DSA signature.
171ByteSource ConvertSignatureToP1363(
172    Environment* env,
173    const ManagedEVPPKey& pkey,
174    const ByteSource& signature) {
175  unsigned int n = GetBytesOfRS(pkey);
176  if (n == kNoDsaSignature)
177    return ByteSource();
178
179  const unsigned char* sig_data = signature.data<unsigned char>();
180
181  ByteSource::Builder out(n * 2);
182  memset(out.data<void>(), 0, n * 2);
183
184  if (!ExtractP1363(sig_data, out.data<unsigned char>(), signature.size(), n))
185    return ByteSource();
186
187  return std::move(out).release();
188}
189
190ByteSource ConvertSignatureToDER(
191      const ManagedEVPPKey& pkey,
192      ByteSource&& out) {
193  unsigned int n = GetBytesOfRS(pkey);
194  if (n == kNoDsaSignature)
195    return std::move(out);
196
197  const unsigned char* sig_data = out.data<unsigned char>();
198
199  if (out.size() != 2 * n)
200    return ByteSource();
201
202  ECDSASigPointer asn1_sig(ECDSA_SIG_new());
203  CHECK(asn1_sig);
204  BIGNUM* r = BN_new();
205  CHECK_NOT_NULL(r);
206  BIGNUM* s = BN_new();
207  CHECK_NOT_NULL(s);
208  CHECK_EQ(r, BN_bin2bn(sig_data, n, r));
209  CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s));
210  CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s));
211
212  unsigned char* data = nullptr;
213  int len = i2d_ECDSA_SIG(asn1_sig.get(), &data);
214
215  if (len <= 0)
216    return ByteSource();
217
218  CHECK_NOT_NULL(data);
219
220  return ByteSource::Allocated(data, len);
221}
222
223void CheckThrow(Environment* env, SignBase::Error error) {
224  HandleScope scope(env->isolate());
225
226  switch (error) {
227    case SignBase::Error::kSignUnknownDigest:
228      return THROW_ERR_CRYPTO_INVALID_DIGEST(env);
229
230    case SignBase::Error::kSignNotInitialised:
231      return THROW_ERR_CRYPTO_INVALID_STATE(env, "Not initialised");
232
233    case SignBase::Error::kSignMalformedSignature:
234      return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Malformed signature");
235
236    case SignBase::Error::kSignInit:
237    case SignBase::Error::kSignUpdate:
238    case SignBase::Error::kSignPrivateKey:
239    case SignBase::Error::kSignPublicKey:
240      {
241        unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
242        if (err)
243          return ThrowCryptoError(env, err);
244        switch (error) {
245          case SignBase::Error::kSignInit:
246            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
247                "EVP_SignInit_ex failed");
248          case SignBase::Error::kSignUpdate:
249            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
250                "EVP_SignUpdate failed");
251          case SignBase::Error::kSignPrivateKey:
252            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
253                "PEM_read_bio_PrivateKey failed");
254          case SignBase::Error::kSignPublicKey:
255            return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
256                "PEM_read_bio_PUBKEY failed");
257          default:
258            ABORT();
259        }
260      }
261
262    case SignBase::Error::kSignOk:
263      return;
264  }
265}
266
267bool IsOneShot(const ManagedEVPPKey& key) {
268  switch (EVP_PKEY_id(key.get())) {
269    case EVP_PKEY_ED25519:
270    case EVP_PKEY_ED448:
271      return true;
272    default:
273      return false;
274  }
275}
276
277bool UseP1363Encoding(const ManagedEVPPKey& key,
278                      const DSASigEnc& dsa_encoding) {
279  switch (EVP_PKEY_id(key.get())) {
280    case EVP_PKEY_EC:
281    case EVP_PKEY_DSA:
282      return dsa_encoding == kSigEncP1363;
283    default:
284      return false;
285  }
286}
287}  // namespace
288
289SignBase::Error SignBase::Init(const char* sign_type) {
290  CHECK_NULL(mdctx_);
291  // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
292  // exposed through the public API.
293  if (strcmp(sign_type, "dss1") == 0 ||
294      strcmp(sign_type, "DSS1") == 0) {
295    sign_type = "SHA1";
296  }
297  const EVP_MD* md = EVP_get_digestbyname(sign_type);
298  if (md == nullptr)
299    return kSignUnknownDigest;
300
301  mdctx_.reset(EVP_MD_CTX_new());
302  if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) {
303    mdctx_.reset();
304    return kSignInit;
305  }
306
307  return kSignOk;
308}
309
310SignBase::Error SignBase::Update(const char* data, size_t len) {
311  if (mdctx_ == nullptr)
312    return kSignNotInitialised;
313  if (!EVP_DigestUpdate(mdctx_.get(), data, len))
314    return kSignUpdate;
315  return kSignOk;
316}
317
318SignBase::SignBase(Environment* env, Local<Object> wrap)
319    : BaseObject(env, wrap) {}
320
321void SignBase::MemoryInfo(MemoryTracker* tracker) const {
322  tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0);
323}
324
325Sign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) {
326  MakeWeak();
327}
328
329void Sign::Initialize(Environment* env, Local<Object> target) {
330  Isolate* isolate = env->isolate();
331  Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New);
332
333  t->InstanceTemplate()->SetInternalFieldCount(
334      SignBase::kInternalFieldCount);
335  t->Inherit(BaseObject::GetConstructorTemplate(env));
336
337  SetProtoMethod(isolate, t, "init", SignInit);
338  SetProtoMethod(isolate, t, "update", SignUpdate);
339  SetProtoMethod(isolate, t, "sign", SignFinal);
340
341  SetConstructorFunction(env->context(), target, "Sign", t);
342
343  SignJob::Initialize(env, target);
344
345  constexpr int kSignJobModeSign = SignConfiguration::kSign;
346  constexpr int kSignJobModeVerify = SignConfiguration::kVerify;
347
348  NODE_DEFINE_CONSTANT(target, kSignJobModeSign);
349  NODE_DEFINE_CONSTANT(target, kSignJobModeVerify);
350  NODE_DEFINE_CONSTANT(target, kSigEncDER);
351  NODE_DEFINE_CONSTANT(target, kSigEncP1363);
352  NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING);
353}
354
355void Sign::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
356  registry->Register(New);
357  registry->Register(SignInit);
358  registry->Register(SignUpdate);
359  registry->Register(SignFinal);
360  SignJob::RegisterExternalReferences(registry);
361}
362
363void Sign::New(const FunctionCallbackInfo<Value>& args) {
364  Environment* env = Environment::GetCurrent(args);
365  new Sign(env, args.This());
366}
367
368void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
369  Environment* env = Environment::GetCurrent(args);
370  Sign* sign;
371  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
372
373  const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
374  crypto::CheckThrow(env, sign->Init(*sign_type));
375}
376
377void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
378  Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args,
379                        const char* data, size_t size) {
380    Environment* env = Environment::GetCurrent(args);
381    if (UNLIKELY(size > INT_MAX))
382      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
383    Error err = sign->Update(data, size);
384    crypto::CheckThrow(sign->env(), err);
385  });
386}
387
388Sign::SignResult Sign::SignFinal(
389    const ManagedEVPPKey& pkey,
390    int padding,
391    const Maybe<int>& salt_len,
392    DSASigEnc dsa_sig_enc) {
393  if (!mdctx_)
394    return SignResult(kSignNotInitialised);
395
396  EVPMDPointer mdctx = std::move(mdctx_);
397
398  if (!ValidateDSAParameters(pkey.get()))
399    return SignResult(kSignPrivateKey);
400
401  std::unique_ptr<BackingStore> buffer =
402      Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len);
403  Error error = buffer ? kSignOk : kSignPrivateKey;
404  if (error == kSignOk && dsa_sig_enc == kSigEncP1363) {
405    buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer));
406    CHECK_NOT_NULL(buffer->Data());
407  }
408  return SignResult(error, std::move(buffer));
409}
410
411void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
412  Environment* env = Environment::GetCurrent(args);
413  Sign* sign;
414  ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
415
416  ClearErrorOnReturn clear_error_on_return;
417
418  unsigned int offset = 0;
419  ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true);
420  if (!key)
421    return;
422
423  int padding = GetDefaultSignPadding(key);
424  if (!args[offset]->IsUndefined()) {
425    CHECK(args[offset]->IsInt32());
426    padding = args[offset].As<Int32>()->Value();
427  }
428
429  Maybe<int> salt_len = Nothing<int>();
430  if (!args[offset + 1]->IsUndefined()) {
431    CHECK(args[offset + 1]->IsInt32());
432    salt_len = Just<int>(args[offset + 1].As<Int32>()->Value());
433  }
434
435  CHECK(args[offset + 2]->IsInt32());
436  DSASigEnc dsa_sig_enc =
437      static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value());
438
439  SignResult ret = sign->SignFinal(
440      key,
441      padding,
442      salt_len,
443      dsa_sig_enc);
444
445  if (ret.error != kSignOk)
446    return crypto::CheckThrow(env, ret.error);
447
448  Local<ArrayBuffer> ab =
449      ArrayBuffer::New(env->isolate(), std::move(ret.signature));
450  args.GetReturnValue().Set(
451      Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()));
452}
453
454Verify::Verify(Environment* env, Local<Object> wrap)
455  : SignBase(env, wrap) {
456  MakeWeak();
457}
458
459void Verify::Initialize(Environment* env, Local<Object> target) {
460  Isolate* isolate = env->isolate();
461  Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New);
462
463  t->InstanceTemplate()->SetInternalFieldCount(
464      SignBase::kInternalFieldCount);
465  t->Inherit(BaseObject::GetConstructorTemplate(env));
466
467  SetProtoMethod(isolate, t, "init", VerifyInit);
468  SetProtoMethod(isolate, t, "update", VerifyUpdate);
469  SetProtoMethod(isolate, t, "verify", VerifyFinal);
470
471  SetConstructorFunction(env->context(), target, "Verify", t);
472}
473
474void Verify::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
475  registry->Register(New);
476  registry->Register(VerifyInit);
477  registry->Register(VerifyUpdate);
478  registry->Register(VerifyFinal);
479}
480
481void Verify::New(const FunctionCallbackInfo<Value>& args) {
482  Environment* env = Environment::GetCurrent(args);
483  new Verify(env, args.This());
484}
485
486void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
487  Environment* env = Environment::GetCurrent(args);
488  Verify* verify;
489  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
490
491  const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
492  crypto::CheckThrow(env, verify->Init(*verify_type));
493}
494
495void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
496  Decode<Verify>(args, [](Verify* verify,
497                          const FunctionCallbackInfo<Value>& args,
498                          const char* data, size_t size) {
499    Environment* env = Environment::GetCurrent(args);
500    if (UNLIKELY(size > INT_MAX))
501      return THROW_ERR_OUT_OF_RANGE(env, "data is too long");
502    Error err = verify->Update(data, size);
503    crypto::CheckThrow(verify->env(), err);
504  });
505}
506
507SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey,
508                                    const ByteSource& sig,
509                                    int padding,
510                                    const Maybe<int>& saltlen,
511                                    bool* verify_result) {
512  if (!mdctx_)
513    return kSignNotInitialised;
514
515  unsigned char m[EVP_MAX_MD_SIZE];
516  unsigned int m_len;
517  *verify_result = false;
518  EVPMDPointer mdctx = std::move(mdctx_);
519
520  if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len))
521    return kSignPublicKey;
522
523  EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
524  if (pkctx &&
525      EVP_PKEY_verify_init(pkctx.get()) > 0 &&
526      ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) &&
527      EVP_PKEY_CTX_set_signature_md(pkctx.get(),
528                                    EVP_MD_CTX_md(mdctx.get())) > 0) {
529    const unsigned char* s = sig.data<unsigned char>();
530    const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len);
531    *verify_result = r == 1;
532  }
533
534  return kSignOk;
535}
536
537void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
538  Environment* env = Environment::GetCurrent(args);
539  ClearErrorOnReturn clear_error_on_return;
540
541  Verify* verify;
542  ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
543
544  unsigned int offset = 0;
545  ManagedEVPPKey pkey =
546      ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset);
547  if (!pkey)
548    return;
549
550  ArrayBufferOrViewContents<char> hbuf(args[offset]);
551  if (UNLIKELY(!hbuf.CheckSizeInt32()))
552    return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
553
554  int padding = GetDefaultSignPadding(pkey);
555  if (!args[offset + 1]->IsUndefined()) {
556    CHECK(args[offset + 1]->IsInt32());
557    padding = args[offset + 1].As<Int32>()->Value();
558  }
559
560  Maybe<int> salt_len = Nothing<int>();
561  if (!args[offset + 2]->IsUndefined()) {
562    CHECK(args[offset + 2]->IsInt32());
563    salt_len = Just<int>(args[offset + 2].As<Int32>()->Value());
564  }
565
566  CHECK(args[offset + 3]->IsInt32());
567  DSASigEnc dsa_sig_enc =
568      static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value());
569
570  ByteSource signature = hbuf.ToByteSource();
571  if (dsa_sig_enc == kSigEncP1363) {
572    signature = ConvertSignatureToDER(pkey, hbuf.ToByteSource());
573    if (signature.data() == nullptr)
574      return crypto::CheckThrow(env, Error::kSignMalformedSignature);
575  }
576
577  bool verify_result;
578  Error err = verify->VerifyFinal(pkey, signature, padding,
579                                  salt_len, &verify_result);
580  if (err != kSignOk)
581    return crypto::CheckThrow(env, err);
582  args.GetReturnValue().Set(verify_result);
583}
584
585SignConfiguration::SignConfiguration(SignConfiguration&& other) noexcept
586    : job_mode(other.job_mode),
587      mode(other.mode),
588      key(std::move(other.key)),
589      data(std::move(other.data)),
590      signature(std::move(other.signature)),
591      digest(other.digest),
592      flags(other.flags),
593      padding(other.padding),
594      salt_length(other.salt_length),
595      dsa_encoding(other.dsa_encoding) {}
596
597SignConfiguration& 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
604void 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
612Maybe<bool> SignTraits::AdditionalConfig(
613    CryptoJobMode mode,
614    const FunctionCallbackInfo<Value>& args,
615    unsigned int offset,
616    SignConfiguration* params) {
617  ClearErrorOnReturn clear_error_on_return;
618  Environment* env = Environment::GetCurrent(args);
619
620  params->job_mode = mode;
621
622  CHECK(args[offset]->IsUint32());  // Sign Mode
623
624  params->mode =
625      static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value());
626
627  ManagedEVPPKey key;
628  unsigned int keyParamOffset = offset + 1;
629  if (params->mode == SignConfiguration::kVerify) {
630    key = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &keyParamOffset);
631  } else {
632    key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &keyParamOffset, true);
633  }
634  if (!key)
635    return Nothing<bool>();
636  params->key = key;
637
638  ArrayBufferOrViewContents<char> data(args[offset + 5]);
639  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      ? data.ToCopy()
645      : data.ToByteSource();
646
647  if (args[offset + 6]->IsString()) {
648    Utf8Value digest(env->isolate(), args[offset + 6]);
649    params->digest = EVP_get_digestbyname(*digest);
650    if (params->digest == nullptr) {
651      THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest);
652      return Nothing<bool>();
653    }
654  }
655
656  if (args[offset + 7]->IsInt32()) {  // Salt length
657    params->flags |= SignConfiguration::kHasSaltLength;
658    params->salt_length = args[offset + 7].As<Int32>()->Value();
659  }
660  if (args[offset + 8]->IsUint32()) {  // Padding
661    params->flags |= SignConfiguration::kHasPadding;
662    params->padding = args[offset + 8].As<Uint32>()->Value();
663  }
664
665  if (args[offset + 9]->IsUint32()) {  // DSA Encoding
666    params->dsa_encoding =
667        static_cast<DSASigEnc>(args[offset + 9].As<Uint32>()->Value());
668    if (params->dsa_encoding != kSigEncDER &&
669        params->dsa_encoding != kSigEncP1363) {
670      THROW_ERR_OUT_OF_RANGE(env, "invalid signature encoding");
671      return Nothing<bool>();
672    }
673  }
674
675  if (params->mode == SignConfiguration::kVerify) {
676    ArrayBufferOrViewContents<char> signature(args[offset + 10]);
677    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    ManagedEVPPKey m_pkey = params->key;
684    Mutex::ScopedLock lock(*m_pkey.mutex());
685    if (UseP1363Encoding(m_pkey, params->dsa_encoding)) {
686      params->signature =
687          ConvertSignatureToDER(m_pkey, signature.ToByteSource());
688    } else {
689      params->signature = mode == kCryptoJobAsync
690          ? signature.ToCopy()
691          : signature.ToByteSource();
692    }
693  }
694
695  return Just(true);
696}
697
698bool SignTraits::DeriveBits(
699    Environment* env,
700    const SignConfiguration& params,
701    ByteSource* out) {
702  ClearErrorOnReturn clear_error_on_return;
703  EVPMDPointer context(EVP_MD_CTX_new());
704  EVP_PKEY_CTX* ctx = nullptr;
705
706  switch (params.mode) {
707    case SignConfiguration::kSign:
708      if (!EVP_DigestSignInit(
709              context.get(),
710              &ctx,
711              params.digest,
712              nullptr,
713              params.key.get())) {
714        crypto::CheckThrow(env, SignBase::Error::kSignInit);
715        return false;
716      }
717      break;
718    case SignConfiguration::kVerify:
719      if (!EVP_DigestVerifyInit(
720              context.get(),
721              &ctx,
722              params.digest,
723              nullptr,
724              params.key.get())) {
725        crypto::CheckThrow(env, SignBase::Error::kSignInit);
726        return false;
727      }
728      break;
729  }
730
731  int padding = params.flags & SignConfiguration::kHasPadding
732      ? params.padding
733      : GetDefaultSignPadding(params.key);
734
735  Maybe<int> salt_length = params.flags & SignConfiguration::kHasSaltLength
736      ? Just<int>(params.salt_length) : Nothing<int>();
737
738  if (!ApplyRSAOptions(
739          params.key,
740          ctx,
741          padding,
742          salt_length)) {
743    crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
744    return false;
745  }
746
747  switch (params.mode) {
748    case SignConfiguration::kSign: {
749      if (IsOneShot(params.key)) {
750        size_t len;
751        if (!EVP_DigestSign(
752            context.get(),
753            nullptr,
754            &len,
755            params.data.data<unsigned char>(),
756            params.data.size())) {
757          crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
758          return false;
759        }
760        ByteSource::Builder buf(len);
761        if (!EVP_DigestSign(context.get(),
762                            buf.data<unsigned char>(),
763                            &len,
764                            params.data.data<unsigned char>(),
765                            params.data.size())) {
766          crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
767          return false;
768        }
769        *out = std::move(buf).release(len);
770      } else {
771        size_t len;
772        if (!EVP_DigestSignUpdate(
773                context.get(),
774                params.data.data<unsigned char>(),
775                params.data.size()) ||
776            !EVP_DigestSignFinal(context.get(), nullptr, &len)) {
777          crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
778          return false;
779        }
780        ByteSource::Builder buf(len);
781        if (!EVP_DigestSignFinal(
782                context.get(), buf.data<unsigned char>(), &len)) {
783          crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey);
784          return false;
785        }
786
787        if (UseP1363Encoding(params.key, params.dsa_encoding)) {
788          *out = ConvertSignatureToP1363(
789              env, params.key, std::move(buf).release());
790        } else {
791          *out = std::move(buf).release(len);
792        }
793      }
794      break;
795    }
796    case SignConfiguration::kVerify: {
797      ByteSource::Builder buf(1);
798      buf.data<char>()[0] = 0;
799      if (EVP_DigestVerify(
800              context.get(),
801              params.signature.data<unsigned char>(),
802              params.signature.size(),
803              params.data.data<unsigned char>(),
804              params.data.size()) == 1) {
805        buf.data<char>()[0] = 1;
806      }
807      *out = std::move(buf).release();
808    }
809  }
810
811  return true;
812}
813
814Maybe<bool> SignTraits::EncodeOutput(
815    Environment* env,
816    const SignConfiguration& params,
817    ByteSource* out,
818    Local<Value>* result) {
819  switch (params.mode) {
820    case SignConfiguration::kSign:
821      *result = out->ToArrayBuffer(env);
822      break;
823    case SignConfiguration::kVerify:
824      *result = Boolean::New(env->isolate(), out->data<char>()[0] == 1);
825      break;
826    default:
827      UNREACHABLE();
828  }
829  return Just(!result->IsEmpty());
830}
831
832}  // namespace crypto
833}  // namespace node
834