• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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 #include "content/renderer/webcrypto/webcrypto_util.h"
6 
7 #include "base/base64.h"
8 #include "base/logging.h"
9 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
10 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
11 
12 namespace content {
13 
14 namespace webcrypto {
15 
16 namespace {
17 
CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmId aes_alg_id,unsigned short length)18 blink::WebCryptoAlgorithm CreateAesKeyGenAlgorithm(
19     blink::WebCryptoAlgorithmId aes_alg_id,
20     unsigned short length) {
21   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
22       aes_alg_id, new blink::WebCryptoAesKeyGenParams(length));
23 }
24 
IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id)25 bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id) {
26   return alg_id == blink::WebCryptoAlgorithmIdSha1 ||
27          alg_id == blink::WebCryptoAlgorithmIdSha224 ||
28          alg_id == blink::WebCryptoAlgorithmIdSha256 ||
29          alg_id == blink::WebCryptoAlgorithmIdSha384 ||
30          alg_id == blink::WebCryptoAlgorithmIdSha512;
31 }
32 
33 }  // namespace
34 
Uint8VectorStart(const std::vector<uint8> & data)35 const uint8* Uint8VectorStart(const std::vector<uint8>& data) {
36   if (data.empty())
37     return NULL;
38   return &data[0];
39 }
40 
ShrinkBuffer(blink::WebArrayBuffer * buffer,unsigned new_size)41 void ShrinkBuffer(blink::WebArrayBuffer* buffer, unsigned new_size) {
42   DCHECK_LE(new_size, buffer->byteLength());
43 
44   if (new_size == buffer->byteLength())
45     return;
46 
47   blink::WebArrayBuffer new_buffer = blink::WebArrayBuffer::create(new_size, 1);
48   DCHECK(!new_buffer.isNull());
49   memcpy(new_buffer.data(), buffer->data(), new_size);
50   *buffer = new_buffer;
51 }
52 
CreateArrayBuffer(const uint8 * data,unsigned data_size)53 blink::WebArrayBuffer CreateArrayBuffer(const uint8* data, unsigned data_size) {
54   blink::WebArrayBuffer buffer = blink::WebArrayBuffer::create(data_size, 1);
55   DCHECK(!buffer.isNull());
56   if (data_size)  // data_size == 0 might mean the data pointer is invalid
57     memcpy(buffer.data(), data, data_size);
58   return buffer;
59 }
60 
61 // This function decodes unpadded 'base64url' encoded data, as described in
62 // RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5. To do this, first
63 // change the incoming data to 'base64' encoding by applying the appropriate
64 // transformation including adding padding if required, and then call a base64
65 // decoder.
Base64DecodeUrlSafe(const std::string & input,std::string * output)66 bool Base64DecodeUrlSafe(const std::string& input, std::string* output) {
67   std::string base64EncodedText(input);
68   std::replace(base64EncodedText.begin(), base64EncodedText.end(), '-', '+');
69   std::replace(base64EncodedText.begin(), base64EncodedText.end(), '_', '/');
70   base64EncodedText.append((4 - base64EncodedText.size() % 4) % 4, '=');
71   return base::Base64Decode(base64EncodedText, output);
72 }
73 
GetInnerHashAlgorithm(const blink::WebCryptoAlgorithm & algorithm)74 blink::WebCryptoAlgorithm GetInnerHashAlgorithm(
75     const blink::WebCryptoAlgorithm& algorithm) {
76   if (algorithm.hmacParams())
77     return algorithm.hmacParams()->hash();
78   if (algorithm.hmacKeyParams())
79     return algorithm.hmacKeyParams()->hash();
80   if (algorithm.rsaSsaParams())
81     return algorithm.rsaSsaParams()->hash();
82   if (algorithm.rsaOaepParams())
83     return algorithm.rsaOaepParams()->hash();
84   return blink::WebCryptoAlgorithm::createNull();
85 }
86 
CreateAlgorithm(blink::WebCryptoAlgorithmId id)87 blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
88   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL);
89 }
90 
CreateHmacAlgorithmByHashOutputLen(unsigned short hash_output_length_bits)91 blink::WebCryptoAlgorithm CreateHmacAlgorithmByHashOutputLen(
92     unsigned short hash_output_length_bits) {
93   blink::WebCryptoAlgorithmId hash_id;
94   switch (hash_output_length_bits) {
95     case 160:
96       hash_id = blink::WebCryptoAlgorithmIdSha1;
97       break;
98     case 224:
99       hash_id = blink::WebCryptoAlgorithmIdSha224;
100       break;
101     case 256:
102       hash_id = blink::WebCryptoAlgorithmIdSha256;
103       break;
104     case 384:
105       hash_id = blink::WebCryptoAlgorithmIdSha384;
106       break;
107     case 512:
108       hash_id = blink::WebCryptoAlgorithmIdSha512;
109       break;
110     default:
111       NOTREACHED();
112       return blink::WebCryptoAlgorithm::createNull();
113   }
114   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
115       blink::WebCryptoAlgorithmIdHmac,
116       new blink::WebCryptoHmacParams(CreateAlgorithm(hash_id)));
117 }
118 
CreateHmacAlgorithmByHashId(blink::WebCryptoAlgorithmId hash_id)119 blink::WebCryptoAlgorithm CreateHmacAlgorithmByHashId(
120     blink::WebCryptoAlgorithmId hash_id) {
121   DCHECK(IsHashAlgorithm(hash_id));
122   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
123       blink::WebCryptoAlgorithmIdHmac,
124       new blink::WebCryptoHmacParams(CreateAlgorithm(hash_id)));
125 }
126 
CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmId hash_id,unsigned key_length_bytes)127 blink::WebCryptoAlgorithm CreateHmacKeyGenAlgorithm(
128     blink::WebCryptoAlgorithmId hash_id,
129     unsigned key_length_bytes) {
130   DCHECK(IsHashAlgorithm(hash_id));
131   // key_length_bytes == 0 means unspecified
132   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
133       blink::WebCryptoAlgorithmIdHmac,
134       new blink::WebCryptoHmacKeyParams(
135           CreateAlgorithm(hash_id), (key_length_bytes != 0), key_length_bytes));
136 }
137 
CreateRsaSsaAlgorithm(blink::WebCryptoAlgorithmId hash_id)138 blink::WebCryptoAlgorithm CreateRsaSsaAlgorithm(
139     blink::WebCryptoAlgorithmId hash_id) {
140   DCHECK(IsHashAlgorithm(hash_id));
141   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
142       blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
143       new blink::WebCryptoRsaSsaParams(CreateAlgorithm(hash_id)));
144 }
145 
CreateRsaOaepAlgorithm(blink::WebCryptoAlgorithmId hash_id)146 blink::WebCryptoAlgorithm CreateRsaOaepAlgorithm(
147     blink::WebCryptoAlgorithmId hash_id) {
148   DCHECK(IsHashAlgorithm(hash_id));
149   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
150       blink::WebCryptoAlgorithmIdRsaOaep,
151       new blink::WebCryptoRsaOaepParams(
152           CreateAlgorithm(hash_id), false, NULL, 0));
153 }
154 
CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmId algorithm_id,unsigned modulus_length,const std::vector<uint8> & public_exponent)155 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm(
156     blink::WebCryptoAlgorithmId algorithm_id,
157     unsigned modulus_length,
158     const std::vector<uint8>& public_exponent) {
159   DCHECK(algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
160          algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
161          algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep);
162   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
163       algorithm_id,
164       new blink::WebCryptoRsaKeyGenParams(
165           modulus_length,
166           webcrypto::Uint8VectorStart(public_exponent),
167           public_exponent.size()));
168 }
169 
CreateAesCbcAlgorithm(const std::vector<uint8> & iv)170 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(const std::vector<uint8>& iv) {
171   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
172       blink::WebCryptoAlgorithmIdAesCbc,
173       new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size()));
174 }
175 
CreateAesGcmAlgorithm(const std::vector<uint8> & iv,const std::vector<uint8> & additional_data,uint8 tag_length_bytes)176 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
177     const std::vector<uint8>& iv,
178     const std::vector<uint8>& additional_data,
179     uint8 tag_length_bytes) {
180   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
181       blink::WebCryptoAlgorithmIdAesCbc,
182       new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv),
183                                        iv.size(),
184                                        additional_data.size() != 0,
185                                        Uint8VectorStart(additional_data),
186                                        additional_data.size(),
187                                        tag_length_bytes != 0,
188                                        tag_length_bytes));
189 }
190 
CreateAesCbcKeyGenAlgorithm(unsigned short key_length_bits)191 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
192     unsigned short key_length_bits) {
193   return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc,
194                                   key_length_bits);
195 }
196 
CreateAesGcmKeyGenAlgorithm(unsigned short key_length_bits)197 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm(
198     unsigned short key_length_bits) {
199   return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm,
200                                   key_length_bits);
201 }
202 
203 }  // namespace webcrypto
204 
205 }  // namespace content
206