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 "WebCryptoKey.h"
36#include "WebPrivatePtr.h"
37
38namespace WebKit {
39
40class WebArrayBuffer;
41class WebCryptoKeyOperation;
42class WebCryptoKeyOperationResult;
43class WebCryptoOperation;
44class WebCryptoOperationResult;
45
46class WebCrypto {
47public:
48    // FIXME: Deprecated, delete once chromium side is updated.
49    virtual WebCryptoOperation* digest(const WebCryptoAlgorithm&) { WEBKIT_ASSERT_NOT_REACHED(); return 0; }
50
51    // The following methods begin an asynchronous multi-part cryptographic
52    // operation.
53    //
54    // Let the WebCryptoOperationResult& be called "result".
55    //
56    // Before returning, implementations can either:
57    //
58    // * Synchronously fail initialization by calling:
59    //   result.initializationFailed(errorDetails)
60    //
61    // OR
62    //
63    // * Create a new WebCryptoOperation* and return it by calling:
64    //   result.initializationSucceeded(cryptoOperation)
65    //
66    // If initialization succeeds, then Blink will subsequently call
67    // methods on cryptoOperation:
68    //
69    //   - cryptoOperation->process() to feed it data
70    //   - cryptoOperation->finish() to indicate there is no more data
71    //   - cryptoOperation->abort() to cancel.
72    //
73    // The embedder may call result.completeWithXXX() at any time while the
74    // cryptoOperation is "in progress" (can copy the initial "result" object).
75    // Typically completion is set once cryptoOperation->finish() is called,
76    // however it can also be called during cryptoOperation->process() (for
77    // instance to set an error).
78    //
79    // The cryptoOperation pointer MUST remain valid while it is "in progress".
80    // The cryptoOperation is said to be "in progress" from the time after
81    // result->initializationSucceded() has been called, up until either:
82    //
83    //   - Blink calls cryptoOperation->abort()
84    //   OR
85    //   - Embedder calls result.completeWithXXX()
86    //
87    // Once the cryptoOperation is no longer "in progress" the embedder is
88    // responsible for freeing the cryptoOperation.
89    virtual void encrypt(const WebCryptoAlgorithm&, const WebCryptoKey&, WebCryptoOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
90    virtual void decrypt(const WebCryptoAlgorithm&, const WebCryptoKey&, WebCryptoOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
91    virtual void sign(const WebCryptoAlgorithm&, const WebCryptoKey&, WebCryptoOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
92    virtual void verifySignature(const WebCryptoAlgorithm&, const WebCryptoKey&, const unsigned char* signature, size_t, WebCryptoOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
93    virtual void digest(const WebCryptoAlgorithm&, WebCryptoOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
94
95    // The following methods begin an asynchronous single-part key operation.
96    //
97    // Let the WebCryptoKeyOperationResult& be called "result".
98    //
99    // Before returning, implementations can either:
100    //
101    // (a) Synchronously fail initialization by calling:
102    //     result.initializationFailed(errorDetails)
103    //     (this results in throwing a Javascript exception)
104    //
105    // (b) Synchronously complete the request (success or error) by calling:
106    //     result.completeWithXXX()
107    //
108    // (c) Defer completion by calling
109    //     result.initializationSucceeded(keyOperation)
110    //
111    // If asynchronous completion (c) was chosen, then the embedder can notify
112    // completion after returning by calling result.completeWithXXX() (can make
113    // a copy of "result").
114    //
115    // The keyOperation pointer MUST remain valid while it is "in progress".
116    // The keyOperation is said to be "in progress" from the time after
117    // result->initializationSucceded() has been called, up until either:
118    //
119    //   - Blink calls keyOperation->abort()
120    //   OR
121    //   - Embedder calls result.completeWithXXX()
122    //
123    // Once the keyOperation is no longer "in progress" the embedder is
124    // responsible for freeing the cryptoOperation.
125    virtual void generateKey(const WebCryptoAlgorithm&, bool extractable, WebCryptoKeyUsageMask, WebCryptoKeyOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
126    virtual void importKey(WebCryptoKeyFormat, const unsigned char* keyData, size_t keyDataSize, const WebCryptoAlgorithm&, bool extractable, WebCryptoKeyUsageMask, WebCryptoKeyOperationResult&) { WEBKIT_ASSERT_NOT_REACHED(); }
127
128protected:
129    virtual ~WebCrypto() { }
130};
131
132class WebCryptoOperation {
133public:
134    // Feeds data (bytes, size) to the operation.
135    //   - |bytes| may be 0 if |size| is 0
136    //   - |bytes| is valid only until process() returns
137    //   - process() will not be called after abort() or finish()
138    virtual void process(const unsigned char*, size_t) = 0;
139
140    // Cancels the in-progress operation.
141    //   * Implementations should delete |this| after aborting.
142    virtual void abort() = 0;
143
144    // Indicates that there is no more data to receive.
145    virtual void finish() = 0;
146
147protected:
148    virtual ~WebCryptoOperation() { }
149};
150
151// Can be implemented by embedder for unit-testing.
152class WebCryptoOperationResultPrivate {
153public:
154    virtual ~WebCryptoOperationResultPrivate() { }
155
156    virtual void initializationFailed() = 0;
157    virtual void initializationSucceeded(WebCryptoOperation*) = 0;
158    virtual void completeWithError() = 0;
159    virtual void completeWithArrayBuffer(const WebArrayBuffer&) = 0;
160    virtual void completeWithBoolean(bool) = 0;
161
162    virtual void ref() = 0;
163    virtual void deref() = 0;
164};
165
166// FIXME: Add error types.
167class WebCryptoOperationResult {
168public:
169    explicit WebCryptoOperationResult(WebCryptoOperationResultPrivate* impl)
170    {
171        assign(impl);
172    }
173
174    ~WebCryptoOperationResult() { reset(); }
175
176    WebCryptoOperationResult(const WebCryptoOperationResult& o)
177    {
178        assign(o);
179    }
180
181    WebCryptoOperationResult& operator=(const WebCryptoOperationResult& o)
182    {
183        assign(o);
184        return *this;
185    }
186
187    WEBKIT_EXPORT void initializationFailed();
188    WEBKIT_EXPORT void initializationSucceeded(WebCryptoOperation*);
189    WEBKIT_EXPORT void completeWithError();
190    WEBKIT_EXPORT void completeWithArrayBuffer(const WebArrayBuffer&);
191    WEBKIT_EXPORT void completeWithBoolean(bool);
192
193private:
194    WEBKIT_EXPORT void reset();
195    WEBKIT_EXPORT void assign(const WebCryptoOperationResult&);
196    WEBKIT_EXPORT void assign(WebCryptoOperationResultPrivate*);
197
198    WebPrivatePtr<WebCryptoOperationResultPrivate> m_impl;
199};
200
201class WebCryptoKeyOperation {
202public:
203    // Cancels the in-progress operation.
204    //   * Implementations should delete |this| after aborting.
205    virtual void abort() = 0;
206
207protected:
208    virtual ~WebCryptoKeyOperation() { }
209};
210
211// Can be implemented by embedder for unit-testing.
212class WebCryptoKeyOperationResultPrivate {
213public:
214    virtual ~WebCryptoKeyOperationResultPrivate() { }
215
216    virtual void initializationFailed() = 0;
217    virtual void initializationSucceeded(WebCryptoKeyOperation*) = 0;
218    virtual void completeWithError() = 0;
219    virtual void completeWithKey(const WebCryptoKey&) = 0;
220
221    virtual void ref() = 0;
222    virtual void deref() = 0;
223};
224
225class WebCryptoKeyOperationResult {
226public:
227    explicit WebCryptoKeyOperationResult(WebCryptoKeyOperationResultPrivate* impl)
228    {
229        assign(impl);
230    }
231
232    ~WebCryptoKeyOperationResult() { reset(); }
233
234    WebCryptoKeyOperationResult(const WebCryptoKeyOperationResult& o)
235    {
236        assign(o);
237    }
238
239    WebCryptoKeyOperationResult& operator=(const WebCryptoKeyOperationResult& o)
240    {
241        assign(o);
242        return *this;
243    }
244
245    WEBKIT_EXPORT void initializationFailed();
246    WEBKIT_EXPORT void initializationSucceeded(WebCryptoKeyOperation*);
247
248    WEBKIT_EXPORT void completeWithError();
249    WEBKIT_EXPORT void completeWithKey(const WebCryptoKey&);
250
251private:
252    WEBKIT_EXPORT void reset();
253    WEBKIT_EXPORT void assign(const WebCryptoKeyOperationResult&);
254    WEBKIT_EXPORT void assign(WebCryptoKeyOperationResultPrivate*);
255
256    WebPrivatePtr<WebCryptoKeyOperationResultPrivate> m_impl;
257};
258
259} // namespace WebKit
260
261#endif
262