@@ -6086,6 +6086,71 @@ class NidKeyPairGenerationConfig : public KeyPairGenerationConfig {
6086
6086
const int id_;
6087
6087
};
6088
6088
6089
+ // TODO(tniessen): Use std::variant instead.
6090
+ // Diffie-Hellman can either generate keys using a fixed prime, or by first
6091
+ // generating a random prime of a given size (in bits). Only one of both options
6092
+ // may be specified.
6093
+ struct PrimeInfo {
6094
+ BignumPointer fixed_value_;
6095
+ unsigned int prime_size_;
6096
+ };
6097
+
6098
+ class DHKeyPairGenerationConfig : public KeyPairGenerationConfig {
6099
+ public:
6100
+ explicit DHKeyPairGenerationConfig (PrimeInfo&& prime_info,
6101
+ unsigned int generator)
6102
+ : prime_info_(std::move(prime_info)),
6103
+ generator_(generator) {}
6104
+
6105
+ EVPKeyCtxPointer Setup () override {
6106
+ EVPKeyPointer params;
6107
+ if (prime_info_.fixed_value_ ) {
6108
+ DHPointer dh (DH_new ());
6109
+ if (!dh)
6110
+ return nullptr ;
6111
+
6112
+ BIGNUM* prime = prime_info_.fixed_value_ .get ();
6113
+ BignumPointer bn_g (BN_new ());
6114
+ if (!BN_set_word (bn_g.get (), generator_) ||
6115
+ !DH_set0_pqg (dh.get (), prime, nullptr , bn_g.get ()))
6116
+ return nullptr ;
6117
+
6118
+ prime_info_.fixed_value_ .release ();
6119
+ bn_g.release ();
6120
+
6121
+ params = EVPKeyPointer (EVP_PKEY_new ());
6122
+ CHECK (params);
6123
+ EVP_PKEY_assign_DH (params.get (), dh.release ());
6124
+ } else {
6125
+ EVPKeyCtxPointer param_ctx (EVP_PKEY_CTX_new_id (EVP_PKEY_DH, nullptr ));
6126
+ if (!param_ctx)
6127
+ return nullptr ;
6128
+
6129
+ if (EVP_PKEY_paramgen_init (param_ctx.get ()) <= 0 )
6130
+ return nullptr ;
6131
+
6132
+ if (EVP_PKEY_CTX_set_dh_paramgen_prime_len (param_ctx.get (),
6133
+ prime_info_.prime_size_ ) <= 0 )
6134
+ return nullptr ;
6135
+
6136
+ if (EVP_PKEY_CTX_set_dh_paramgen_generator (param_ctx.get (),
6137
+ generator_) <= 0 )
6138
+ return nullptr ;
6139
+
6140
+ EVP_PKEY* raw_params = nullptr ;
6141
+ if (EVP_PKEY_paramgen (param_ctx.get (), &raw_params) <= 0 )
6142
+ return nullptr ;
6143
+ params = EVPKeyPointer (raw_params);
6144
+ }
6145
+
6146
+ return EVPKeyCtxPointer (EVP_PKEY_CTX_new (params.get (), nullptr ));
6147
+ }
6148
+
6149
+ private:
6150
+ PrimeInfo prime_info_;
6151
+ unsigned int generator_;
6152
+ };
6153
+
6089
6154
class GenerateKeyPairJob : public CryptoJob {
6090
6155
public:
6091
6156
GenerateKeyPairJob (Environment* env,
@@ -6299,6 +6364,39 @@ void GenerateKeyPairNid(const FunctionCallbackInfo<Value>& args) {
6299
6364
GenerateKeyPair (args, 1 , std::move (config));
6300
6365
}
6301
6366
6367
+ void GenerateKeyPairDH (const FunctionCallbackInfo<Value>& args) {
6368
+ Environment* env = Environment::GetCurrent (args);
6369
+
6370
+ PrimeInfo prime_info = {};
6371
+ unsigned int generator;
6372
+ if (args[0 ]->IsString ()) {
6373
+ String::Utf8Value group_name (args.GetIsolate (), args[0 ].As <String>());
6374
+ const modp_group* group = FindDiffieHellmanGroup (*group_name);
6375
+ if (group == nullptr )
6376
+ return THROW_ERR_CRYPTO_UNKNOWN_DH_GROUP (env);
6377
+
6378
+ prime_info.fixed_value_ = BignumPointer (
6379
+ BN_bin2bn (reinterpret_cast <const unsigned char *>(group->prime ),
6380
+ group->prime_size , nullptr ));
6381
+ generator = group->gen ;
6382
+ } else {
6383
+ if (args[0 ]->IsInt32 ()) {
6384
+ prime_info.prime_size_ = args[0 ].As <Int32>()->Value ();
6385
+ } else {
6386
+ ArrayBufferViewContents<unsigned char > input (args[0 ]);
6387
+ prime_info.fixed_value_ = BignumPointer (
6388
+ BN_bin2bn (input.data (), input.length (), nullptr ));
6389
+ }
6390
+
6391
+ CHECK (args[1 ]->IsInt32 ());
6392
+ generator = args[1 ].As <Int32>()->Value ();
6393
+ }
6394
+
6395
+ std::unique_ptr<KeyPairGenerationConfig> config (
6396
+ new DHKeyPairGenerationConfig (std::move (prime_info), generator));
6397
+ GenerateKeyPair (args, 2 , std::move (config));
6398
+ }
6399
+
6302
6400
6303
6401
void GetSSLCiphers (const FunctionCallbackInfo<Value>& args) {
6304
6402
Environment* env = Environment::GetCurrent (args);
@@ -6732,6 +6830,7 @@ void Initialize(Local<Object> target,
6732
6830
env->SetMethod (target, " generateKeyPairDSA" , GenerateKeyPairDSA);
6733
6831
env->SetMethod (target, " generateKeyPairEC" , GenerateKeyPairEC);
6734
6832
env->SetMethod (target, " generateKeyPairNid" , GenerateKeyPairNid);
6833
+ env->SetMethod (target, " generateKeyPairDH" , GenerateKeyPairDH);
6735
6834
NODE_DEFINE_CONSTANT (target, EVP_PKEY_ED25519);
6736
6835
NODE_DEFINE_CONSTANT (target, EVP_PKEY_ED448);
6737
6836
NODE_DEFINE_CONSTANT (target, EVP_PKEY_X25519);
0 commit comments