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.
5 #include "content/renderer/webcrypto/webcrypto_util.h"
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"
18 bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id
) {
19 return alg_id
== blink::WebCryptoAlgorithmIdSha1
||
20 alg_id
== blink::WebCryptoAlgorithmIdSha224
||
21 alg_id
== blink::WebCryptoAlgorithmIdSha256
||
22 alg_id
== blink::WebCryptoAlgorithmIdSha384
||
23 alg_id
== blink::WebCryptoAlgorithmIdSha512
;
28 const uint8
* Uint8VectorStart(const std::vector
<uint8
>& data
) {
34 void ShrinkBuffer(blink::WebArrayBuffer
* buffer
, unsigned new_size
) {
35 DCHECK_LE(new_size
, buffer
->byteLength());
37 if (new_size
== buffer
->byteLength())
40 blink::WebArrayBuffer new_buffer
= blink::WebArrayBuffer::create(new_size
, 1);
41 DCHECK(!new_buffer
.isNull());
42 memcpy(new_buffer
.data(), buffer
->data(), new_size
);
46 blink::WebArrayBuffer
CreateArrayBuffer(const uint8
* data
, unsigned data_size
) {
47 blink::WebArrayBuffer buffer
= blink::WebArrayBuffer::create(data_size
, 1);
48 DCHECK(!buffer
.isNull());
49 if (data_size
) // data_size == 0 might mean the data pointer is invalid
50 memcpy(buffer
.data(), data
, data_size
);
54 // This function decodes unpadded 'base64url' encoded data, as described in
55 // RFC4648 (http://www.ietf.org/rfc/rfc4648.txt) Section 5. To do this, first
56 // change the incoming data to 'base64' encoding by applying the appropriate
57 // transformation including adding padding if required, and then call a base64
59 bool Base64DecodeUrlSafe(const std::string
& input
, std::string
* output
) {
60 std::string
base64EncodedText(input
);
61 std::replace(base64EncodedText
.begin(), base64EncodedText
.end(), '-', '+');
62 std::replace(base64EncodedText
.begin(), base64EncodedText
.end(), '_', '/');
63 base64EncodedText
.append((4 - base64EncodedText
.size() % 4) % 4, '=');
64 return base::Base64Decode(base64EncodedText
, output
);
67 blink::WebCryptoAlgorithm
GetInnerHashAlgorithm(
68 const blink::WebCryptoAlgorithm
& algorithm
) {
69 if (algorithm
.hmacParams())
70 return algorithm
.hmacParams()->hash();
71 if (algorithm
.hmacKeyParams())
72 return algorithm
.hmacKeyParams()->hash();
73 if (algorithm
.rsaSsaParams())
74 return algorithm
.rsaSsaParams()->hash();
75 if (algorithm
.rsaOaepParams())
76 return algorithm
.rsaOaepParams()->hash();
77 return blink::WebCryptoAlgorithm::createNull();
80 blink::WebCryptoAlgorithm
CreateAlgorithm(blink::WebCryptoAlgorithmId id
) {
81 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id
, NULL
);
84 blink::WebCryptoAlgorithm
CreateHmacAlgorithmByHashId(
85 blink::WebCryptoAlgorithmId hash_id
) {
86 DCHECK(IsHashAlgorithm(hash_id
));
87 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
88 blink::WebCryptoAlgorithmIdHmac
,
89 new blink::WebCryptoHmacParams(CreateAlgorithm(hash_id
)));
92 blink::WebCryptoAlgorithm
CreateHmacKeyGenAlgorithm(
93 blink::WebCryptoAlgorithmId hash_id
,
94 unsigned key_length_bytes
) {
95 DCHECK(IsHashAlgorithm(hash_id
));
96 // key_length_bytes == 0 means unspecified
97 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
98 blink::WebCryptoAlgorithmIdHmac
,
99 new blink::WebCryptoHmacKeyParams(
100 CreateAlgorithm(hash_id
), (key_length_bytes
!= 0), key_length_bytes
));
103 blink::WebCryptoAlgorithm
CreateRsaSsaAlgorithm(
104 blink::WebCryptoAlgorithmId hash_id
) {
105 DCHECK(IsHashAlgorithm(hash_id
));
106 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
107 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5
,
108 new blink::WebCryptoRsaSsaParams(CreateAlgorithm(hash_id
)));
111 blink::WebCryptoAlgorithm
CreateRsaOaepAlgorithm(
112 blink::WebCryptoAlgorithmId hash_id
) {
113 DCHECK(IsHashAlgorithm(hash_id
));
114 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
115 blink::WebCryptoAlgorithmIdRsaOaep
,
116 new blink::WebCryptoRsaOaepParams(
117 CreateAlgorithm(hash_id
), false, NULL
, 0));
120 blink::WebCryptoAlgorithm
CreateRsaKeyGenAlgorithm(
121 blink::WebCryptoAlgorithmId algorithm_id
,
122 unsigned modulus_length
,
123 const std::vector
<uint8
>& public_exponent
) {
124 DCHECK(algorithm_id
== blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5
||
125 algorithm_id
== blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5
||
126 algorithm_id
== blink::WebCryptoAlgorithmIdRsaOaep
);
127 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
129 new blink::WebCryptoRsaKeyGenParams(
131 webcrypto::Uint8VectorStart(public_exponent
),
132 public_exponent
.size()));
135 blink::WebCryptoAlgorithm
CreateAesCbcAlgorithm(const std::vector
<uint8
>& iv
) {
136 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
137 blink::WebCryptoAlgorithmIdAesCbc
,
138 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv
), iv
.size()));
141 blink::WebCryptoAlgorithm
CreateAesGcmAlgorithm(
142 const std::vector
<uint8
>& iv
,
143 const std::vector
<uint8
>& additional_data
,
144 uint8 tag_length_bytes
) {
145 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
146 blink::WebCryptoAlgorithmIdAesCbc
,
147 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv
),
149 additional_data
.size() != 0,
150 Uint8VectorStart(additional_data
),
151 additional_data
.size(),
152 tag_length_bytes
!= 0,
156 unsigned int ShaBlockSizeBytes(blink::WebCryptoAlgorithmId hash_id
) {
158 case blink::WebCryptoAlgorithmIdSha1
:
159 case blink::WebCryptoAlgorithmIdSha224
:
160 case blink::WebCryptoAlgorithmIdSha256
:
162 case blink::WebCryptoAlgorithmIdSha384
:
163 case blink::WebCryptoAlgorithmIdSha512
:
171 } // namespace webcrypto
173 } // namespace content