| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var utils = require('utils'); | 5 var utils = require('utils'); |
| 6 var internalAPI = require('enterprise.platformKeys.internalAPI'); | 6 var internalAPI = require('enterprise.platformKeys.internalAPI'); |
| 7 var intersect = require('enterprise.platformKeys.utils').intersect; | 7 var intersect = require('platformKeys.utils').intersect; |
| 8 var subtleCryptoModule = require('platformKeys.SubtleCrypto'); |
| 9 var SubtleCrypto = subtleCryptoModule.SubtleCrypto; |
| 10 var SubtleCryptoImpl = subtleCryptoModule.SubtleCryptoImpl; |
| 8 var KeyPair = require('enterprise.platformKeys.KeyPair').KeyPair; | 11 var KeyPair = require('enterprise.platformKeys.KeyPair').KeyPair; |
| 9 var keyModule = require('enterprise.platformKeys.Key'); | 12 var KeyUsage = require('platformKeys.Key').KeyUsage; |
| 10 var getSpki = keyModule.getSpki; | |
| 11 var KeyUsage = keyModule.KeyUsage; | |
| 12 | 13 |
| 13 var normalizeAlgorithm = | 14 var normalizeAlgorithm = |
| 14 requireNative('enterprise_platform_keys_natives').NormalizeAlgorithm; | 15 requireNative('platform_keys_natives').NormalizeAlgorithm; |
| 15 | 16 |
| 16 // This error is thrown by the internal and public API's token functions and | 17 // This error is thrown by the internal and public API's token functions and |
| 17 // must be rethrown by this custom binding. Keep this in sync with the C++ part | 18 // must be rethrown by this custom binding. Keep this in sync with the C++ part |
| 18 // of this API. | 19 // of this API. |
| 19 var errorInvalidToken = "The token is not valid."; | 20 var errorInvalidToken = "The token is not valid."; |
| 20 | 21 |
| 21 // The following errors are specified in WebCrypto. | 22 // The following errors are specified in WebCrypto. |
| 22 // TODO(pneubeck): These should be DOMExceptions. | 23 // TODO(pneubeck): These should be DOMExceptions. |
| 23 function CreateNotSupportedError() { | 24 function CreateNotSupportedError() { |
| 24 return new Error('The algorithm is not supported'); | 25 return new Error('The algorithm is not supported'); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 expectedDigit = expected[i]; | 66 expectedDigit = expected[i]; |
| 66 } | 67 } |
| 67 if (array[array.length - 1 - i] !== expectedDigit) | 68 if (array[array.length - 1 - i] !== expectedDigit) |
| 68 return false; | 69 return false; |
| 69 } | 70 } |
| 70 return true; | 71 return true; |
| 71 } | 72 } |
| 72 | 73 |
| 73 /** | 74 /** |
| 74 * Implementation of WebCrypto.SubtleCrypto used in enterprise.platformKeys. | 75 * Implementation of WebCrypto.SubtleCrypto used in enterprise.platformKeys. |
| 76 * Derived from platformKeys.SubtleCrypto. |
| 75 * @param {string} tokenId The id of the backing Token. | 77 * @param {string} tokenId The id of the backing Token. |
| 76 * @constructor | 78 * @constructor |
| 77 */ | 79 */ |
| 78 var SubtleCryptoImpl = function(tokenId) { | 80 var EnterpriseSubtleCryptoImpl = function(tokenId) { |
| 79 this.tokenId = tokenId; | 81 SubtleCryptoImpl.call(this, tokenId); |
| 80 }; | 82 }; |
| 81 | 83 |
| 82 SubtleCryptoImpl.prototype.generateKey = | 84 EnterpriseSubtleCryptoImpl.prototype = |
| 85 Object.create(SubtleCryptoImpl.prototype); |
| 86 |
| 87 EnterpriseSubtleCryptoImpl.prototype.generateKey = |
| 83 function(algorithm, extractable, keyUsages) { | 88 function(algorithm, extractable, keyUsages) { |
| 84 var subtleCrypto = this; | 89 var subtleCrypto = this; |
| 85 return new Promise(function(resolve, reject) { | 90 return new Promise(function(resolve, reject) { |
| 86 // TODO(pneubeck): Apply the algorithm normalization of the WebCrypto | 91 // TODO(pneubeck): Apply the algorithm normalization of the WebCrypto |
| 87 // implementation. | 92 // implementation. |
| 88 | 93 |
| 89 if (extractable) { | 94 if (extractable) { |
| 90 // Note: This deviates from WebCrypto.SubtleCrypto. | 95 // Note: This deviates from WebCrypto.SubtleCrypto. |
| 91 throw CreateNotSupportedError(); | 96 throw CreateNotSupportedError(); |
| 92 } | 97 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 121 return; | 126 return; |
| 122 if (chrome.runtime.lastError) { | 127 if (chrome.runtime.lastError) { |
| 123 reject(CreateOperationError()); | 128 reject(CreateOperationError()); |
| 124 return; | 129 return; |
| 125 } | 130 } |
| 126 resolve(new KeyPair(spki, normalizedAlgorithmParameters, keyUsages)); | 131 resolve(new KeyPair(spki, normalizedAlgorithmParameters, keyUsages)); |
| 127 }); | 132 }); |
| 128 }); | 133 }); |
| 129 }; | 134 }; |
| 130 | 135 |
| 131 SubtleCryptoImpl.prototype.sign = function(algorithm, key, dataView) { | |
| 132 var subtleCrypto = this; | |
| 133 return new Promise(function(resolve, reject) { | |
| 134 if (key.type != 'private' || key.usages.indexOf(KeyUsage.sign) == -1) | |
| 135 throw CreateInvalidAccessError(); | |
| 136 | |
| 137 var normalizedAlgorithmParameters = | |
| 138 normalizeAlgorithm(algorithm, 'Sign'); | |
| 139 if (!normalizedAlgorithmParameters) { | |
| 140 // TODO(pneubeck): It's not clear from the WebCrypto spec which error to | |
| 141 // throw here. | |
| 142 throw CreateSyntaxError(); | |
| 143 } | |
| 144 | |
| 145 // Create an ArrayBuffer that equals the dataView. Note that dataView.buffer | |
| 146 // might contain more data than dataView. | |
| 147 var data = dataView.buffer.slice(dataView.byteOffset, | |
| 148 dataView.byteOffset + dataView.byteLength); | |
| 149 internalAPI.sign(subtleCrypto.tokenId, | |
| 150 getSpki(key), | |
| 151 key.algorithm.hash.name, | |
| 152 data, | |
| 153 function(signature) { | |
| 154 if (catchInvalidTokenError(reject)) | |
| 155 return; | |
| 156 if (chrome.runtime.lastError) { | |
| 157 reject(CreateOperationError()); | |
| 158 return; | |
| 159 } | |
| 160 resolve(signature); | |
| 161 }); | |
| 162 }); | |
| 163 }; | |
| 164 | |
| 165 SubtleCryptoImpl.prototype.exportKey = function(format, key) { | |
| 166 return new Promise(function(resolve, reject) { | |
| 167 if (format == 'pkcs8') { | |
| 168 // Either key.type is not 'private' or the key is not extractable. In both | |
| 169 // cases the error is the same. | |
| 170 throw CreateInvalidAccessError(); | |
| 171 } else if (format == 'spki') { | |
| 172 if (key.type != 'public') | |
| 173 throw CreateInvalidAccessError(); | |
| 174 resolve(getSpki(key)); | |
| 175 } else { | |
| 176 // TODO(pneubeck): It should be possible to export to format 'jwk'. | |
| 177 throw CreateNotSupportedError(); | |
| 178 } | |
| 179 }); | |
| 180 }; | |
| 181 | |
| 182 exports.SubtleCrypto = | 136 exports.SubtleCrypto = |
| 183 utils.expose('SubtleCrypto', | 137 utils.expose('SubtleCrypto', |
| 184 SubtleCryptoImpl, | 138 EnterpriseSubtleCryptoImpl, |
| 185 {functions:['generateKey', 'sign', 'exportKey']}); | 139 { |
| 140 superclass: SubtleCrypto, |
| 141 functions: ['generateKey'] |
| 142 // ['sign', 'exportKey'] are exposed by the base class |
| 143 }); |
| OLD | NEW |