Commit c44add2d authored by pneubeck's avatar pneubeck Committed by Commit bot

chrome.platformKeys: Require a algorithm name to getKeyPair().

This makes the algorithm name a mandatory argument of getKeyPair().
In a later CL, this name will be compared with the key restrictions that the certificate puts onto the key usage.

BUG=466584

Review URL: https://codereview.chromium.org/1001853003

Cr-Commit-Position: refs/heads/master@{#321956}
parent d62576e5
...@@ -7,44 +7,56 @@ var internalAPI = require('platformKeys.internalAPI'); ...@@ -7,44 +7,56 @@ var internalAPI = require('platformKeys.internalAPI');
var normalizeAlgorithm = var normalizeAlgorithm =
requireNative('platform_keys_natives').NormalizeAlgorithm; requireNative('platform_keys_natives').NormalizeAlgorithm;
function combineAlgorithms(algorithm, importParams) { // Returns the normalized parameters of |importParams|.
if (importParams.name === undefined) { // Any unknown parameters will be ignored.
importParams.name = algorithm.name; function normalizeImportParams(importParams) {
if (!importParams.name ||
Object.prototype.toString.call(importParams.name) != '[object String]') {
throw new Error('Algorithm: name: Missing or not a String');
} }
// Verify whether importParams.hash equals var filteredParams = { name: importParams.name };
// { name: 'none' }
if (importParams.hash && var hashIsNone = false;
importParams.hash.name.toLowerCase() === 'none') { if (importParams.hash) {
if (Object.keys(importParams.hash).length != 1 || if (importParams.hash.name.toLowerCase() === 'none') {
Object.keys(importParams).length != 2) { hashIsNone = true;
// 'name' must be the only hash property in this case. // Temporarily replace |hash| by a valid WebCrypto Hash for normalization.
throw new Error('A required parameter was missing or out-of-range'); // This will be reverted to 'none' after normalization.
} filteredParams.hash = { name: 'SHA-1' };
importParams.hash.name = 'none'; } else {
} else { filteredParams.hash = { name: importParams.hash.name }
// Otherwise apply WebCrypto's algorithm normalization.
importParams = normalizeAlgorithm(importParams, 'ImportKey');
if (!importParams) {
// throw CreateSyntaxError();
throw new Error('A required parameter was missing or out-of-range');
} }
} }
// Apply WebCrypto's algorithm normalization.
var resultParams = normalizeAlgorithm(filteredParams, 'ImportKey');
if (!resultParams ) {
throw new Error('A required parameter was missing or out-of-range');
}
if (hashIsNone) {
resultParams.hash = { name: 'none' };
}
return resultParams;
}
function combineAlgorithms(algorithm, importParams) {
// internalAPI.getPublicKey returns publicExponent as ArrayBuffer, but it // internalAPI.getPublicKey returns publicExponent as ArrayBuffer, but it
// should be a Uint8Array. // should be a Uint8Array.
if (algorithm.publicExponent) { if (algorithm.publicExponent) {
algorithm.publicExponent = new Uint8Array(algorithm.publicExponent); algorithm.publicExponent = new Uint8Array(algorithm.publicExponent);
} }
for (var key in importParams) { algorithm.hash = importParams.hash;
algorithm[key] = importParams[key];
}
return algorithm; return algorithm;
} }
function getPublicKey(cert, importParams, callback) { function getPublicKey(cert, importParams, callback) {
importParams = normalizeImportParams(importParams);
// TODO(pneubeck): pass importParams.name to the internal getPublicKey and
// verify on the C++ side that the requested algorithm is compatible with the
// given SubjectPublicKeyInfo of the certificate.
// https://crbug.com/466584
internalAPI.getPublicKey(cert, function(publicKey, algorithm) { internalAPI.getPublicKey(cert, function(publicKey, algorithm) {
var combinedAlgorithm = combineAlgorithms(algorithm, importParams); var combinedAlgorithm = combineAlgorithms(algorithm, importParams);
callback(publicKey, combinedAlgorithm); callback(publicKey, combinedAlgorithm);
......
...@@ -180,14 +180,12 @@ function testStaticMethods() { ...@@ -180,14 +180,12 @@ function testStaticMethods() {
assertTrue(!!chrome.platformKeys, "No platformKeys namespace."); assertTrue(!!chrome.platformKeys, "No platformKeys namespace.");
assertTrue(!!chrome.platformKeys.selectClientCertificates, assertTrue(!!chrome.platformKeys.selectClientCertificates,
"No selectClientCertificates function."); "No selectClientCertificates function.");
succeed(); assertTrue(!!chrome.platformKeys.getKeyPair, "No getKeyPair method.");
} assertTrue(!!chrome.platformKeys.subtleCrypto, "No subtleCrypto getter.");
assertTrue(!!chrome.platformKeys.subtleCrypto(), "No subtleCrypto object.");
function testHasSubtleCryptoMethods(token) { assertTrue(!!chrome.platformKeys.subtleCrypto().sign, "No sign method.");
assertTrue(!!token.subtleCrypto.generateKey, assertTrue(!!chrome.platformKeys.subtleCrypto().exportKey,
"token has no generateKey method"); "No exportKey method.");
assertTrue(!!token.subtleCrypto.sign, "token has no sign method");
assertTrue(!!token.subtleCrypto.exportKey, "token has no exportKey method");
succeed(); succeed();
} }
...@@ -252,10 +250,28 @@ function testMatchResult() { ...@@ -252,10 +250,28 @@ function testMatchResult() {
})); }));
} }
function testGetKeyPairMissingAlgorithName() {
var keyParams = {
// This is missing the algorithm name.
hash: {name: 'SHA-1'}
};
try {
chrome.platformKeys.getKeyPair(
data.client_1.buffer, keyParams, function(error) {
fail('getKeyPair call was expected to fail.');
});
fail('getKeyPair did not throw error');
} catch (e) {
assertEq('Algorithm: name: Missing or not a String', e.message);
succeed();
}
}
function testGetKeyPair() { function testGetKeyPair() {
var keyParams = { var keyParams = {
// Algorithm names are case-insensitive. // Algorithm names are case-insensitive.
'hash': {'name': 'sha-1'} name: 'RSASSA-Pkcs1-V1_5',
hash: {name: 'sha-1'}
}; };
chrome.platformKeys.getKeyPair( chrome.platformKeys.getKeyPair(
data.client_1.buffer, keyParams, data.client_1.buffer, keyParams,
...@@ -286,6 +302,7 @@ function testGetKeyPair() { ...@@ -286,6 +302,7 @@ function testGetKeyPair() {
function testSignNoHash() { function testSignNoHash() {
var keyParams = { var keyParams = {
// Algorithm names are case-insensitive. // Algorithm names are case-insensitive.
name: 'RSASSA-PKCS1-V1_5',
hash: {name: 'NONE'} hash: {name: 'NONE'}
}; };
var signParams = { var signParams = {
...@@ -307,6 +324,7 @@ function testSignNoHash() { ...@@ -307,6 +324,7 @@ function testSignNoHash() {
function testSignSha1Client1() { function testSignSha1Client1() {
var keyParams = { var keyParams = {
name: 'RSASSA-PKCS1-v1_5',
// Algorithm names are case-insensitive. // Algorithm names are case-insensitive.
hash: {name: 'Sha-1'} hash: {name: 'Sha-1'}
}; };
...@@ -332,6 +350,7 @@ function testSignSha1Client1() { ...@@ -332,6 +350,7 @@ function testSignSha1Client1() {
// that's implemented. // that's implemented.
function testSignFails(cert) { function testSignFails(cert) {
var keyParams = { var keyParams = {
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-1'} hash: {name: 'SHA-1'}
}; };
var signParams = { var signParams = {
...@@ -370,6 +389,7 @@ var testSuites = { ...@@ -370,6 +389,7 @@ var testSuites = {
testSelectCA1Certs, testSelectCA1Certs,
testInteractiveSelectNoCerts, testInteractiveSelectNoCerts,
testMatchResult, testMatchResult,
testGetKeyPairMissingAlgorithName,
testGetKeyPair, testGetKeyPair,
testSignNoHash, testSignNoHash,
testSignSha1Client1, testSignSha1Client1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment