Skip to content
This repository was archived by the owner on Oct 23, 2020. It is now read-only.

Extract RSA key properties #43

Merged
merged 1 commit into from
Mar 14, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
38 changes: 35 additions & 3 deletions lib/algorithms/rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function uint8ArrayToUint32(bigInteger) {
}

function uint32ToUint8Array(integer) {
const result = Buffer.alloc(8);
const result = new Uint8Array(8);
let i = 7;
while (integer !== 0) {
result[i--] = integer & 0xff;
Expand All @@ -46,6 +46,33 @@ function uint32ToUint8Array(integer) {
return result.slice(i + 1);
}

function getAlgorithmProperties(key) {
const der = key.export({
format: 'der',
type: 'pkcs1'
});

const dec = new Asn1SequenceDecoder(der);
if (key.type === 'private') {
// Skip the version field.
dec.unsignedInteger();
}

const n = dec.unsignedInteger();
const e = dec.unsignedInteger();

// n cannot have a leading zero byte, but leading zero bits.
let modulusLength = 8;
while ((n[0] & (1 << (modulusLength - 1))) === 0)
modulusLength--;
modulusLength += (n.length - 1) * 8;

return {
modulusLength,
publicExponent: new Uint8Array(e)
};
}

function jwkToDer(jwk, jwkHashMapping) {
if (jwk.kty !== 'RSA')
throw new DataError();
Expand Down Expand Up @@ -205,8 +232,13 @@ const rsaBase = {
type: keyFormat
});

return new CryptoKey(key.type, { name: this.name, hash },
extractable, keyUsages, key);
const algorithm = {
name: this.name,
hash,
...getAlgorithmProperties(key)
};

return new CryptoKey(key.type, algorithm, extractable, keyUsages, key);
},

exportKey(format, key) {
Expand Down
10 changes: 9 additions & 1 deletion test/unit/algorithms/rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function testGenImportExport(name, pubKeyUsage, privKeyUsage) {
assert.strictEqual(key.algorithm.name, name);
assert.strictEqual(key.algorithm.modulusLength, 2048);
assert.deepStrictEqual(key.algorithm.publicExponent,
Buffer.from([0x01, 0x00, 0x01]));
new Uint8Array([0x01, 0x00, 0x01]));
assert.strictEqual(key.algorithm.hash.name, 'SHA-384');
}

Expand All @@ -41,6 +41,14 @@ function testGenImportExport(name, pubKeyUsage, privKeyUsage) {
hash: 'SHA-384'
}, true, [privKeyUsage]);

for (const key of [impPublicKey, impPrivateKey]) {
assert.strictEqual(key.algorithm.name, name);
assert.strictEqual(key.algorithm.modulusLength, 2048);
assert.deepStrictEqual(key.algorithm.publicExponent,
new Uint8Array([0x01, 0x00, 0x01]));
assert.strictEqual(key.algorithm.hash.name, 'SHA-384');
}

assert.deepStrictEqual(await subtle.exportKey('spki', impPublicKey),
expPublicKey);
assert.deepStrictEqual(await subtle.exportKey('pkcs8', impPrivateKey),
Expand Down