Home | History | Annotate | Download | only in webcrypto
      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 
     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 
     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 
     35 const uint8* Uint8VectorStart(const std::vector<uint8>& data) {
     36   if (data.empty())
     37     return NULL;
     38   return &data[0];
     39 }
     40 
     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 
     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.
     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 
     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 
     87 blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
     88   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL);
     89 }
     90 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    191 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
    192     unsigned short key_length_bits) {
    193   return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc,
    194                                   key_length_bits);
    195 }
    196 
    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