Home | History | Annotate | Download | only in platform
      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 #ifndef WebCrypto_h
     32 #define WebCrypto_h
     33 
     34 #include "WebCommon.h"
     35 #include "WebCryptoAlgorithm.h"
     36 #include "WebCryptoKey.h"
     37 #include "WebPrivatePtr.h"
     38 #include "WebString.h"
     39 #include "WebVector.h"
     40 
     41 #if INSIDE_BLINK
     42 namespace WTF { template <typename T> class PassRefPtr; }
     43 #endif
     44 
     45 namespace blink {
     46 
     47 class CryptoResult;
     48 class WebArrayBuffer;
     49 class WebString;
     50 
     51 enum WebCryptoErrorType {
     52     WebCryptoErrorTypeType,
     53     WebCryptoErrorTypeNotSupported,
     54     WebCryptoErrorTypeSyntax,
     55     WebCryptoErrorTypeInvalidState,
     56     WebCryptoErrorTypeInvalidAccess,
     57     WebCryptoErrorTypeUnknown,
     58     WebCryptoErrorTypeData,
     59     WebCryptoErrorTypeOperation,
     60 };
     61 
     62 class WebCryptoResult {
     63 public:
     64     WebCryptoResult(const WebCryptoResult& o)
     65     {
     66         assign(o);
     67     }
     68 
     69     ~WebCryptoResult()
     70     {
     71         reset();
     72     }
     73 
     74     WebCryptoResult& operator=(const WebCryptoResult& o)
     75     {
     76         assign(o);
     77         return *this;
     78     }
     79 
     80     // Note that WebString is NOT safe to pass across threads.
     81     //
     82     // Error details are surfaced in an exception, and MUST NEVER reveal any
     83     // secret information such as bytes of the key or plain text. An
     84     // appropriate error would be something like:
     85     //   "iv must be 16 bytes long".
     86     BLINK_PLATFORM_EXPORT void completeWithError(WebCryptoErrorType, const WebString&);
     87 
     88     // Note that WebArrayBuffer is NOT safe to create from another thread.
     89     BLINK_PLATFORM_EXPORT void completeWithBuffer(const WebArrayBuffer&);
     90     // Makes a copy of the input data given as a pointer and byte length.
     91     BLINK_PLATFORM_EXPORT void completeWithBuffer(const void*, unsigned);
     92     BLINK_PLATFORM_EXPORT void completeWithJson(const char* utf8Data, unsigned length);
     93     BLINK_PLATFORM_EXPORT void completeWithBoolean(bool);
     94     BLINK_PLATFORM_EXPORT void completeWithKey(const WebCryptoKey&);
     95     BLINK_PLATFORM_EXPORT void completeWithKeyPair(const WebCryptoKey& publicKey, const WebCryptoKey& privateKey);
     96 
     97     // Returns true if the underlying operation was cancelled.
     98     // This method can be called from any thread.
     99     BLINK_PLATFORM_EXPORT bool cancelled() const;
    100 
    101 #if INSIDE_BLINK
    102     BLINK_PLATFORM_EXPORT explicit WebCryptoResult(const WTF::PassRefPtr<CryptoResult>&);
    103 #endif
    104 
    105 private:
    106     BLINK_PLATFORM_EXPORT void reset();
    107     BLINK_PLATFORM_EXPORT void assign(const WebCryptoResult&);
    108 
    109     WebPrivatePtr<CryptoResult> m_impl;
    110 };
    111 
    112 class WebCryptoDigestor {
    113 public:
    114     virtual ~WebCryptoDigestor() { }
    115 
    116     // consume() will return |true| on the successful addition of data to the
    117     // partially generated digest. It will return |false| when that fails. After
    118     // a return of |false|, consume() should not be called again (nor should
    119     // finish() be called).
    120     virtual bool consume(const unsigned char* data, unsigned dataSize) { return false; }
    121 
    122     // finish() will return |true| if the digest has been successfully computed
    123     // and put into the result buffer, otherwise it will return |false|. In
    124     // either case, neither finish() nor consume() should be called again after
    125     // a call to finish(). resultData is valid until the WebCrytpoDigestor
    126     // object is destroyed.
    127     virtual bool finish(unsigned char*& resultData, unsigned& resultDataSize) { return false; }
    128 
    129 protected:
    130     WebCryptoDigestor() { }
    131 };
    132 
    133 class WebCrypto {
    134 public:
    135     // WebCrypto is the interface for starting one-shot cryptographic
    136     // operations.
    137     //
    138     // -----------------------
    139     // Completing the request
    140     // -----------------------
    141     //
    142     // Implementations signal completion by calling one of the methods on
    143     // "result". Only a single result/error should be set for the request.
    144     // Different operations expect different result types based on the
    145     // algorithm parameters; see the Web Crypto standard for details.
    146     //
    147     // The result can be set either synchronously while handling the request,
    148     // or asynchronously after the method has returned. When completing
    149     // asynchronously make a copy of the WebCryptoResult and call it from the
    150     // same thread that started the request.
    151     //
    152     // If the request was cancelled it is not necessary for implementations to
    153     // set the result.
    154     //
    155     // -----------------------
    156     // Threading
    157     // -----------------------
    158     //
    159     // The WebCrypto interface will be called from blink threads (main or
    160     // web worker). All communication back to Blink must be on this same thread.
    161     //
    162     // Notably:
    163     //
    164     //   * The WebCryptoResult can be copied between threads, however all
    165     //     methods other than the destructor must be called from the origin
    166     //     Blink thread.
    167     //
    168     //   * WebCryptoKey and WebCryptoAlgorithm ARE threadsafe. They can be
    169     //     safely copied between threads and accessed. Copying is cheap because
    170     //     they are internally reference counted.
    171     //
    172     //   * WebArrayBuffer is NOT threadsafe. It should only be created from the
    173     //     target Blink thread. This means threaded implementations may have to
    174     //     make a copy of the output buffer.
    175     //
    176     // -----------------------
    177     // Inputs
    178     // -----------------------
    179     //
    180     //   * Data buffers are passed as (basePointer, byteLength) pairs.
    181     //     These buffers are only valid during the call itself. Asynchronous
    182     //     implementations wishing to access it after the function returns
    183     //     should make a copy.
    184     //
    185     //   * All WebCryptoKeys are guaranteeed to be !isNull().
    186     //
    187     //   * All WebCryptoAlgorithms are guaranteed to be !isNull()
    188     //
    189     //   * Look to the Web Crypto spec for an explanation of the parameter. The
    190     //     method names here have a 1:1 correspondence with those of
    191     //     crypto.subtle, with the exception of "verify" which is here called
    192     //     "verifySignature".
    193     //
    194     // -----------------------
    195     // Guarantees on input validity
    196     // -----------------------
    197     //
    198     // Implementations MUST carefully sanitize algorithm inputs before using
    199     // them, as they come directly from the user. Few checks have been done on
    200     // algorithm parameters prior to passing to the embedder.
    201     //
    202     // Only the following checks can be assumed as having already passed:
    203     //
    204     //  * The key is extractable when calling into exportKey/wrapKey.
    205     //  * The key usages permit the operation being requested.
    206     //  * The key's algorithm matches that of the requested operation.
    207     //
    208     virtual void encrypt(const WebCryptoAlgorithm&, const WebCryptoKey&, const unsigned char* data, unsigned dataSize, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    209     virtual void decrypt(const WebCryptoAlgorithm&, const WebCryptoKey&, const unsigned char* data, unsigned dataSize, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    210     virtual void sign(const WebCryptoAlgorithm&, const WebCryptoKey&, const unsigned char* data, unsigned dataSize, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    211     virtual void verifySignature(const WebCryptoAlgorithm&, const WebCryptoKey&, const unsigned char* signature, unsigned signatureSize, const unsigned char* data, unsigned dataSize, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    212     virtual void digest(const WebCryptoAlgorithm&, const unsigned char* data, unsigned dataSize, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    213     virtual void generateKey(const WebCryptoAlgorithm&, bool extractable, WebCryptoKeyUsageMask, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    214     virtual void importKey(WebCryptoKeyFormat, const unsigned char* keyData, unsigned keyDataSize, const WebCryptoAlgorithm&, bool extractable, WebCryptoKeyUsageMask, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    215     virtual void exportKey(WebCryptoKeyFormat, const WebCryptoKey&, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    216     virtual void wrapKey(WebCryptoKeyFormat, const WebCryptoKey& key, const WebCryptoKey& wrappingKey, const WebCryptoAlgorithm&, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    217     virtual void unwrapKey(WebCryptoKeyFormat, const unsigned char* wrappedKey, unsigned wrappedKeySize, const WebCryptoKey&, const WebCryptoAlgorithm& unwrapAlgorithm, const WebCryptoAlgorithm& unwrappedKeyAlgorithm, bool extractable, WebCryptoKeyUsageMask, WebCryptoResult result) { result.completeWithError(WebCryptoErrorTypeNotSupported, ""); }
    218 
    219     // This is the exception to the "Completing the request" guarantees
    220     // outlined above. This is useful for Blink internal crypto and is not part
    221     // of the WebCrypto standard. createDigestor must provide the result via
    222     // the WebCryptoDigestor object synchronously. createDigestor may return 0
    223     // if it fails to create a WebCryptoDigestor. If it succeeds, the
    224     // WebCryptoDigestor returned by createDigestor must be freed by the
    225     // caller.
    226     virtual WebCryptoDigestor* createDigestor(WebCryptoAlgorithmId algorithmId) { return 0; }
    227 
    228     // -----------------------
    229     // Structured clone
    230     // -----------------------
    231     //
    232     // deserializeKeyForClone() and serializeKeyForClone() are used for
    233     // implementing structured cloning of WebCryptoKey.
    234     //
    235     // Blink is responsible for saving and restoring all of the attributes of
    236     // WebCryptoKey EXCEPT for the actual key data:
    237     //
    238     // In other words, Blink takes care of serializing:
    239     //   * Key usages
    240     //   * Key extractability
    241     //   * Key algorithm
    242     //   * Key type (public, private, secret)
    243     //
    244     // The embedder is responsible for saving the key data itself.
    245     //
    246     // Visibility of the serialized key data:
    247     //
    248     // The serialized key data will NOT be visible to web pages. So if the
    249     // serialized format were to include key bytes as plain text, this wouldn't
    250     // make it available to web pages.
    251     //
    252     // Longevity of the key data:
    253     //
    254     // The serialized key data is intended to be long lived (years) and MUST
    255     // be using a stable format. For instance a key might be persisted to
    256     // IndexedDB and should be able to be deserialized correctly in the
    257     // future.
    258     //
    259     // Error handling and asynchronous completion:
    260     //
    261     // Serialization/deserialization must complete synchronously, and will
    262     // block the JavaScript thread.
    263     //
    264     // The only reasons to fail serialization/deserialization are:
    265     //   * Key serialization not yet implemented
    266     //   * The bytes to deserialize were corrupted
    267 
    268     // Creates a new key given key data which was written using
    269     // serializeKeyForClone(). Returns true on success.
    270     virtual bool deserializeKeyForClone(const WebCryptoKeyAlgorithm&, WebCryptoKeyType, bool extractable, WebCryptoKeyUsageMask, const unsigned char* keyData, unsigned keyDataSize, WebCryptoKey&) { return false; }
    271 
    272     // Writes the key data into the given WebVector.
    273     // Returns true on success.
    274     virtual bool serializeKeyForClone(const WebCryptoKey&, WebVector<unsigned char>&) { return false; }
    275 
    276 protected:
    277     virtual ~WebCrypto() { }
    278 };
    279 
    280 } // namespace blink
    281 
    282 #endif
    283