[WebAuthN] Implement authenticatorMakeCredential
[WebKit-https.git] / Source / WebCore / testing / MockCredentialsMessenger.cpp
1 /*
2  * Copyright (C) 2018 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "MockCredentialsMessenger.h"
28
29 #if ENABLE(WEB_AUTHN)
30
31 #include "Internals.h"
32 #include <wtf/Vector.h>
33
34 namespace WebCore {
35
36 MockCredentialsMessenger::MockCredentialsMessenger(Internals& internals)
37     : m_internals(internals)
38 {
39 }
40
41 MockCredentialsMessenger::~MockCredentialsMessenger()
42 {
43     // Have no effects to original promises. Just to call handlers to avoid any assertion failures.
44     for (auto messageId : m_timeOutMessageIds)
45         exceptionReply(messageId, ExceptionData { NotAllowedError, ASCIILiteral("Operation timed out.") });
46 }
47
48 void MockCredentialsMessenger::setCreationReturnBundle(const BufferSource& credentialId, const BufferSource& attestationObject)
49 {
50     ASSERT(m_credentialId.isEmpty() && m_attestationObject.isEmpty());
51     m_credentialId.append(credentialId.data(), credentialId.length());
52     m_attestationObject.append(attestationObject.data(), attestationObject.length());
53 }
54
55 void MockCredentialsMessenger::setAssertionReturnBundle(const BufferSource& credentialId, const BufferSource& authenticatorData, const BufferSource& signature, const BufferSource& userHandle)
56 {
57     ASSERT(m_credentialId.isEmpty() && m_authenticatorData.isEmpty() && m_signature.isEmpty() && m_userHandle.isEmpty());
58     m_credentialId.append(credentialId.data(), credentialId.length());
59     m_authenticatorData.append(authenticatorData.data(), authenticatorData.length());
60     m_signature.append(signature.data(), signature.length());
61     m_userHandle.append(userHandle.data(), userHandle.length());
62 }
63
64 void MockCredentialsMessenger::ref()
65 {
66     m_internals.ref();
67 }
68
69 void MockCredentialsMessenger::deref()
70 {
71     m_internals.deref();
72 }
73
74 void MockCredentialsMessenger::makeCredential(const Vector<uint8_t>&, const PublicKeyCredentialCreationOptions&, CreationCompletionHandler&& handler)
75 {
76     auto messageId = addCreationCompletionHandler(WTFMove(handler));
77     if (m_didTimeOut) {
78         m_didTimeOut = false;
79         m_timeOutMessageIds.append(messageId);
80         return;
81     }
82     if (m_didUserCancel) {
83         m_didUserCancel = false;
84         exceptionReply(messageId, ExceptionData { NotAllowedError, ASCIILiteral("User cancelled.") });
85         return;
86     }
87     if (!m_credentialId.isEmpty()) {
88         ASSERT(!m_attestationObject.isEmpty());
89         makeCredentialReply(messageId, m_credentialId, m_attestationObject);
90         m_credentialId.clear();
91         m_attestationObject.clear();
92         return;
93     }
94     ASSERT_NOT_REACHED();
95 }
96
97 void MockCredentialsMessenger::getAssertion(const Vector<uint8_t>&, const PublicKeyCredentialRequestOptions&, RequestCompletionHandler&& handler)
98 {
99     auto messageId = addRequestCompletionHandler(WTFMove(handler));
100     if (m_didTimeOut) {
101         m_didTimeOut = false;
102         m_timeOutMessageIds.append(messageId);
103         return;
104     }
105     if (m_didUserCancel) {
106         m_didUserCancel = false;
107         exceptionReply(messageId, ExceptionData { NotAllowedError, ASCIILiteral("User cancelled.") });
108         return;
109     }
110     if (!m_credentialId.isEmpty()) {
111         ASSERT(!m_authenticatorData.isEmpty() && !m_signature.isEmpty() && !m_userHandle.isEmpty());
112         getAssertionReply(messageId, m_credentialId, m_authenticatorData, m_signature, m_userHandle);
113         m_credentialId.clear();
114         m_authenticatorData.clear();
115         m_signature.clear();
116         m_userHandle.clear();
117         return;
118     }
119     ASSERT_NOT_REACHED();
120 }
121
122 void MockCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&& handler)
123 {
124     auto messageId = addQueryCompletionHandler(WTFMove(handler));
125     if (m_didUserVerifyingPlatformAuthenticatorPresent) {
126         isUserVerifyingPlatformAuthenticatorAvailableReply(messageId, true);
127         m_didUserVerifyingPlatformAuthenticatorPresent = false;
128     } else
129         isUserVerifyingPlatformAuthenticatorAvailableReply(messageId, false);
130 }
131
132 void MockCredentialsMessenger::makeCredentialReply(uint64_t messageId, const Vector<uint8_t>& credentialId, const Vector<uint8_t>& attestationObject)
133 {
134     auto handler = takeCreationCompletionHandler(messageId);
135     handler(CreationReturnBundle(ArrayBuffer::create(credentialId.data(), credentialId.size()), ArrayBuffer::create(attestationObject.data(), attestationObject.size())));
136 }
137
138 void MockCredentialsMessenger::getAssertionReply(uint64_t messageId, const Vector<uint8_t>& credentialId, const Vector<uint8_t>& authenticatorData, const Vector<uint8_t>& signature, const Vector<uint8_t>& userHandle)
139 {
140     auto handler = takeRequestCompletionHandler(messageId);
141     handler(AssertionReturnBundle(ArrayBuffer::create(credentialId.data(), credentialId.size()), ArrayBuffer::create(authenticatorData.data(), authenticatorData.size()), ArrayBuffer::create(signature.data(), signature.size()), ArrayBuffer::create(userHandle.data(), userHandle.size())));
142 }
143
144 void MockCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool result)
145 {
146     auto handler = takeQueryCompletionHandler(messageId);
147     handler(result);
148 }
149
150 } // namespace WebCore
151
152 #endif // ENABLE(WEB_AUTHN)