• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "crypto/crypto_keygen.h"
2 #include "async_wrap-inl.h"
3 #include "base_object-inl.h"
4 #include "debug_utils-inl.h"
5 #include "env-inl.h"
6 #include "memory_tracker-inl.h"
7 #include "threadpoolwork-inl.h"
8 #include "v8.h"
9 
10 #include <cmath>
11 
12 namespace node {
13 
14 using v8::FunctionCallbackInfo;
15 using v8::Int32;
16 using v8::Just;
17 using v8::Local;
18 using v8::Maybe;
19 using v8::Object;
20 using v8::Uint32;
21 using v8::Value;
22 
23 namespace crypto {
24 // NidKeyPairGenJob input arguments:
25 //   1. CryptoJobMode
26 //   2. NID
27 //   3. Public Format
28 //   4. Public Type
29 //   5. Private Format
30 //   6. Private Type
31 //   7. Cipher
32 //   8. Passphrase
AdditionalConfig(CryptoJobMode mode,const FunctionCallbackInfo<Value> & args,unsigned int * offset,NidKeyPairGenConfig * params)33 Maybe<bool> NidKeyPairGenTraits::AdditionalConfig(
34     CryptoJobMode mode,
35     const FunctionCallbackInfo<Value>& args,
36     unsigned int* offset,
37     NidKeyPairGenConfig* params) {
38   CHECK(args[*offset]->IsInt32());
39   params->params.id = args[*offset].As<Int32>()->Value();
40 
41   *offset += 1;
42 
43   return Just(true);
44 }
45 
Setup(NidKeyPairGenConfig * params)46 EVPKeyCtxPointer NidKeyPairGenTraits::Setup(NidKeyPairGenConfig* params) {
47   EVPKeyCtxPointer ctx =
48       EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(params->params.id, nullptr));
49   if (!ctx || EVP_PKEY_keygen_init(ctx.get()) <= 0)
50     return EVPKeyCtxPointer();
51 
52   return ctx;
53 }
54 
MemoryInfo(MemoryTracker * tracker) const55 void SecretKeyGenConfig::MemoryInfo(MemoryTracker* tracker) const {
56   if (out != nullptr)
57     tracker->TrackFieldWithSize("out", length);
58 }
59 
AdditionalConfig(CryptoJobMode mode,const FunctionCallbackInfo<Value> & args,unsigned int * offset,SecretKeyGenConfig * params)60 Maybe<bool> SecretKeyGenTraits::AdditionalConfig(
61     CryptoJobMode mode,
62     const FunctionCallbackInfo<Value>& args,
63     unsigned int* offset,
64     SecretKeyGenConfig* params) {
65   CHECK(args[*offset]->IsUint32());
66   uint32_t bits = args[*offset].As<Uint32>()->Value();
67   static_assert(std::numeric_limits<decltype(bits)>::max() / CHAR_BIT <=
68                 INT_MAX);
69   params->length = bits / CHAR_BIT;
70   *offset += 1;
71   return Just(true);
72 }
73 
DoKeyGen(Environment * env,SecretKeyGenConfig * params)74 KeyGenJobStatus SecretKeyGenTraits::DoKeyGen(
75     Environment* env,
76     SecretKeyGenConfig* params) {
77   CHECK_LE(params->length, INT_MAX);
78   params->out = MallocOpenSSL<char>(params->length);
79   if (CSPRNG(reinterpret_cast<unsigned char*>(params->out),
80              params->length).is_err()) {
81     OPENSSL_clear_free(params->out, params->length);
82     params->out = nullptr;
83     params->length = 0;
84     return KeyGenJobStatus::FAILED;
85   }
86   return KeyGenJobStatus::OK;
87 }
88 
EncodeKey(Environment * env,SecretKeyGenConfig * params,Local<Value> * result)89 Maybe<bool> SecretKeyGenTraits::EncodeKey(
90     Environment* env,
91     SecretKeyGenConfig* params,
92     Local<Value>* result) {
93   ByteSource out = ByteSource::Allocated(params->out, params->length);
94   std::shared_ptr<KeyObjectData> data =
95       KeyObjectData::CreateSecret(std::move(out));
96   return Just(KeyObjectHandle::Create(env, data).ToLocal(result));
97 }
98 
99 namespace Keygen {
Initialize(Environment * env,Local<Object> target)100 void Initialize(Environment* env, Local<Object> target) {
101   NidKeyPairGenJob::Initialize(env, target);
102   SecretKeyGenJob::Initialize(env, target);
103 }
104 
RegisterExternalReferences(ExternalReferenceRegistry * registry)105 void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
106   NidKeyPairGenJob::RegisterExternalReferences(registry);
107   SecretKeyGenJob::RegisterExternalReferences(registry);
108 }
109 
110 }  // namespace Keygen
111 }  // namespace crypto
112 }  // namespace node
113