OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 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. | |
4 | |
5 #ifndef CONTENT_RENDERER_WEBCRYPTO_WEBCRYPTO_UTIL_H_ | |
6 #define CONTENT_RENDERER_WEBCRYPTO_WEBCRYPTO_UTIL_H_ | |
7 | |
8 #include <string> | |
9 #include <vector> | |
10 #include "base/basictypes.h" | |
11 #include "content/common/content_export.h" | |
12 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | |
13 #include "third_party/WebKit/public/platform/WebCrypto.h" // TODO(eroman): delet
e | |
14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | |
15 #include "third_party/WebKit/public/platform/WebCryptoKey.h" | |
16 | |
17 namespace content { | |
18 | |
19 namespace webcrypto { | |
20 | |
21 // TODO(eroman): Move Status class to a separate file | |
22 | |
23 // Status indicates whether an operation completed successfully, or with an | |
24 // error. The error is used for verification in unit-tests, as well as for | |
25 // display to the user. | |
26 // | |
27 // As such, it is important that errors DO NOT reveal any sensitive material | |
28 // (like key bytes). | |
29 // | |
30 // Care must be taken with what errors are reported back to blink when doing | |
31 // compound operations like unwrapping a JWK key. In this case, errors | |
32 // generated by the JWK import are not appropriate to report since the wrapped | |
33 // JWK is not visible to the caller. | |
34 class CONTENT_EXPORT Status { | |
35 public: | |
36 // Returns true if the Status represents an error (any one of them). | |
37 bool IsError() const; | |
38 | |
39 // Returns true if the Status represent success. | |
40 bool IsSuccess() const; | |
41 | |
42 // Returns true if the Status contains a non-empty error message. | |
43 bool HasErrorDetails() const; | |
44 | |
45 // Returns a UTF-8 error message (non-localized) describing the error. This | |
46 // message is intended to be displayed in the dev tools console. | |
47 std::string ToString() const; | |
48 | |
49 // Constructs a status representing success. | |
50 static Status Success(); | |
51 | |
52 // Constructs a status representing a generic error. It contains no extra | |
53 // details. | |
54 static Status Error(); | |
55 | |
56 // ------------------------------------ | |
57 // Errors when importing a JWK formatted key | |
58 // ------------------------------------ | |
59 | |
60 // The key bytes could not parsed as JSON dictionary. This either | |
61 // means there was a parsing error, or the JSON object was not | |
62 // convertable to a dictionary. | |
63 static Status ErrorJwkNotDictionary(); | |
64 | |
65 // The required property |property| was missing. | |
66 static Status ErrorJwkPropertyMissing(const std::string& property); | |
67 | |
68 // The property |property| was not of type |expected_type|. | |
69 static Status ErrorJwkPropertyWrongType(const std::string& property, | |
70 const std::string& expected_type); | |
71 | |
72 // The property |property| was a string, however could not be successfully | |
73 // base64 decoded. | |
74 static Status ErrorJwkBase64Decode(const std::string& property); | |
75 | |
76 // The "extractable" parameter was specified but was | |
77 // incompatible with the value requested by the Web Crypto call. | |
78 static Status ErrorJwkExtractableInconsistent(); | |
79 | |
80 // The "alg" parameter could not be converted to an equivalent | |
81 // WebCryptoAlgorithm. Either it was malformed or unrecognized. | |
82 static Status ErrorJwkUnrecognizedAlgorithm(); | |
83 | |
84 // The "alg" parameter is incompatible with the (optional) Algorithm | |
85 // specified by the Web Crypto import operation. | |
86 static Status ErrorJwkAlgorithmInconsistent(); | |
87 | |
88 // The "alg" parameter was not provided, however neither was an algorithm | |
89 // provided by the Web Crypto import operation. | |
90 static Status ErrorJwkAlgorithmMissing(); | |
91 | |
92 // The "use" parameter was specified, however it couldn't be converted to an | |
93 // equivalent Web Crypto usage. | |
94 static Status ErrorJwkUnrecognizedUsage(); | |
95 | |
96 // The "use" parameter was specified, however it is incompatible with that | |
97 // specified by the Web Crypto import operation. | |
98 static Status ErrorJwkUsageInconsistent(); | |
99 | |
100 // TODO(eroman): Private key import through JWK is not yet supported. | |
101 static Status ErrorJwkRsaPrivateKeyUnsupported(); | |
102 | |
103 // The "kty" parameter was given and was a string, however it was | |
104 // unrecognized. | |
105 static Status ErrorJwkUnrecognizedKty(); | |
106 | |
107 // The amount of key data provided was incompatible with the selected | |
108 // algorithm. For instance if the algorith name was A128CBC then EXACTLY | |
109 // 128-bits of key data must have been provided. If 192-bits of key data were | |
110 // given that is an error. | |
111 static Status ErrorJwkIncorrectKeyLength(); | |
112 | |
113 // ------------------------------------ | |
114 // Other errors | |
115 // ------------------------------------ | |
116 | |
117 // No key data was provided when importing an spki, pkcs8, or jwk formatted | |
118 // key. This does not apply to raw format, since it is possible to have empty | |
119 // key data there. | |
120 static Status ErrorImportEmptyKeyData(); | |
121 | |
122 // The wrong key was used for the operation. For instance, a public key was | |
123 // used to verify a RsaSsaPkcs1v1_5 signature, or tried exporting a private | |
124 // key using spki format. | |
125 static Status ErrorUnexpectedKeyType(); | |
126 | |
127 // When doing an AES-CBC encryption/decryption, the "iv" parameter was not 16 | |
128 // bytes. | |
129 static Status ErrorIncorrectSizeAesCbcIv(); | |
130 | |
131 // The data provided to an encrypt/decrypt/sign/verify operation was too | |
132 // large. This can either represent an internal limitation (for instance | |
133 // representing buffer lengths as uints), or an algorithm restriction (for | |
134 // instance RSAES can operation on messages relative to the length of the | |
135 // key's modulus). | |
136 static Status ErrorDataTooLarge(); | |
137 | |
138 // Something was unsupported or unimplemented. This can mean the algorithm in | |
139 // question was unsupported, some parameter combination was unsupported, or | |
140 // something has not yet been implemented. | |
141 static Status ErrorUnsupported(); | |
142 | |
143 // Something unexpected happened in the code, which implies there is a | |
144 // source-level bug. These should not happen, but safer to fail than simply | |
145 // DCHECK. | |
146 static Status ErrorUnexpected(); | |
147 | |
148 // The authentication tag length specified for AES-GCM encrypt/decrypt was | |
149 // not 32, 64, 96, 104, 112, 120, or 128. | |
150 static Status ErrorInvalidAesGcmTagLength(); | |
151 | |
152 // The "publicExponent" used to generate a key was invalid: either no bytes | |
153 // were specified, or the number was too large to fit into an "unsigned long" | |
154 // (implemention limitation), or the exponent was zero. | |
155 static Status ErrorGenerateKeyPublicExponent(); | |
156 | |
157 // The algorithm was null when importing a raw-formatted key. In this case it | |
158 // is required. | |
159 static Status ErrorMissingAlgorithmImportRawKey(); | |
160 | |
161 // The modulus bytes were empty when importing an RSA public key. | |
162 static Status ErrorImportRsaEmptyModulus(); | |
163 | |
164 // The the modulus length was zero bits when generating an RSA public key. | |
165 static Status ErrorGenerateRsaZeroModulus(); | |
166 | |
167 // The exponent bytes were empty when importing an RSA public key. | |
168 static Status ErrorImportRsaEmptyExponent(); | |
169 | |
170 // An unextractable key was used by an operation which exports the key data. | |
171 static Status ErrorKeyNotExtractable(); | |
172 | |
173 // The key length specified when generating a key was invalid. Either it was | |
174 // zero, or it was not a multiple of 8 bits. | |
175 static Status ErrorGenerateKeyLength(); | |
176 | |
177 private: | |
178 enum Type { TYPE_ERROR, TYPE_SUCCESS }; | |
179 | |
180 // Constructs an error with the specified message. | |
181 explicit Status(const std::string& error_details_utf8); | |
182 | |
183 // Constructs a success or error without any details. | |
184 explicit Status(Type type); | |
185 | |
186 Type type_; | |
187 std::string error_details_; | |
188 }; | |
189 | |
190 // Returns a pointer to the start of |data|, or NULL if it is empty. This is a | |
191 // convenience function for getting the pointer, and should not be used beyond | |
192 // the expected lifetime of |data|. | |
193 CONTENT_EXPORT const uint8* Uint8VectorStart(const std::vector<uint8>& data); | |
194 | |
195 // Shrinks a WebArrayBuffer to a new size. | |
196 // TODO(eroman): This works by re-allocating a new buffer. It would be better if | |
197 // the WebArrayBuffer could just be truncated instead. | |
198 void ShrinkBuffer(blink::WebArrayBuffer* buffer, unsigned int new_size); | |
199 | |
200 // Creates a WebArrayBuffer from a uint8 byte array | |
201 blink::WebArrayBuffer CreateArrayBuffer(const uint8* data, | |
202 unsigned int data_size); | |
203 | |
204 // TODO(eroman): Move this to JWK file. | |
205 // This function decodes unpadded 'base64url' encoded data, as described in | |
206 // RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5. | |
207 // In Web Crypto, this type of encoding is only used inside JWK. | |
208 bool Base64DecodeUrlSafe(const std::string& input, std::string* output); | |
209 | |
210 CONTENT_EXPORT bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id); | |
211 | |
212 // Returns the "hash" param for an algorithm if it exists, otherwise returns | |
213 // a null algorithm. | |
214 blink::WebCryptoAlgorithm GetInnerHashAlgorithm( | |
215 const blink::WebCryptoAlgorithm& algorithm); | |
216 | |
217 // Creates a WebCryptoAlgorithm without any parameters. | |
218 CONTENT_EXPORT blink::WebCryptoAlgorithm CreateAlgorithm( | |
219 blink::WebCryptoAlgorithmId id); | |
220 | |
221 // Creates an HMAC import algorithm whose inner hash algorithm is determined by | |
222 // the specified algorithm ID. It is an error to call this method with a hash | |
223 // algorithm that is not SHA*. | |
224 CONTENT_EXPORT blink::WebCryptoAlgorithm CreateHmacImportAlgorithm( | |
225 blink::WebCryptoAlgorithmId hash_id); | |
226 | |
227 // Creates an RSASSA-PKCS1-v1_5 algorithm. It is an error to call this with a | |
228 // hash_id that is not a SHA*. | |
229 blink::WebCryptoAlgorithm CreateRsaSsaImportAlgorithm( | |
230 blink::WebCryptoAlgorithmId hash_id); | |
231 | |
232 // Creates an RSA-OAEP algorithm. It is an error to call this with a hash_id | |
233 // that is not a SHA*. | |
234 blink::WebCryptoAlgorithm CreateRsaOaepImportAlgorithm( | |
235 blink::WebCryptoAlgorithmId hash_id); | |
236 | |
237 // TODO(eroman): Move to shared_crypto.cc | |
238 // Returns the internal block size for SHA-* | |
239 unsigned int ShaBlockSizeBytes(blink::WebCryptoAlgorithmId hash_id); | |
240 | |
241 bool CreateSecretKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | |
242 unsigned keylen_bytes, | |
243 blink::WebCryptoKeyAlgorithm* key_algorithm); | |
244 | |
245 } // namespace webcrypto | |
246 | |
247 } // namespace content | |
248 | |
249 #endif // CONTENT_RENDERER_WEBCRYPTO_WEBCRYPTO_UTIL_H_ | |
OLD | NEW |