Home | History | Annotate | Download | only in runner
      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 "MockWebCrypto.h"
     32 
     33 #include "public/platform/WebArrayBuffer.h"
     34 #include "public/platform/WebCryptoAlgorithm.h"
     35 #include <string>
     36 #include <string.h>
     37 
     38 using namespace WebKit;
     39 
     40 namespace WebTestRunner {
     41 
     42 namespace {
     43 
     44 enum Operation {
     45     Encrypt,
     46     Decrypt,
     47     Sign,
     48     Verify,
     49     Digest,
     50 };
     51 
     52 class MockCryptoOperation : public WebKit::WebCryptoOperation {
     53 public:
     54     MockCryptoOperation(const WebKit::WebCryptoAlgorithm& algorithm, Operation op, const WebKit::WebCryptoOperationResult& result)
     55         : m_algorithm(algorithm)
     56         , m_operation(op)
     57         , m_result(result) { }
     58 
     59     virtual void process(const unsigned char* bytes, size_t size) OVERRIDE
     60     {
     61         // Don't buffer too much data.
     62         if (m_data.size() + size > 6) {
     63             m_result.completeWithError();
     64             delete this;
     65             return;
     66         }
     67 
     68         if (size)
     69             m_data.append(reinterpret_cast<const char*>(bytes), size);
     70     }
     71 
     72     virtual void abort() OVERRIDE
     73     {
     74         delete this;
     75     }
     76 
     77     virtual void finish() OVERRIDE
     78     {
     79         if (m_algorithm.id() == WebKit::WebCryptoAlgorithmIdSha1 && m_operation == Digest) {
     80             if (m_data.empty()) {
     81                 const unsigned char result[] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09};
     82                 completeWithArrayBuffer(result, sizeof(result));
     83             } else if (m_data == std::string("\x00", 1)) {
     84                 const unsigned char result[] = {0x5b, 0xa9, 0x3c, 0x9d, 0xb0, 0xcf, 0xf9, 0x3f, 0x52, 0xb5, 0x21, 0xd7, 0x42, 0x0e, 0x43, 0xf6, 0xed, 0xa2, 0x78, 0x4f};
     85                 completeWithArrayBuffer(result, sizeof(result));
     86             } else if (m_data == std::string("\x00\x01\x02\x03\x04\x05", 6)) {
     87                 const unsigned char result[] = {0x86, 0x84, 0x60, 0xd9, 0x8d, 0x09, 0xd8, 0xbb, 0xb9, 0x3d, 0x7b, 0x6c, 0xdd, 0x15, 0xcc, 0x7f, 0xbe, 0xc6, 0x76, 0xb9};
     88                 completeWithArrayBuffer(result, sizeof(result));
     89             } else {
     90                 m_result.completeWithError();
     91             }
     92         } else if (m_algorithm.id() == WebKit::WebCryptoAlgorithmIdHmac && m_operation == Sign) {
     93             std::string result = "signed HMAC:" + m_data;
     94             completeWithArrayBuffer(result.data(), result.size());
     95         } else if (m_algorithm.id() == WebKit::WebCryptoAlgorithmIdHmac && m_operation == Verify) {
     96             std::string expectedSignature = "signed HMAC:" + m_data;
     97             m_result.completeWithBoolean(expectedSignature == m_signature);
     98         } else {
     99             m_result.completeWithError();
    100         }
    101         delete this;
    102     }
    103 
    104     void setSignature(const unsigned char* signatureBytes, size_t signatureLength)
    105     {
    106         m_signature.assign(reinterpret_cast<const char*>(signatureBytes), signatureLength);
    107     }
    108 
    109 private:
    110     void completeWithArrayBuffer(const void* data, size_t bytes)
    111     {
    112         WebKit::WebArrayBuffer buffer = WebKit::WebArrayBuffer::create(bytes, 1);
    113         memcpy(buffer.data(), data, bytes);
    114         m_result.completeWithArrayBuffer(buffer);
    115     }
    116 
    117     WebKit::WebCryptoAlgorithm m_algorithm;
    118     Operation m_operation;
    119     WebKit::WebCryptoOperationResult m_result;
    120     std::string m_data;
    121     std::string m_signature;
    122 };
    123 
    124 } // namespace
    125 
    126 MockWebCrypto* MockWebCrypto::get()
    127 {
    128     static MockWebCrypto crypto;
    129     return &crypto;
    130 }
    131 
    132 void MockWebCrypto::encrypt(const WebKit::WebCryptoAlgorithm& algorithm, const WebKit::WebCryptoKey& key, WebKit::WebCryptoOperationResult& result)
    133 {
    134     result.initializationSucceeded(new MockCryptoOperation(algorithm, Encrypt, result));
    135 }
    136 
    137 void MockWebCrypto::decrypt(const WebKit::WebCryptoAlgorithm& algorithm, const WebKit::WebCryptoKey& key, WebKit::WebCryptoOperationResult& result)
    138 {
    139     result.initializationSucceeded(new MockCryptoOperation(algorithm, Decrypt, result));
    140 }
    141 
    142 void MockWebCrypto::sign(const WebKit::WebCryptoAlgorithm& algorithm, const WebKit::WebCryptoKey& key, WebKit::WebCryptoOperationResult& result)
    143 {
    144     result.initializationSucceeded(new MockCryptoOperation(algorithm, Sign, result));
    145 }
    146 
    147 void MockWebCrypto::verifySignature(const WebKit::WebCryptoAlgorithm& algorithm, const WebKit::WebCryptoKey& key, const unsigned char* signature, size_t signatureLength, WebKit::WebCryptoOperationResult& result)
    148 {
    149     MockCryptoOperation* op = new MockCryptoOperation(algorithm, Verify, result);
    150     op->setSignature(signature, signatureLength);
    151     result.initializationSucceeded(op);
    152 }
    153 
    154 void MockWebCrypto::digest(const WebKit::WebCryptoAlgorithm& algorithm, WebKit::WebCryptoOperationResult& result)
    155 {
    156     result.initializationSucceeded(new MockCryptoOperation(algorithm, Digest, result));
    157 }
    158 
    159 void MockWebCrypto::generateKey(const WebKit::WebCryptoAlgorithm& algorithm, bool extractable, WebKit::WebCryptoKeyUsageMask usages, WebKit::WebCryptoKeyOperationResult& result)
    160 {
    161     result.completeWithKey(WebKit::WebCryptoKey::create(0, WebKit::WebCryptoKeyTypePrivate, extractable, algorithm, usages));
    162 }
    163 
    164 void MockWebCrypto::importKey(WebKit::WebCryptoKeyFormat, const unsigned char* keyData, size_t keyDataSize, const WebKit::WebCryptoAlgorithm& algorithm, bool extractable, WebKit::WebCryptoKeyUsageMask usages, WebKit::WebCryptoKeyOperationResult& result)
    165 {
    166     std::string keyDataString(reinterpret_cast<const char*>(keyData), keyDataSize);
    167 
    168     if (keyDataString == "reject") {
    169         result.completeWithError();
    170     } else if (keyDataString == "throw") {
    171         result.initializationFailed();
    172     } else {
    173         WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePrivate;
    174         if (keyDataString == "public")
    175             type = WebKit::WebCryptoKeyTypePublic;
    176         result.completeWithKey(WebKit::WebCryptoKey::create(0, type, extractable, algorithm, usages));
    177     }
    178 }
    179 
    180 } // namespace WebTestRunner
    181