Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "modules/crypto/Key.h"
     33 
     34 #include "modules/crypto/Algorithm.h"
     35 
     36 namespace WebCore {
     37 
     38 namespace {
     39 
     40 const char* keyTypeToString(WebKit::WebCryptoKeyType type)
     41 {
     42     switch (type) {
     43     case WebKit::WebCryptoKeyTypeSecret:
     44         return "secret";
     45     case WebKit::WebCryptoKeyTypePublic:
     46         return "public";
     47     case WebKit::WebCryptoKeyTypePrivate:
     48         return "private";
     49     }
     50     ASSERT_NOT_REACHED();
     51     return 0;
     52 }
     53 
     54 struct KeyUsageMapping {
     55     WebKit::WebCryptoKeyUsage value;
     56     const char* const name;
     57 };
     58 
     59 const KeyUsageMapping keyUsageMappings[] = {
     60     { WebKit::WebCryptoKeyUsageEncrypt, "encrypt" },
     61     { WebKit::WebCryptoKeyUsageDecrypt, "decrypt" },
     62     { WebKit::WebCryptoKeyUsageSign, "sign" },
     63     { WebKit::WebCryptoKeyUsageVerify, "verify" },
     64     { WebKit::WebCryptoKeyUsageDeriveKey, "deriveKey" },
     65     { WebKit::WebCryptoKeyUsageWrapKey, "wrapKey" },
     66     { WebKit::WebCryptoKeyUsageUnwrapKey, "unwrapKey" },
     67 };
     68 
     69 COMPILE_ASSERT(WebKit::EndOfWebCryptoKeyUsage == (1 << 6) + 1, update_keyUsageMappings);
     70 
     71 const char* keyUsageToString(WebKit::WebCryptoKeyUsage usage)
     72 {
     73     for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyUsageMappings); ++i) {
     74         if (keyUsageMappings[i].value == usage)
     75             return keyUsageMappings[i].name;
     76     }
     77     ASSERT_NOT_REACHED();
     78     return 0;
     79 }
     80 
     81 WebKit::WebCryptoKeyUsageMask keyUsageStringToMask(const String& usageString)
     82 {
     83     for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyUsageMappings); ++i) {
     84         if (keyUsageMappings[i].name == usageString)
     85             return keyUsageMappings[i].value;
     86     }
     87     return 0;
     88 }
     89 
     90 } // namespace
     91 
     92 Key::~Key()
     93 {
     94 }
     95 
     96 Key::Key(const WebKit::WebCryptoKey& key)
     97     : m_key(key)
     98 {
     99     ScriptWrappable::init(this);
    100 }
    101 
    102 String Key::type() const
    103 {
    104     return keyTypeToString(m_key.type());
    105 }
    106 
    107 bool Key::extractable() const
    108 {
    109     return m_key.extractable();
    110 }
    111 
    112 Algorithm* Key::algorithm()
    113 {
    114     if (!m_algorithm)
    115         m_algorithm = Algorithm::create(m_key.algorithm());
    116     return m_algorithm.get();
    117 }
    118 
    119 // FIXME: This creates a new javascript array each time. What should happen
    120 //        instead is return the same (immutable) array. (Javascript callers can
    121 //        distinguish this by doing an == test on the arrays and seeing they are
    122 //        different).
    123 Vector<String> Key::usages() const
    124 {
    125     Vector<String> result;
    126     for (int i = 0; i < WTF_ARRAY_LENGTH(keyUsageMappings); ++i) {
    127         WebKit::WebCryptoKeyUsage usage = keyUsageMappings[i].value;
    128         if (m_key.usages() & usage)
    129             result.append(keyUsageToString(usage));
    130     }
    131     return result;
    132 }
    133 
    134 bool Key::parseFormat(const String& formatString, WebKit::WebCryptoKeyFormat& format)
    135 {
    136     // There are few enough values that testing serially is fast enough.
    137     if (formatString == "raw") {
    138         format = WebKit::WebCryptoKeyFormatRaw;
    139         return true;
    140     }
    141     if (formatString == "pkcs8") {
    142         format = WebKit::WebCryptoKeyFormatPkcs8;
    143         return true;
    144     }
    145     if (formatString == "spki") {
    146         format = WebKit::WebCryptoKeyFormatSpki;
    147         return true;
    148     }
    149     if (formatString == "jwk") {
    150         format = WebKit::WebCryptoKeyFormatJwk;
    151         return true;
    152     }
    153 
    154     return false;
    155 }
    156 
    157 bool Key::parseUsageMask(const Vector<String>& usages, WebKit::WebCryptoKeyUsageMask& mask)
    158 {
    159     mask = 0;
    160     for (size_t i = 0; i < usages.size(); ++i) {
    161         WebKit::WebCryptoKeyUsageMask usage = keyUsageStringToMask(usages[i]);
    162         if (!usage)
    163             return false;
    164         mask |= usage;
    165     }
    166     return true;
    167 }
    168 
    169 } // namespace WebCore
    170