@@ -6625,6 +6625,71 @@ class NidKeyPairGenerationConfig : public KeyPairGenerationConfig {
66256625 const int id_;
66266626};
66276627
6628+ // TODO(tniessen): Use std::variant instead.
6629+ // Diffie-Hellman can either generate keys using a fixed prime, or by first
6630+ // generating a random prime of a given size (in bits). Only one of both options
6631+ // may be specified.
6632+ struct PrimeInfo {
6633+ BignumPointer fixed_value_;
6634+ unsigned int prime_size_;
6635+ };
6636+
6637+ class DHKeyPairGenerationConfig : public KeyPairGenerationConfig {
6638+ public:
6639+ explicit DHKeyPairGenerationConfig (PrimeInfo&& prime_info,
6640+ unsigned int generator)
6641+ : prime_info_(std::move(prime_info)),
6642+ generator_(generator) {}
6643+
6644+ EVPKeyCtxPointer Setup () override {
6645+ EVPKeyPointer params;
6646+ if (prime_info_.fixed_value_ ) {
6647+ DHPointer dh (DH_new ());
6648+ if (!dh)
6649+ return nullptr ;
6650+
6651+ BIGNUM* prime = prime_info_.fixed_value_ .get ();
6652+ BignumPointer bn_g (BN_new ());
6653+ if (!BN_set_word (bn_g.get (), generator_) ||
6654+ !DH_set0_pqg (dh.get (), prime, nullptr , bn_g.get ()))
6655+ return nullptr ;
6656+
6657+ prime_info_.fixed_value_ .release ();
6658+ bn_g.release ();
6659+
6660+ params = EVPKeyPointer (EVP_PKEY_new ());
6661+ CHECK (params);
6662+ EVP_PKEY_assign_DH (params.get (), dh.release ());
6663+ } else {
6664+ EVPKeyCtxPointer param_ctx (EVP_PKEY_CTX_new_id (EVP_PKEY_DH, nullptr ));
6665+ if (!param_ctx)
6666+ return nullptr ;
6667+
6668+ if (EVP_PKEY_paramgen_init (param_ctx.get ()) <= 0 )
6669+ return nullptr ;
6670+
6671+ if (EVP_PKEY_CTX_set_dh_paramgen_prime_len (param_ctx.get (),
6672+ prime_info_.prime_size_ ) <= 0 )
6673+ return nullptr ;
6674+
6675+ if (EVP_PKEY_CTX_set_dh_paramgen_generator (param_ctx.get (),
6676+ generator_) <= 0 )
6677+ return nullptr ;
6678+
6679+ EVP_PKEY* raw_params = nullptr ;
6680+ if (EVP_PKEY_paramgen (param_ctx.get (), &raw_params) <= 0 )
6681+ return nullptr ;
6682+ params = EVPKeyPointer (raw_params);
6683+ }
6684+
6685+ return EVPKeyCtxPointer (EVP_PKEY_CTX_new (params.get (), nullptr ));
6686+ }
6687+
6688+ private:
6689+ PrimeInfo prime_info_;
6690+ unsigned int generator_;
6691+ };
6692+
66286693class GenerateKeyPairJob : public CryptoJob {
66296694 public:
66306695 GenerateKeyPairJob (Environment* env,
@@ -6844,6 +6909,39 @@ void GenerateKeyPairNid(const FunctionCallbackInfo<Value>& args) {
68446909 GenerateKeyPair (args, 1 , std::move (config));
68456910}
68466911
6912+ void GenerateKeyPairDH (const FunctionCallbackInfo<Value>& args) {
6913+ Environment* env = Environment::GetCurrent (args);
6914+
6915+ PrimeInfo prime_info = {};
6916+ unsigned int generator;
6917+ if (args[0 ]->IsString ()) {
6918+ String::Utf8Value group_name (args.GetIsolate (), args[0 ].As <String>());
6919+ const modp_group* group = FindDiffieHellmanGroup (*group_name);
6920+ if (group == nullptr )
6921+ return THROW_ERR_CRYPTO_UNKNOWN_DH_GROUP (env);
6922+
6923+ prime_info.fixed_value_ = BignumPointer (
6924+ BN_bin2bn (reinterpret_cast <const unsigned char *>(group->prime ),
6925+ group->prime_size , nullptr ));
6926+ generator = group->gen ;
6927+ } else {
6928+ if (args[0 ]->IsInt32 ()) {
6929+ prime_info.prime_size_ = args[0 ].As <Int32>()->Value ();
6930+ } else {
6931+ ArrayBufferViewContents<unsigned char > input (args[0 ]);
6932+ prime_info.fixed_value_ = BignumPointer (
6933+ BN_bin2bn (input.data (), input.length (), nullptr ));
6934+ }
6935+
6936+ CHECK (args[1 ]->IsInt32 ());
6937+ generator = args[1 ].As <Int32>()->Value ();
6938+ }
6939+
6940+ std::unique_ptr<KeyPairGenerationConfig> config (
6941+ new DHKeyPairGenerationConfig (std::move (prime_info), generator));
6942+ GenerateKeyPair (args, 2 , std::move (config));
6943+ }
6944+
68476945
68486946void GetSSLCiphers (const FunctionCallbackInfo<Value>& args) {
68496947 Environment* env = Environment::GetCurrent (args);
@@ -7250,6 +7348,7 @@ void Initialize(Local<Object> target,
72507348 env->SetMethod (target, " generateKeyPairDSA" , GenerateKeyPairDSA);
72517349 env->SetMethod (target, " generateKeyPairEC" , GenerateKeyPairEC);
72527350 env->SetMethod (target, " generateKeyPairNid" , GenerateKeyPairNid);
7351+ env->SetMethod (target, " generateKeyPairDH" , GenerateKeyPairDH);
72537352 NODE_DEFINE_CONSTANT (target, EVP_PKEY_ED25519);
72547353 NODE_DEFINE_CONSTANT (target, EVP_PKEY_ED448);
72557354 NODE_DEFINE_CONSTANT (target, EVP_PKEY_X25519);
0 commit comments