| 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 |