Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "modules/crypto/NormalizeAlgorithm.h" | 32 #include "modules/crypto/NormalizeAlgorithm.h" |
| 33 | 33 |
| 34 #include "bindings/v8/Dictionary.h" | 34 #include "bindings/v8/Dictionary.h" |
| 35 #include "platform/CryptoResult.h" | 35 #include "platform/CryptoResult.h" |
| 36 #include "platform/NotImplemented.h" | 36 #include "platform/NotImplemented.h" |
| 37 #include "public/platform/WebCryptoAlgorithmParams.h" | 37 #include "public/platform/WebCryptoAlgorithmParams.h" |
| 38 #include "public/platform/WebString.h" | 38 #include "public/platform/WebString.h" |
| 39 #include "wtf/ArrayBuffer.h" | 39 #include "wtf/ArrayBuffer.h" |
| 40 #include "wtf/ArrayBufferView.h" | 40 #include "wtf/ArrayBufferView.h" |
| 41 #include "wtf/HashMap.h" | |
| 42 #include "wtf/MathExtras.h" | 41 #include "wtf/MathExtras.h" |
| 43 #include "wtf/Uint8Array.h" | 42 #include "wtf/Uint8Array.h" |
| 44 #include "wtf/Vector.h" | 43 #include "wtf/Vector.h" |
| 45 #include "wtf/text/StringBuilder.h" | 44 #include "wtf/text/StringBuilder.h" |
| 46 #include "wtf/text/StringHash.h" | 45 #include <algorithm> |
| 47 | 46 |
| 48 namespace WebCore { | 47 namespace WebCore { |
| 49 | 48 |
| 50 namespace { | 49 namespace { |
| 51 | 50 |
| 52 struct AlgorithmNameMapping { | 51 struct AlgorithmNameMapping { |
| 52 // Must be an upper case ASCII string. | |
| 53 const char* const algorithmName; | 53 const char* const algorithmName; |
| 54 // Must be strlen(algorithmName). | |
| 55 unsigned char algorithmNameLength; | |
| 54 blink::WebCryptoAlgorithmId algorithmId; | 56 blink::WebCryptoAlgorithmId algorithmId; |
| 57 | |
| 58 #if ASSERT_ENABLED | |
| 59 bool operator<(const AlgorithmNameMapping&) const; | |
| 60 #endif | |
| 55 }; | 61 }; |
| 56 | 62 |
| 57 // Indicates that the algorithm doesn't support the specified operation. | |
| 58 const int UnsupportedOp = -1; | |
| 59 | |
| 60 // Either UnsupportedOp, or a value from blink::WebCryptoAlgorithmParamsType | |
| 61 typedef int AlgorithmParamsForOperation; | |
| 62 | |
| 63 struct OperationParamsMapping { | 63 struct OperationParamsMapping { |
| 64 blink::WebCryptoAlgorithmId algorithmId; | 64 blink::WebCryptoAlgorithmId algorithmId; |
| 65 AlgorithmOperation operation; | 65 AlgorithmOperation operation; |
| 66 AlgorithmParamsForOperation params; | 66 blink::WebCryptoAlgorithmParamsType params; |
| 67 | |
| 68 bool operator<(const OperationParamsMapping&) const; | |
| 67 }; | 69 }; |
| 68 | 70 |
| 71 // Must be sorted by length, and then by reverse string. | |
| 72 // Also all names must be upper case ASCII. | |
| 69 const AlgorithmNameMapping algorithmNameMappings[] = { | 73 const AlgorithmNameMapping algorithmNameMappings[] = { |
| 70 {"AES-CBC", blink::WebCryptoAlgorithmIdAesCbc}, | 74 {"HMAC", 4, blink::WebCryptoAlgorithmIdHmac}, |
| 71 {"AES-CTR", blink::WebCryptoAlgorithmIdAesCtr}, | 75 {"SHA-1", 5, blink::WebCryptoAlgorithmIdSha1}, |
| 72 {"AES-GCM", blink::WebCryptoAlgorithmIdAesGcm}, | 76 {"AES-KW", 6, blink::WebCryptoAlgorithmIdAesKw}, |
| 73 {"HMAC", blink::WebCryptoAlgorithmIdHmac}, | 77 {"SHA-512", 7, blink::WebCryptoAlgorithmIdSha512}, |
| 74 {"RSASSA-PKCS1-v1_5", blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5}, | 78 {"SHA-384", 7, blink::WebCryptoAlgorithmIdSha384}, |
| 75 {"RSAES-PKCS1-v1_5", blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5}, | 79 {"SHA-256", 7, blink::WebCryptoAlgorithmIdSha256}, |
| 76 {"SHA-1", blink::WebCryptoAlgorithmIdSha1}, | 80 {"AES-CBC", 7, blink::WebCryptoAlgorithmIdAesCbc}, |
| 77 {"SHA-256", blink::WebCryptoAlgorithmIdSha256}, | 81 {"AES-GCM", 7, blink::WebCryptoAlgorithmIdAesGcm}, |
| 78 {"SHA-384", blink::WebCryptoAlgorithmIdSha384}, | 82 {"AES-CTR", 7, blink::WebCryptoAlgorithmIdAesCtr}, |
| 79 {"SHA-512", blink::WebCryptoAlgorithmIdSha512}, | 83 {"RSAES-PKCS1-V1_5", 16, blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5}, |
| 80 {"AES-KW", blink::WebCryptoAlgorithmIdAesKw}, | 84 {"RSASSA-PKCS1-V1_5", 17, blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5}, |
| 81 }; | 85 }; |
| 82 | 86 |
| 83 // What operations each algorithm supports, and what parameters it expects. | 87 // What operations each algorithm supports, and what parameters it expects. |
| 88 // Must be sorted by algorithm id and then operation. | |
| 84 const OperationParamsMapping operationParamsMappings[] = { | 89 const OperationParamsMapping operationParamsMappings[] = { |
| 85 // AES-CBC | 90 // AES-CBC |
| 91 {blink::WebCryptoAlgorithmIdAesCbc, Encrypt, blink::WebCryptoAlgorithmParams TypeAesCbcParams}, | |
| 86 {blink::WebCryptoAlgorithmIdAesCbc, Decrypt, blink::WebCryptoAlgorithmParams TypeAesCbcParams}, | 92 {blink::WebCryptoAlgorithmIdAesCbc, Decrypt, blink::WebCryptoAlgorithmParams TypeAesCbcParams}, |
| 87 {blink::WebCryptoAlgorithmIdAesCbc, Encrypt, blink::WebCryptoAlgorithmParams TypeAesCbcParams}, | |
| 88 {blink::WebCryptoAlgorithmIdAesCbc, GenerateKey, blink::WebCryptoAlgorithmPa ramsTypeAesKeyGenParams}, | 93 {blink::WebCryptoAlgorithmIdAesCbc, GenerateKey, blink::WebCryptoAlgorithmPa ramsTypeAesKeyGenParams}, |
| 89 {blink::WebCryptoAlgorithmIdAesCbc, ImportKey, blink::WebCryptoAlgorithmPara msTypeNone}, | 94 {blink::WebCryptoAlgorithmIdAesCbc, ImportKey, blink::WebCryptoAlgorithmPara msTypeNone}, |
| 95 {blink::WebCryptoAlgorithmIdAesCbc, WrapKey, blink::WebCryptoAlgorithmParams TypeAesCbcParams}, | |
| 90 {blink::WebCryptoAlgorithmIdAesCbc, UnwrapKey, blink::WebCryptoAlgorithmPara msTypeAesCbcParams}, | 96 {blink::WebCryptoAlgorithmIdAesCbc, UnwrapKey, blink::WebCryptoAlgorithmPara msTypeAesCbcParams}, |
| 91 {blink::WebCryptoAlgorithmIdAesCbc, WrapKey, blink::WebCryptoAlgorithmParams TypeAesCbcParams}, | |
| 92 | |
| 93 // AES-CTR | |
| 94 {blink::WebCryptoAlgorithmIdAesCtr, Decrypt, blink::WebCryptoAlgorithmParams TypeAesCtrParams}, | |
| 95 {blink::WebCryptoAlgorithmIdAesCtr, Encrypt, blink::WebCryptoAlgorithmParams TypeAesCtrParams}, | |
| 96 {blink::WebCryptoAlgorithmIdAesCtr, GenerateKey, blink::WebCryptoAlgorithmPa ramsTypeAesKeyGenParams}, | |
| 97 {blink::WebCryptoAlgorithmIdAesCtr, ImportKey, blink::WebCryptoAlgorithmPara msTypeNone}, | |
| 98 {blink::WebCryptoAlgorithmIdAesCtr, UnwrapKey, blink::WebCryptoAlgorithmPara msTypeAesCtrParams}, | |
| 99 {blink::WebCryptoAlgorithmIdAesCtr, WrapKey, blink::WebCryptoAlgorithmParams TypeAesCtrParams}, | |
| 100 | 97 |
| 101 // HMAC | 98 // HMAC |
| 102 {blink::WebCryptoAlgorithmIdHmac, Sign, blink::WebCryptoAlgorithmParamsTypeN one}, | 99 {blink::WebCryptoAlgorithmIdHmac, Sign, blink::WebCryptoAlgorithmParamsTypeN one}, |
| 103 {blink::WebCryptoAlgorithmIdHmac, Verify, blink::WebCryptoAlgorithmParamsTyp eNone}, | 100 {blink::WebCryptoAlgorithmIdHmac, Verify, blink::WebCryptoAlgorithmParamsTyp eNone}, |
| 104 {blink::WebCryptoAlgorithmIdHmac, GenerateKey, blink::WebCryptoAlgorithmPara msTypeHmacKeyGenParams}, | 101 {blink::WebCryptoAlgorithmIdHmac, GenerateKey, blink::WebCryptoAlgorithmPara msTypeHmacKeyGenParams}, |
| 105 {blink::WebCryptoAlgorithmIdHmac, ImportKey, blink::WebCryptoAlgorithmParams TypeHmacImportParams}, | 102 {blink::WebCryptoAlgorithmIdHmac, ImportKey, blink::WebCryptoAlgorithmParams TypeHmacImportParams}, |
| 106 | 103 |
| 107 // RSASSA-PKCS1-v1_5 | 104 // RSASSA-PKCS1-v1_5 |
| 108 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Sign, blink::WebCryptoAlgorithm ParamsTypeNone}, | 105 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Sign, blink::WebCryptoAlgorithm ParamsTypeNone}, |
| 109 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Verify, blink::WebCryptoAlgorit hmParamsTypeNone}, | 106 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Verify, blink::WebCryptoAlgorit hmParamsTypeNone}, |
| 110 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, GenerateKey, blink::WebCryptoAl gorithmParamsTypeRsaHashedKeyGenParams}, | 107 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, GenerateKey, blink::WebCryptoAl gorithmParamsTypeRsaHashedKeyGenParams}, |
| 111 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, ImportKey, blink::WebCryptoAlgo rithmParamsTypeRsaHashedImportParams}, | 108 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, ImportKey, blink::WebCryptoAlgo rithmParamsTypeRsaHashedImportParams}, |
| 112 | 109 |
| 113 // RSAES-PKCS1-v1_5 | 110 // RSAES-PKCS1-v1_5 |
| 114 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, Encrypt, blink::WebCryptoAlgorit hmParamsTypeNone}, | 111 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, Encrypt, blink::WebCryptoAlgorit hmParamsTypeNone}, |
| 115 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, Decrypt, blink::WebCryptoAlgorit hmParamsTypeNone}, | 112 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, Decrypt, blink::WebCryptoAlgorit hmParamsTypeNone}, |
| 116 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, GenerateKey, blink::WebCryptoAlg orithmParamsTypeRsaKeyGenParams}, | 113 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, GenerateKey, blink::WebCryptoAlg orithmParamsTypeRsaKeyGenParams}, |
| 117 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, ImportKey, blink::WebCryptoAlgor ithmParamsTypeNone}, | 114 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, ImportKey, blink::WebCryptoAlgor ithmParamsTypeNone}, |
| 118 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, WrapKey, blink::WebCryptoAlgorit hmParamsTypeNone}, | 115 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, WrapKey, blink::WebCryptoAlgorit hmParamsTypeNone}, |
| 119 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, UnwrapKey, blink::WebCryptoAlgor ithmParamsTypeNone}, | 116 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, UnwrapKey, blink::WebCryptoAlgor ithmParamsTypeNone}, |
| 120 | 117 |
| 121 // SHA-* | 118 // SHA-* |
| 122 {blink::WebCryptoAlgorithmIdSha1, Digest, blink::WebCryptoAlgorithmParamsTyp eNone}, | 119 {blink::WebCryptoAlgorithmIdSha1, Digest, blink::WebCryptoAlgorithmParamsTyp eNone}, |
| 123 {blink::WebCryptoAlgorithmIdSha256, Digest, blink::WebCryptoAlgorithmParamsT ypeNone}, | 120 {blink::WebCryptoAlgorithmIdSha256, Digest, blink::WebCryptoAlgorithmParamsT ypeNone}, |
| 124 {blink::WebCryptoAlgorithmIdSha384, Digest, blink::WebCryptoAlgorithmParamsT ypeNone}, | 121 {blink::WebCryptoAlgorithmIdSha384, Digest, blink::WebCryptoAlgorithmParamsT ypeNone}, |
| 125 {blink::WebCryptoAlgorithmIdSha512, Digest, blink::WebCryptoAlgorithmParamsT ypeNone}, | 122 {blink::WebCryptoAlgorithmIdSha512, Digest, blink::WebCryptoAlgorithmParamsT ypeNone}, |
| 126 | 123 |
| 124 // AES-GCM | |
| 125 {blink::WebCryptoAlgorithmIdAesGcm, Encrypt, blink::WebCryptoAlgorithmParams TypeAesGcmParams}, | |
| 126 {blink::WebCryptoAlgorithmIdAesGcm, Decrypt, blink::WebCryptoAlgorithmParams TypeAesGcmParams}, | |
| 127 {blink::WebCryptoAlgorithmIdAesGcm, GenerateKey, blink::WebCryptoAlgorithmPa ramsTypeAesKeyGenParams}, | |
| 128 {blink::WebCryptoAlgorithmIdAesGcm, ImportKey, blink::WebCryptoAlgorithmPara msTypeNone}, | |
| 129 {blink::WebCryptoAlgorithmIdAesGcm, WrapKey, blink::WebCryptoAlgorithmParams TypeAesGcmParams}, | |
| 130 {blink::WebCryptoAlgorithmIdAesGcm, UnwrapKey, blink::WebCryptoAlgorithmPara msTypeAesGcmParams}, | |
| 131 | |
| 132 // AES-CTR | |
| 133 {blink::WebCryptoAlgorithmIdAesCtr, Encrypt, blink::WebCryptoAlgorithmParams TypeAesCtrParams}, | |
| 134 {blink::WebCryptoAlgorithmIdAesCtr, Decrypt, blink::WebCryptoAlgorithmParams TypeAesCtrParams}, | |
| 135 {blink::WebCryptoAlgorithmIdAesCtr, GenerateKey, blink::WebCryptoAlgorithmPa ramsTypeAesKeyGenParams}, | |
| 136 {blink::WebCryptoAlgorithmIdAesCtr, ImportKey, blink::WebCryptoAlgorithmPara msTypeNone}, | |
| 137 {blink::WebCryptoAlgorithmIdAesCtr, WrapKey, blink::WebCryptoAlgorithmParams TypeAesCtrParams}, | |
| 138 {blink::WebCryptoAlgorithmIdAesCtr, UnwrapKey, blink::WebCryptoAlgorithmPara msTypeAesCtrParams}, | |
| 139 | |
| 127 // AES-KW | 140 // AES-KW |
| 128 {blink::WebCryptoAlgorithmIdAesKw, GenerateKey, blink::WebCryptoAlgorithmPar amsTypeAesKeyGenParams}, | 141 {blink::WebCryptoAlgorithmIdAesKw, GenerateKey, blink::WebCryptoAlgorithmPar amsTypeAesKeyGenParams}, |
| 129 {blink::WebCryptoAlgorithmIdAesKw, ImportKey, blink::WebCryptoAlgorithmParam sTypeNone}, | 142 {blink::WebCryptoAlgorithmIdAesKw, ImportKey, blink::WebCryptoAlgorithmParam sTypeNone}, |
| 143 {blink::WebCryptoAlgorithmIdAesKw, WrapKey, blink::WebCryptoAlgorithmParamsT ypeNone}, | |
| 130 {blink::WebCryptoAlgorithmIdAesKw, UnwrapKey, blink::WebCryptoAlgorithmParam sTypeNone}, | 144 {blink::WebCryptoAlgorithmIdAesKw, UnwrapKey, blink::WebCryptoAlgorithmParam sTypeNone}, |
| 131 {blink::WebCryptoAlgorithmIdAesKw, WrapKey, blink::WebCryptoAlgorithmParamsT ypeNone}, | |
| 132 | |
| 133 // AES-GCM | |
| 134 {blink::WebCryptoAlgorithmIdAesGcm, GenerateKey, blink::WebCryptoAlgorithmPa ramsTypeAesKeyGenParams}, | |
| 135 {blink::WebCryptoAlgorithmIdAesGcm, ImportKey, blink::WebCryptoAlgorithmPara msTypeNone}, | |
| 136 {blink::WebCryptoAlgorithmIdAesGcm, Encrypt, blink::WebCryptoAlgorithmParams TypeAesGcmParams}, | |
| 137 {blink::WebCryptoAlgorithmIdAesGcm, Decrypt, blink::WebCryptoAlgorithmParams TypeAesGcmParams}, | |
| 138 {blink::WebCryptoAlgorithmIdAesGcm, UnwrapKey, blink::WebCryptoAlgorithmPara msTypeAesGcmParams}, | |
| 139 {blink::WebCryptoAlgorithmIdAesGcm, WrapKey, blink::WebCryptoAlgorithmParams TypeAesGcmParams}, | |
| 140 }; | 145 }; |
| 141 | 146 |
| 142 // This structure describes an algorithm and its supported operations. | 147 #if ASSERT_ENABLED |
| 143 struct AlgorithmInfo { | 148 bool AlgorithmNameMapping::operator<(const AlgorithmNameMapping& o) const |
| 144 AlgorithmInfo() | 149 { |
| 145 : algorithmName(0) | 150 if (algorithmNameLength < o.algorithmNameLength) |
| 146 { | 151 return true; |
| 147 for (size_t i = 0; i < WTF_ARRAY_LENGTH(paramsForOperation); ++i) | 152 if (algorithmNameLength > o.algorithmNameLength) |
| 148 paramsForOperation[i] = UnsupportedOp; | 153 return false; |
| 154 | |
| 155 for (size_t i = 0; i < algorithmNameLength; ++i) { | |
| 156 size_t reverseIndex = algorithmNameLength - i - 1; | |
| 157 char c1 = algorithmName[reverseIndex]; | |
| 158 char c2 = o.algorithmName[reverseIndex]; | |
| 159 | |
| 160 if (c1 < c2) | |
| 161 return true; | |
| 162 if (c1 > c2) | |
| 163 return false; | |
| 149 } | 164 } |
| 150 | 165 |
| 151 blink::WebCryptoAlgorithmId algorithmId; | 166 return false; |
| 152 const char* algorithmName; | |
| 153 AlgorithmParamsForOperation paramsForOperation[LastAlgorithmOperation + 1]; | |
| 154 }; | |
| 155 | |
| 156 // AlgorithmRegistry enumerates each of the different algorithms and its | |
| 157 // parameters. This describes the same information as the static tables above, | |
| 158 // but in a more convenient runtime form. | |
| 159 class AlgorithmRegistry { | |
| 160 public: | |
| 161 static AlgorithmRegistry& instance(); | |
| 162 | |
| 163 const AlgorithmInfo* lookupAlgorithmByName(const String&) const; | |
| 164 const AlgorithmInfo* lookupAlgorithmById(blink::WebCryptoAlgorithmId) const; | |
| 165 | |
| 166 private: | |
| 167 AlgorithmRegistry(); | |
| 168 | |
| 169 // Algorithm name to ID. | |
| 170 typedef HashMap<String, blink::WebCryptoAlgorithmId, CaseFoldingHash> Algori thmNameToIdMap; | |
| 171 AlgorithmNameToIdMap m_algorithmNameToId; | |
| 172 | |
| 173 // Algorithm ID to information. | |
| 174 AlgorithmInfo m_algorithms[blink::WebCryptoAlgorithmIdLast + 1]; | |
| 175 }; | |
| 176 | |
| 177 AlgorithmRegistry& AlgorithmRegistry::instance() | |
| 178 { | |
| 179 DEFINE_STATIC_LOCAL(AlgorithmRegistry, registry, ()); | |
| 180 return registry; | |
| 181 } | 167 } |
| 182 | 168 |
| 183 const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmByName(const String& algo rithmName) const | 169 bool verifyAlgorithmNameMappings(const AlgorithmNameMapping* begin, const Algori thmNameMapping* end) |
| 184 { | 170 { |
| 185 AlgorithmNameToIdMap::const_iterator it = m_algorithmNameToId.find(algorithm Name); | 171 for (const AlgorithmNameMapping* it = begin; it != end; ++it) { |
| 186 if (it == m_algorithmNameToId.end()) | 172 if (it->algorithmNameLength != strlen(it->algorithmName)) |
| 187 return 0; | 173 return false; |
| 188 return lookupAlgorithmById(it->value); | 174 String str(it->algorithmName, it->algorithmNameLength); |
| 175 if (!str.containsOnlyASCII()) | |
| 176 return false; | |
| 177 if (str.upper() != str) | |
| 178 return false; | |
| 179 } | |
| 180 | |
| 181 return std::is_sorted(begin, end); | |
| 182 } | |
| 183 #endif | |
| 184 | |
| 185 bool OperationParamsMapping::operator<(const OperationParamsMapping& o) const | |
| 186 { | |
| 187 if (algorithmId < o.algorithmId) | |
| 188 return true; | |
| 189 if (algorithmId > o.algorithmId) | |
| 190 return false; | |
| 191 return operation < o.operation; | |
| 189 } | 192 } |
| 190 | 193 |
| 191 const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmById(blink::WebCryptoAlgo rithmId algorithmId) const | 194 template <typename Char> |
|
abarth-chromium
2014/04/01 21:46:13
We usually use CharType for this template paramete
eroman
2014/04/01 22:28:31
Done.
| |
| 195 bool algorithmNameComparator(const AlgorithmNameMapping& a, StringImpl* b) | |
| 192 { | 196 { |
| 193 ASSERT(algorithmId >= 0 && algorithmId < WTF_ARRAY_LENGTH(m_algorithms)); | 197 if (a.algorithmNameLength < b->length()) |
| 194 return &m_algorithms[algorithmId]; | 198 return true; |
| 199 if (a.algorithmNameLength > b->length()) | |
| 200 return false; | |
| 201 | |
| 202 // Because the algorithm names contain many common prefixes, it is better | |
| 203 // to compare starting at the end of the string. | |
| 204 for (size_t i = 0; i < a.algorithmNameLength; ++i) { | |
| 205 size_t reverseIndex = a.algorithmNameLength - i - 1; | |
| 206 Char c1 = a.algorithmName[reverseIndex]; | |
| 207 Char c2 = b->getCharacters<Char>()[reverseIndex]; | |
| 208 if (!isASCII(c2)) | |
| 209 return false; | |
| 210 c2 = toASCIIUpper(c2); | |
| 211 | |
| 212 if (c1 < c2) | |
| 213 return true; | |
| 214 if (c1 > c2) | |
| 215 return false; | |
| 216 } | |
| 217 | |
| 218 return false; | |
| 195 } | 219 } |
| 196 | 220 |
| 197 AlgorithmRegistry::AlgorithmRegistry() | 221 bool lookupAlgorithmIdByName(const String& algorithmName, blink::WebCryptoAlgori thmId& id) |
| 198 { | 222 { |
| 199 for (size_t i = 0; i < WTF_ARRAY_LENGTH(algorithmNameMappings); ++i) { | 223 const AlgorithmNameMapping* begin = algorithmNameMappings; |
| 200 const AlgorithmNameMapping& mapping = algorithmNameMappings[i]; | 224 const AlgorithmNameMapping* end = algorithmNameMappings + WTF_ARRAY_LENGTH(a lgorithmNameMappings); |
| 201 m_algorithmNameToId.add(mapping.algorithmName, mapping.algorithmId); | |
| 202 m_algorithms[mapping.algorithmId].algorithmName = mapping.algorithmName; | |
| 203 m_algorithms[mapping.algorithmId].algorithmId = mapping.algorithmId; | |
| 204 } | |
| 205 | 225 |
| 206 for (size_t i = 0; i < WTF_ARRAY_LENGTH(operationParamsMappings); ++i) { | 226 ASSERT(verifyAlgorithmNameMappings(begin, end)); |
| 207 const OperationParamsMapping& mapping = operationParamsMappings[i]; | 227 |
| 208 m_algorithms[mapping.algorithmId].paramsForOperation[mapping.operation] = mapping.params; | 228 const AlgorithmNameMapping* it; |
| 209 } | 229 if (algorithmName.impl()->is8Bit()) |
| 230 it = std::lower_bound(begin, end, algorithmName.impl(), &algorithmNameCo mparator<LChar>); | |
| 231 else | |
| 232 it = std::lower_bound(begin, end, algorithmName.impl(), &algorithmNameCo mparator<UChar>); | |
| 233 | |
| 234 if (it == end) | |
| 235 return false; | |
| 236 | |
| 237 if (it->algorithmNameLength != algorithmName.length() || !equalIgnoringCase( algorithmName, it->algorithmName)) | |
| 238 return false; | |
| 239 | |
| 240 id = it->algorithmId; | |
| 241 return true; | |
| 242 } | |
| 243 | |
| 244 bool lookupAlgorithmParamsType(blink::WebCryptoAlgorithmId id, AlgorithmOperatio n op, blink::WebCryptoAlgorithmParamsType& paramsType) | |
| 245 { | |
| 246 const OperationParamsMapping* begin = operationParamsMappings; | |
| 247 const OperationParamsMapping* end = operationParamsMappings + WTF_ARRAY_LENG TH(operationParamsMappings); | |
| 248 | |
| 249 ASSERT(std::is_sorted(begin, end)); | |
| 250 | |
| 251 OperationParamsMapping search = { id, op }; | |
| 252 const OperationParamsMapping* it = std::lower_bound(begin, end, search); | |
| 253 if (it == end) | |
| 254 return false; | |
| 255 if (it->algorithmId != id || it->operation != op) | |
| 256 return false; | |
| 257 paramsType = it->params; | |
| 258 return true; | |
| 210 } | 259 } |
| 211 | 260 |
| 212 // ErrorContext holds a stack of string literals which describe what was | 261 // ErrorContext holds a stack of string literals which describe what was |
| 213 // happening at the time the error occurred. This is helpful because | 262 // happening at the time the error occurred. This is helpful because |
| 214 // parsing of the algorithm dictionary can be recursive and it is difficult to | 263 // parsing of the algorithm dictionary can be recursive and it is difficult to |
| 215 // tell what went wrong from a failure alone. | 264 // tell what went wrong from a failure alone. |
| 216 class ErrorContext { | 265 class ErrorContext { |
| 217 public: | 266 public: |
| 218 void add(const char* message) | 267 void add(const char* message) |
| 219 { | 268 { |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 errorDetails = context.toString("Not an object"); | 709 errorDetails = context.toString("Not an object"); |
| 661 return false; | 710 return false; |
| 662 } | 711 } |
| 663 | 712 |
| 664 String algorithmName; | 713 String algorithmName; |
| 665 if (!raw.get("name", algorithmName)) { | 714 if (!raw.get("name", algorithmName)) { |
| 666 errorDetails = context.toString("name", "Missing or not a string"); | 715 errorDetails = context.toString("name", "Missing or not a string"); |
| 667 return false; | 716 return false; |
| 668 } | 717 } |
| 669 | 718 |
| 670 const AlgorithmInfo* info = AlgorithmRegistry::instance().lookupAlgorithmByN ame(algorithmName); | 719 blink::WebCryptoAlgorithmId algorithmId; |
| 671 if (!info) { | 720 if (!lookupAlgorithmIdByName(algorithmName, algorithmId)) { |
| 672 errorDetails = context.toString("Unrecognized algorithm name"); | 721 errorDetails = context.toString("Unrecognized algorithm name"); |
| 673 return false; | 722 return false; |
| 674 } | 723 } |
| 675 | 724 |
| 676 context.add(info->algorithmName); | 725 context.add(algorithmIdToName(algorithmId)); |
| 677 | 726 |
| 678 if (info->paramsForOperation[op] == UnsupportedOp) { | 727 blink::WebCryptoAlgorithmParamsType paramsType; |
| 728 if (!lookupAlgorithmParamsType(algorithmId, op, paramsType)) { | |
| 679 errorDetails = context.toString("Unsupported operation"); | 729 errorDetails = context.toString("Unsupported operation"); |
| 680 return false; | 730 return false; |
| 681 } | 731 } |
| 682 | 732 |
| 683 blink::WebCryptoAlgorithmParamsType paramsType = static_cast<blink::WebCrypt oAlgorithmParamsType>(info->paramsForOperation[op]); | |
| 684 OwnPtr<blink::WebCryptoAlgorithmParams> params; | 733 OwnPtr<blink::WebCryptoAlgorithmParams> params; |
| 685 if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) | 734 if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) |
| 686 return false; | 735 return false; |
| 687 | 736 |
| 688 algorithm = blink::WebCryptoAlgorithm(info->algorithmId, params.release()); | 737 algorithm = blink::WebCryptoAlgorithm(algorithmId, params.release()); |
| 689 return true; | 738 return true; |
| 690 } | 739 } |
| 691 | 740 |
| 692 } // namespace | 741 } // namespace |
| 693 | 742 |
| 694 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp toAlgorithm& algorithm, CryptoResult* result) | 743 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp toAlgorithm& algorithm, CryptoResult* result) |
| 695 { | 744 { |
| 696 String errorDetails; | 745 String errorDetails; |
| 697 if (!parseAlgorithm(raw, op, algorithm, ErrorContext(), errorDetails)) { | 746 if (!parseAlgorithm(raw, op, algorithm, ErrorContext(), errorDetails)) { |
| 698 result->completeWithError(errorDetails); | 747 result->completeWithError(errorDetails); |
| 699 return false; | 748 return false; |
| 700 } | 749 } |
| 701 return true; | 750 return true; |
| 702 } | 751 } |
| 703 | 752 |
| 704 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) | 753 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) |
| 705 { | 754 { |
| 706 return AlgorithmRegistry::instance().lookupAlgorithmById(id)->algorithmName; | 755 switch (id) { |
| 756 case blink::WebCryptoAlgorithmIdAesCbc: | |
| 757 return "AES-CBC"; | |
| 758 case blink::WebCryptoAlgorithmIdAesCtr: | |
| 759 return "AES-CTR"; | |
| 760 case blink::WebCryptoAlgorithmIdAesGcm: | |
| 761 return "AES-GCM"; | |
| 762 case blink::WebCryptoAlgorithmIdHmac: | |
| 763 return "HMAC"; | |
| 764 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | |
| 765 return "RSASSA-PKCS1-v1_5"; | |
| 766 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | |
| 767 return "RSAES-PKCS1-v1_5"; | |
| 768 case blink::WebCryptoAlgorithmIdSha1: | |
| 769 return "SHA-1"; | |
| 770 case blink::WebCryptoAlgorithmIdSha256: | |
| 771 return "SHA-256"; | |
| 772 case blink::WebCryptoAlgorithmIdSha384: | |
| 773 return "SHA-384"; | |
| 774 case blink::WebCryptoAlgorithmIdSha512: | |
| 775 return "SHA-512"; | |
| 776 case blink::WebCryptoAlgorithmIdAesKw: | |
| 777 return "AES-KW"; | |
| 778 case blink::WebCryptoAlgorithmIdRsaOaep: | |
| 779 return "RSA-OAEP"; | |
| 780 } | |
| 781 return 0; | |
| 707 } | 782 } |
| 708 | 783 |
| 709 } // namespace WebCore | 784 } // namespace WebCore |
| OLD | NEW |