Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: add support for x25119 and x448 key pair generation #26774

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -1129,14 +1129,17 @@ passing keys as strings or `Buffer`s due to improved security features.
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/26774
description: Added support for `'x25519'` and `'x448'`
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/26319
description: Added support for `'ed25519'` and `'ed448'`
-->
* {string}

For asymmetric keys, this property represents the type of the embedded key
(`'rsa'`, `'dsa'`, `'ec'`, `'ed25519'`, or `'ed448'`).
(`'rsa'`, `'dsa'`, `'ec'`, `'ed25519'`, `'ed448'`, `'x25519'` or `'x448'`).
This property is `undefined` for symmetric keys.

### keyObject.export([options])
Expand Down Expand Up @@ -1903,6 +1906,9 @@ algorithm names.
<!-- YAML
added: v10.12.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/26774
description: Add ability to generate X25519 and X448 key pairs.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/26554
description: Add ability to generate Ed25519 and Ed448 key pairs.
Expand All @@ -1911,7 +1917,8 @@ changes:
description: The `generateKeyPair` and `generateKeyPairSync` functions now
produce key objects if no encoding was specified.
-->
* `type`: {string} Must be `'rsa'`, `'dsa'`, `'ec'`, `'ed25519'`, or `'ed448'`.
* `type`: {string} Must be `'rsa'`, `'dsa'`, `'ec'`, `'ed25519'`, `'ed448'`,
`'x25519'`, or `'x448'.
panva marked this conversation as resolved.
Show resolved Hide resolved
* `options`: {Object}
- `modulusLength`: {number} Key size in bits (RSA, DSA).
- `publicExponent`: {number} Public exponent (RSA). **Default:** `0x10001`.
Expand Down
22 changes: 20 additions & 2 deletions lib/internal/crypto/keygen.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const {
generateKeyPairEdDSA,
EVP_PKEY_ED25519,
EVP_PKEY_ED448,
EVP_PKEY_X25519,
EVP_PKEY_X448,
OPENSSL_EC_NAMED_CURVE,
OPENSSL_EC_EXPLICIT_CURVE
} = internalBinding('crypto');
Expand Down Expand Up @@ -197,8 +199,24 @@ function check(type, options, callback) {
break;
case 'ed25519':
case 'ed448':
case 'x25519':
case 'x448':
{
const id = type === 'ed25519' ? EVP_PKEY_ED25519 : EVP_PKEY_ED448;
let id;
switch (type) {
case 'ed25519':
id = EVP_PKEY_ED25519;
break;
case 'ed448':
id = EVP_PKEY_ED448;
break;
case 'x25519':
id = EVP_PKEY_X25519;
break;
case 'x448':
id = EVP_PKEY_X448;
break;
}
impl = (wrap) => generateKeyPairEdDSA(id,
publicFormat, publicType,
privateFormat, privateType,
Expand All @@ -208,7 +226,7 @@ function check(type, options, callback) {
default:
throw new ERR_INVALID_ARG_VALUE('type', type,
"must be one of 'rsa', 'dsa', 'ec', " +
"'ed25519', 'ed448'");
"'ed25519', 'ed448', 'x25519', 'x448'");
}

if (options) {
Expand Down
2 changes: 2 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(crypto_ec_string, "ec") \
V(crypto_ed25519_string, "ed25519") \
V(crypto_ed448_string, "ed448") \
V(crypto_x25519_string, "x25519") \
V(crypto_x448_string, "x448") \
V(crypto_rsa_string, "rsa") \
V(cwd_string, "cwd") \
V(data_string, "data") \
Expand Down
6 changes: 6 additions & 0 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3451,6 +3451,10 @@ Local<String> KeyObject::GetAsymmetricKeyType() const {
return env()->crypto_ed25519_string();
case EVP_PKEY_ED448:
return env()->crypto_ed448_string();
case EVP_PKEY_X25519:
return env()->crypto_x25519_string();
case EVP_PKEY_X448:
return env()->crypto_x448_string();
default:
CHECK(false);
}
Expand Down Expand Up @@ -6336,6 +6340,8 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "generateKeyPairEdDSA", GenerateKeyPairEdDSA);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED25519);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED448);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);
NODE_DEFINE_CONSTANT(target, OPENSSL_EC_NAMED_CURVE);
NODE_DEFINE_CONSTANT(target, OPENSSL_EC_EXPLICIT_CURVE);
NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS1);
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/test_x25519_privkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEILD/13Y5R/tmcCjZVSooIcpfGvZxf+qt6dMu5FYaOC1a
-----END PRIVATE KEY-----
3 changes: 3 additions & 0 deletions test/fixtures/test_x25519_pubkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAYHCXnz085FKclfnx+gdiGXAyy7BhJjx0pxyE4wbXF0A=
-----END PUBLIC KEY-----
4 changes: 4 additions & 0 deletions test/fixtures/test_x448_privkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MEYCAQAwBQYDK2VvBDoEOPilLIAZTQqUbFb0LhTGaqn47zN2p2yGVk+2hhQQk9C8
8SvFqEFw73YITSIJ2NUBZnZKNz2nGkrm
-----END PRIVATE KEY-----
4 changes: 4 additions & 0 deletions test/fixtures/test_x448_pubkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MEIwBQYDK2VvAzkAbceBBM+LkveTK09QojZdnHokCh7lOWxyVZrlbH3Ny3WorprD
Iir5A6heZzlRnz1elOHp7ZpPfWk=
-----END PUBLIC KEY-----
8 changes: 7 additions & 1 deletion test/parallel/test-crypto-key-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,13 @@ const privatePem = fixtures.readSync('test_rsa_privkey.pem', 'ascii');
keyType: 'ed25519' },
{ private: fixtures.readSync('test_ed448_privkey.pem', 'ascii'),
public: fixtures.readSync('test_ed448_pubkey.pem', 'ascii'),
keyType: 'ed448' }
keyType: 'ed448' },
{ private: fixtures.readSync('test_x25519_privkey.pem', 'ascii'),
public: fixtures.readSync('test_x25519_pubkey.pem', 'ascii'),
keyType: 'x25519' },
{ private: fixtures.readSync('test_x448_privkey.pem', 'ascii'),
public: fixtures.readSync('test_x448_pubkey.pem', 'ascii'),
keyType: 'x448' }
].forEach((info) => {
const keyType = info.keyType;

Expand Down
5 changes: 3 additions & 2 deletions test/parallel/test-crypto-keygen.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
type: TypeError,
code: 'ERR_INVALID_ARG_VALUE',
message: "The argument 'type' must be one of " +
"'rsa', 'dsa', 'ec', 'ed25519', 'ed448'. Received 'rsa2'"
"'rsa', 'dsa', 'ec', 'ed25519', 'ed448'," +
" 'x25519', 'x448'. Received 'rsa2'"
});
}

Expand Down Expand Up @@ -786,7 +787,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
// Test EdDSA key generation.
{
if (!/^1\.1\.0/.test(process.versions.openssl)) {
['ed25519', 'ed448'].forEach((keyType) => {
['ed25519', 'ed448', 'x25519', 'x448'].forEach((keyType) => {
generateKeyPair(keyType, common.mustCall((err, publicKey, privateKey) => {
assert.ifError(err);

Expand Down