Skip to content
Permalink
Browse files

crypto: add KeyObject.asymmetricKeySize

Expose the size of asymetric keys of crypto key object from the
crypto module added in v11.6.0.

PR-URL: #26387
Refs: #24234
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information...
paroga authored and BridgeAR committed Mar 2, 2019
1 parent 53d4e04 commit 4895927a0a4372e0699f84657e0a299393a3d281
@@ -1121,6 +1121,15 @@ exposes different functions.
Most applications should consider using the new `KeyObject` API instead of
passing keys as strings or `Buffer`s due to improved security features.

### keyObject.asymmetricKeySize
<!-- YAML
added: REPLACEME
-->
* {number}

For asymmetric keys, this property represents the size of the embedded key in
bytes. This property is `undefined` for symmetric keys.

### keyObject.asymmetricKeyType
<!-- YAML
added: v11.6.0
@@ -73,9 +73,15 @@ class SecretKeyObject extends KeyObject {
}
}

const kAsymmetricKeySize = Symbol('kAsymmetricKeySize');
const kAsymmetricKeyType = Symbol('kAsymmetricKeyType');

class AsymmetricKeyObject extends KeyObject {
get asymmetricKeySize() {
return this[kAsymmetricKeySize] ||
(this[kAsymmetricKeySize] = this[kHandle].getAsymmetricKeySize());
}

get asymmetricKeyType() {
return this[kAsymmetricKeyType] ||
(this[kAsymmetricKeyType] = this[kHandle].getAsymmetricKeyType());
@@ -3330,6 +3330,8 @@ Local<Function> KeyObject::Initialize(Environment* env, Local<Object> target) {
t->InstanceTemplate()->SetInternalFieldCount(1);

env->SetProtoMethod(t, "init", Init);
env->SetProtoMethodNoSideEffect(t, "getAsymmetricKeySize",
GetAsymmetricKeySize);
env->SetProtoMethodNoSideEffect(t, "getSymmetricKeySize",
GetSymmetricKeySize);
env->SetProtoMethodNoSideEffect(t, "getAsymmetricKeyType",
@@ -3375,6 +3377,11 @@ const char* KeyObject::GetSymmetricKey() const {
return this->symmetric_key_.get();
}

size_t KeyObject::GetAsymmetricKeySize() const {
CHECK_NE(key_type_, kKeyTypeSecret);
return EVP_PKEY_size(this->asymmetric_key_.get());
}

size_t KeyObject::GetSymmetricKeySize() const {
CHECK_EQ(key_type_, kKeyTypeSecret);
return this->symmetric_key_len_;
@@ -3474,6 +3481,12 @@ void KeyObject::GetAsymmetricKeyType(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(key->GetAsymmetricKeyType());
}

void KeyObject::GetAsymmetricKeySize(const FunctionCallbackInfo<Value>& args) {
KeyObject* key;
ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
args.GetReturnValue().Set(static_cast<uint32_t>(key->GetAsymmetricKeySize()));
}

void KeyObject::GetSymmetricKeySize(const FunctionCallbackInfo<Value>& args) {
KeyObject* key;
ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());
@@ -456,6 +456,7 @@ class KeyObject : public BaseObject {
// only be used to implement cryptograohic operations requiring the key.
ManagedEVPPKey GetAsymmetricKey() const;
const char* GetSymmetricKey() const;
size_t GetAsymmetricKeySize() const;
size_t GetSymmetricKeySize() const;

protected:
@@ -470,6 +471,9 @@ class KeyObject : public BaseObject {
const v8::FunctionCallbackInfo<v8::Value>& args);
v8::Local<v8::String> GetAsymmetricKeyType() const;

static void GetAsymmetricKeySize(
const v8::FunctionCallbackInfo<v8::Value>& args);

static void GetSymmetricKeySize(
const v8::FunctionCallbackInfo<v8::Value>& args);

@@ -38,6 +38,7 @@ const privatePem = fixtures.readSync('test_rsa_privkey.pem', 'ascii');
const key = createSecretKey(keybuf);
assert.strictEqual(key.type, 'secret');
assert.strictEqual(key.symmetricKeySize, 32);
assert.strictEqual(key.asymmetricKeySize, undefined);
assert.strictEqual(key.asymmetricKeyType, undefined);

const exportedKey = key.export();
@@ -91,11 +92,13 @@ const privatePem = fixtures.readSync('test_rsa_privkey.pem', 'ascii');
const publicKey = createPublicKey(publicPem);
assert.strictEqual(publicKey.type, 'public');
assert.strictEqual(publicKey.asymmetricKeyType, 'rsa');
assert.strictEqual(publicKey.asymmetricKeySize, 128);
assert.strictEqual(publicKey.symmetricKeySize, undefined);

const privateKey = createPrivateKey(privatePem);
assert.strictEqual(privateKey.type, 'private');
assert.strictEqual(privateKey.asymmetricKeyType, 'rsa');
assert.strictEqual(privateKey.asymmetricKeySize, 128);
assert.strictEqual(privateKey.symmetricKeySize, undefined);

// It should be possible to derive a public key from a private key.
@@ -108,10 +108,12 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
assert.strictEqual(typeof publicKey, 'object');
assert.strictEqual(publicKey.type, 'public');
assert.strictEqual(publicKey.asymmetricKeyType, 'rsa');
assert.strictEqual(publicKey.asymmetricKeySize, 64);

assert.strictEqual(typeof privateKey, 'object');
assert.strictEqual(privateKey.type, 'private');
assert.strictEqual(privateKey.asymmetricKeyType, 'rsa');
assert.strictEqual(publicKey.asymmetricKeySize, 64);
}

{
@@ -453,6 +455,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
assert.strictEqual(typeof publicKey, 'object');
assert.strictEqual(publicKey.type, 'public');
assert.strictEqual(publicKey.asymmetricKeyType, 'rsa');
assert.strictEqual(publicKey.asymmetricKeySize, 128);

// The private key should still be a string.
assert.strictEqual(typeof privateKey, 'string');
@@ -477,6 +480,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
assert.strictEqual(typeof privateKey, 'object');
assert.strictEqual(privateKey.type, 'private');
assert.strictEqual(privateKey.asymmetricKeyType, 'rsa');
assert.strictEqual(privateKey.asymmetricKeySize, 128);

testEncryptDecrypt(publicKey, privateKey);
testSignVerify(publicKey, privateKey);

0 comments on commit 4895927

Please sign in to comment.
You can’t perform that action at this time.