1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 var utils
= require('utils');
6 var internalAPI
= require('platformKeys.internalAPI');
7 var keyModule
= require('platformKeys.Key');
8 var getSpki
= keyModule
.getSpki
;
9 var KeyUsage
= keyModule
.KeyUsage
;
11 var normalizeAlgorithm
=
12 requireNative('platform_keys_natives').NormalizeAlgorithm
;
14 // This error is thrown by the internal and public API's token functions and
15 // must be rethrown by this custom binding. Keep this in sync with the C++ part
17 var errorInvalidToken
= "The token is not valid.";
19 // The following errors are specified in WebCrypto.
20 // TODO(pneubeck): These should be DOMExceptions.
21 function CreateNotSupportedError() {
22 return new Error('The algorithm is not supported');
25 function CreateInvalidAccessError() {
26 return new Error('The requested operation is not valid for the provided key');
29 function CreateDataError() {
30 return new Error('Data provided to an operation does not meet requirements');
33 function CreateSyntaxError() {
34 return new Error('A required parameter was missing or out-of-range');
37 function CreateOperationError() {
38 return new Error('The operation failed for an operation-specific reason');
41 // Catches an |internalErrorInvalidToken|. If so, forwards it to |reject| and
43 function catchInvalidTokenError(reject
) {
44 if (chrome
.runtime
.lastError
&&
45 chrome
.runtime
.lastError
.message
== errorInvalidToken
) {
46 reject(chrome
.runtime
.lastError
);
53 * Implementation of WebCrypto.SubtleCrypto used in platformKeys and
54 * enterprise.platformKeys.
55 * @param {string} tokenId The id of the backing Token.
58 var SubtleCryptoImpl = function(tokenId
) {
59 this.tokenId
= tokenId
;
62 SubtleCryptoImpl
.prototype.sign = function(algorithm
, key
, dataView
) {
63 var subtleCrypto
= this;
64 return new Promise(function(resolve
, reject
) {
65 if (key
.type
!= 'private' || key
.usages
.indexOf(KeyUsage
.sign
) == -1)
66 throw CreateInvalidAccessError();
68 var normalizedAlgorithmParameters
=
69 normalizeAlgorithm(algorithm
, 'Sign');
70 if (!normalizedAlgorithmParameters
) {
71 // TODO(pneubeck): It's not clear from the WebCrypto spec which error to
73 throw CreateSyntaxError();
76 // Create an ArrayBuffer that equals the dataView. Note that dataView.buffer
77 // might contain more data than dataView.
78 var data
= dataView
.buffer
.slice(dataView
.byteOffset
,
79 dataView
.byteOffset
+ dataView
.byteLength
);
80 internalAPI
.sign(subtleCrypto
.tokenId
,
82 key
.algorithm
.hash
.name
,
85 if (catchInvalidTokenError(reject
))
87 if (chrome
.runtime
.lastError
) {
88 reject(CreateOperationError());
96 SubtleCryptoImpl
.prototype.exportKey = function(format
, key
) {
97 return new Promise(function(resolve
, reject
) {
98 if (format
== 'pkcs8') {
99 // Either key.type is not 'private' or the key is not extractable. In both
100 // cases the error is the same.
101 throw CreateInvalidAccessError();
102 } else if (format
== 'spki') {
103 if (key
.type
!= 'public')
104 throw CreateInvalidAccessError();
105 resolve(getSpki(key
));
107 // TODO(pneubeck): It should be possible to export to format 'jwk'.
108 throw CreateNotSupportedError();
113 // Required for subclassing.
114 exports
.SubtleCryptoImpl
= SubtleCryptoImpl
116 exports
.SubtleCrypto
=
117 utils
.expose('SubtleCrypto',
119 {functions
:['sign', 'exportKey']});