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 |
144 AlgorithmInfo() | 149 // Essentially std::is_sorted() (however that function is new to C++11). |
145 : algorithmName(0) | 150 template <typename Iterator> |
146 { | 151 bool isSorted(Iterator begin, Iterator end) |
147 for (size_t i = 0; i < WTF_ARRAY_LENGTH(paramsForOperation); ++i) | 152 { |
148 paramsForOperation[i] = UnsupportedOp; | 153 if (begin == end) |
| 154 return true; |
| 155 |
| 156 Iterator prev = begin; |
| 157 Iterator cur = begin + 1; |
| 158 |
| 159 while (cur != end) { |
| 160 if (*cur < *prev) |
| 161 return false; |
| 162 cur++; |
| 163 prev++; |
149 } | 164 } |
150 | 165 |
151 blink::WebCryptoAlgorithmId algorithmId; | 166 return true; |
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 AlgorithmNameMapping::operator<(const AlgorithmNameMapping& o) const |
184 { | 170 { |
185 AlgorithmNameToIdMap::const_iterator it = m_algorithmNameToId.find(algorithm
Name); | 171 if (algorithmNameLength < o.algorithmNameLength) |
186 if (it == m_algorithmNameToId.end()) | 172 return true; |
187 return 0; | 173 if (algorithmNameLength > o.algorithmNameLength) |
188 return lookupAlgorithmById(it->value); | 174 return false; |
| 175 |
| 176 for (size_t i = 0; i < algorithmNameLength; ++i) { |
| 177 size_t reverseIndex = algorithmNameLength - i - 1; |
| 178 char c1 = algorithmName[reverseIndex]; |
| 179 char c2 = o.algorithmName[reverseIndex]; |
| 180 |
| 181 if (c1 < c2) |
| 182 return true; |
| 183 if (c1 > c2) |
| 184 return false; |
| 185 } |
| 186 |
| 187 return false; |
189 } | 188 } |
190 | 189 |
191 const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmById(blink::WebCryptoAlgo
rithmId algorithmId) const | 190 bool verifyAlgorithmNameMappings(const AlgorithmNameMapping* begin, const Algori
thmNameMapping* end) |
192 { | 191 { |
193 ASSERT(algorithmId >= 0 && algorithmId < WTF_ARRAY_LENGTH(m_algorithms)); | 192 for (const AlgorithmNameMapping* it = begin; it != end; ++it) { |
194 return &m_algorithms[algorithmId]; | 193 if (it->algorithmNameLength != strlen(it->algorithmName)) |
| 194 return false; |
| 195 String str(it->algorithmName, it->algorithmNameLength); |
| 196 if (!str.containsOnlyASCII()) |
| 197 return false; |
| 198 if (str.upper() != str) |
| 199 return false; |
| 200 } |
| 201 |
| 202 return isSorted(begin, end); |
| 203 } |
| 204 #endif |
| 205 |
| 206 bool OperationParamsMapping::operator<(const OperationParamsMapping& o) const |
| 207 { |
| 208 if (algorithmId < o.algorithmId) |
| 209 return true; |
| 210 if (algorithmId > o.algorithmId) |
| 211 return false; |
| 212 return operation < o.operation; |
195 } | 213 } |
196 | 214 |
197 AlgorithmRegistry::AlgorithmRegistry() | 215 template <typename CharType> |
| 216 bool algorithmNameComparator(const AlgorithmNameMapping& a, StringImpl* b) |
198 { | 217 { |
199 for (size_t i = 0; i < WTF_ARRAY_LENGTH(algorithmNameMappings); ++i) { | 218 if (a.algorithmNameLength < b->length()) |
200 const AlgorithmNameMapping& mapping = algorithmNameMappings[i]; | 219 return true; |
201 m_algorithmNameToId.add(mapping.algorithmName, mapping.algorithmId); | 220 if (a.algorithmNameLength > b->length()) |
202 m_algorithms[mapping.algorithmId].algorithmName = mapping.algorithmName; | 221 return false; |
203 m_algorithms[mapping.algorithmId].algorithmId = mapping.algorithmId; | 222 |
| 223 // Because the algorithm names contain many common prefixes, it is better |
| 224 // to compare starting at the end of the string. |
| 225 for (size_t i = 0; i < a.algorithmNameLength; ++i) { |
| 226 size_t reverseIndex = a.algorithmNameLength - i - 1; |
| 227 CharType c1 = a.algorithmName[reverseIndex]; |
| 228 CharType c2 = b->getCharacters<CharType>()[reverseIndex]; |
| 229 if (!isASCII(c2)) |
| 230 return false; |
| 231 c2 = toASCIIUpper(c2); |
| 232 |
| 233 if (c1 < c2) |
| 234 return true; |
| 235 if (c1 > c2) |
| 236 return false; |
204 } | 237 } |
205 | 238 |
206 for (size_t i = 0; i < WTF_ARRAY_LENGTH(operationParamsMappings); ++i) { | 239 return false; |
207 const OperationParamsMapping& mapping = operationParamsMappings[i]; | 240 } |
208 m_algorithms[mapping.algorithmId].paramsForOperation[mapping.operation]
= mapping.params; | 241 |
209 } | 242 bool lookupAlgorithmIdByName(const String& algorithmName, blink::WebCryptoAlgori
thmId& id) |
| 243 { |
| 244 const AlgorithmNameMapping* begin = algorithmNameMappings; |
| 245 const AlgorithmNameMapping* end = algorithmNameMappings + WTF_ARRAY_LENGTH(a
lgorithmNameMappings); |
| 246 |
| 247 ASSERT(verifyAlgorithmNameMappings(begin, end)); |
| 248 |
| 249 const AlgorithmNameMapping* it; |
| 250 if (algorithmName.impl()->is8Bit()) |
| 251 it = std::lower_bound(begin, end, algorithmName.impl(), &algorithmNameCo
mparator<LChar>); |
| 252 else |
| 253 it = std::lower_bound(begin, end, algorithmName.impl(), &algorithmNameCo
mparator<UChar>); |
| 254 |
| 255 if (it == end) |
| 256 return false; |
| 257 |
| 258 if (it->algorithmNameLength != algorithmName.length() || !equalIgnoringCase(
algorithmName, it->algorithmName)) |
| 259 return false; |
| 260 |
| 261 id = it->algorithmId; |
| 262 return true; |
| 263 } |
| 264 |
| 265 bool lookupAlgorithmParamsType(blink::WebCryptoAlgorithmId id, AlgorithmOperatio
n op, blink::WebCryptoAlgorithmParamsType& paramsType) |
| 266 { |
| 267 const OperationParamsMapping* begin = operationParamsMappings; |
| 268 const OperationParamsMapping* end = operationParamsMappings + WTF_ARRAY_LENG
TH(operationParamsMappings); |
| 269 |
| 270 ASSERT(isSorted(begin, end)); |
| 271 |
| 272 OperationParamsMapping search = { id, op }; |
| 273 const OperationParamsMapping* it = std::lower_bound(begin, end, search); |
| 274 if (it == end) |
| 275 return false; |
| 276 if (it->algorithmId != id || it->operation != op) |
| 277 return false; |
| 278 paramsType = it->params; |
| 279 return true; |
210 } | 280 } |
211 | 281 |
212 // ErrorContext holds a stack of string literals which describe what was | 282 // ErrorContext holds a stack of string literals which describe what was |
213 // happening at the time the error occurred. This is helpful because | 283 // 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 | 284 // parsing of the algorithm dictionary can be recursive and it is difficult to |
215 // tell what went wrong from a failure alone. | 285 // tell what went wrong from a failure alone. |
216 class ErrorContext { | 286 class ErrorContext { |
217 public: | 287 public: |
218 void add(const char* message) | 288 void add(const char* message) |
219 { | 289 { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 errorDetails = context.toString("Not an object"); | 730 errorDetails = context.toString("Not an object"); |
661 return false; | 731 return false; |
662 } | 732 } |
663 | 733 |
664 String algorithmName; | 734 String algorithmName; |
665 if (!raw.get("name", algorithmName)) { | 735 if (!raw.get("name", algorithmName)) { |
666 errorDetails = context.toString("name", "Missing or not a string"); | 736 errorDetails = context.toString("name", "Missing or not a string"); |
667 return false; | 737 return false; |
668 } | 738 } |
669 | 739 |
670 const AlgorithmInfo* info = AlgorithmRegistry::instance().lookupAlgorithmByN
ame(algorithmName); | 740 blink::WebCryptoAlgorithmId algorithmId; |
671 if (!info) { | 741 if (!lookupAlgorithmIdByName(algorithmName, algorithmId)) { |
672 errorDetails = context.toString("Unrecognized algorithm name"); | 742 errorDetails = context.toString("Unrecognized algorithm name"); |
673 return false; | 743 return false; |
674 } | 744 } |
675 | 745 |
676 context.add(info->algorithmName); | 746 context.add(algorithmIdToName(algorithmId)); |
677 | 747 |
678 if (info->paramsForOperation[op] == UnsupportedOp) { | 748 blink::WebCryptoAlgorithmParamsType paramsType; |
| 749 if (!lookupAlgorithmParamsType(algorithmId, op, paramsType)) { |
679 errorDetails = context.toString("Unsupported operation"); | 750 errorDetails = context.toString("Unsupported operation"); |
680 return false; | 751 return false; |
681 } | 752 } |
682 | 753 |
683 blink::WebCryptoAlgorithmParamsType paramsType = static_cast<blink::WebCrypt
oAlgorithmParamsType>(info->paramsForOperation[op]); | |
684 OwnPtr<blink::WebCryptoAlgorithmParams> params; | 754 OwnPtr<blink::WebCryptoAlgorithmParams> params; |
685 if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) | 755 if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) |
686 return false; | 756 return false; |
687 | 757 |
688 algorithm = blink::WebCryptoAlgorithm(info->algorithmId, params.release()); | 758 algorithm = blink::WebCryptoAlgorithm(algorithmId, params.release()); |
689 return true; | 759 return true; |
690 } | 760 } |
691 | 761 |
692 } // namespace | 762 } // namespace |
693 | 763 |
694 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp
toAlgorithm& algorithm, CryptoResult* result) | 764 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp
toAlgorithm& algorithm, CryptoResult* result) |
695 { | 765 { |
696 String errorDetails; | 766 String errorDetails; |
697 if (!parseAlgorithm(raw, op, algorithm, ErrorContext(), errorDetails)) { | 767 if (!parseAlgorithm(raw, op, algorithm, ErrorContext(), errorDetails)) { |
698 result->completeWithError(errorDetails); | 768 result->completeWithError(errorDetails); |
699 return false; | 769 return false; |
700 } | 770 } |
701 return true; | 771 return true; |
702 } | 772 } |
703 | 773 |
704 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) | 774 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) |
705 { | 775 { |
706 return AlgorithmRegistry::instance().lookupAlgorithmById(id)->algorithmName; | 776 switch (id) { |
| 777 case blink::WebCryptoAlgorithmIdAesCbc: |
| 778 return "AES-CBC"; |
| 779 case blink::WebCryptoAlgorithmIdAesCtr: |
| 780 return "AES-CTR"; |
| 781 case blink::WebCryptoAlgorithmIdAesGcm: |
| 782 return "AES-GCM"; |
| 783 case blink::WebCryptoAlgorithmIdHmac: |
| 784 return "HMAC"; |
| 785 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
| 786 return "RSASSA-PKCS1-v1_5"; |
| 787 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 788 return "RSAES-PKCS1-v1_5"; |
| 789 case blink::WebCryptoAlgorithmIdSha1: |
| 790 return "SHA-1"; |
| 791 case blink::WebCryptoAlgorithmIdSha256: |
| 792 return "SHA-256"; |
| 793 case blink::WebCryptoAlgorithmIdSha384: |
| 794 return "SHA-384"; |
| 795 case blink::WebCryptoAlgorithmIdSha512: |
| 796 return "SHA-512"; |
| 797 case blink::WebCryptoAlgorithmIdAesKw: |
| 798 return "AES-KW"; |
| 799 case blink::WebCryptoAlgorithmIdRsaOaep: |
| 800 return "RSA-OAEP"; |
| 801 } |
| 802 return 0; |
707 } | 803 } |
708 | 804 |
709 } // namespace WebCore | 805 } // namespace WebCore |
OLD | NEW |