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