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 12namespace node { 13 14using v8::FunctionCallbackInfo; 15using v8::Int32; 16using v8::Just; 17using v8::Local; 18using v8::Maybe; 19using v8::Object; 20using v8::Uint32; 21using v8::Value; 22 23namespace 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 33Maybe<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 46EVPKeyCtxPointer 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 55void SecretKeyGenConfig::MemoryInfo(MemoryTracker* tracker) const { 56 if (out != nullptr) 57 tracker->TrackFieldWithSize("out", length); 58} 59 60Maybe<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 74KeyGenJobStatus 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 89Maybe<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 99namespace Keygen { 100void Initialize(Environment* env, Local<Object> target) { 101 NidKeyPairGenJob::Initialize(env, target); 102 SecretKeyGenJob::Initialize(env, target); 103} 104 105void RegisterExternalReferences(ExternalReferenceRegistry* registry) { 106 NidKeyPairGenJob::RegisterExternalReferences(registry); 107 SecretKeyGenJob::RegisterExternalReferences(registry); 108} 109 110} // namespace Keygen 111} // namespace crypto 112} // namespace node 113