2
* Copyright (C) 2018 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
30
#include <JavaScriptCore/ArrayBuffer.h>
31
#include <wtf/Forward.h>
35
class AuthenticatorResponse;
37
struct AuthenticatorResponseData {
38
bool isAuthenticatorAttestationResponse;
40
// AuthenticatorResponse
41
RefPtr<ArrayBuffer> rawId;
46
// AuthenticatorAttestationResponse
47
RefPtr<ArrayBuffer> attestationObject;
49
// AuthenticatorAssertionResponse
50
RefPtr<ArrayBuffer> authenticatorData;
51
RefPtr<ArrayBuffer> signature;
52
RefPtr<ArrayBuffer> userHandle;
54
template<class Encoder> void encode(Encoder&) const;
55
template<class Decoder> static Optional<AuthenticatorResponseData> decode(Decoder&);
58
template<class Encoder>
59
void AuthenticatorResponseData::encode(Encoder& encoder) const
67
encoder << static_cast<uint64_t>(rawId->byteLength());
68
encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(rawId->data()), rawId->byteLength(), 1);
70
encoder << isAuthenticatorAttestationResponse;
72
if (isAuthenticatorAttestationResponse && attestationObject) {
73
encoder << static_cast<uint64_t>(attestationObject->byteLength());
74
encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(attestationObject->data()), attestationObject->byteLength(), 1);
78
if (!authenticatorData || !signature)
80
encoder << static_cast<uint64_t>(authenticatorData->byteLength());
81
encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(authenticatorData->data()), authenticatorData->byteLength(), 1);
82
encoder << static_cast<uint64_t>(signature->byteLength());
83
encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(signature->data()), signature->byteLength(), 1);
85
// Encode AppID before user handle to avoid the userHandle flag.
93
encoder << static_cast<uint64_t>(userHandle->byteLength());
94
encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(userHandle->data()), userHandle->byteLength(), 1);
97
template<class Decoder>
98
Optional<AuthenticatorResponseData> AuthenticatorResponseData::decode(Decoder& decoder)
100
AuthenticatorResponseData result;
102
Optional<bool> isEmpty;
109
Optional<uint64_t> rawIdLength;
110
decoder >> rawIdLength;
114
result.rawId = ArrayBuffer::create(rawIdLength.value(), sizeof(uint8_t));
115
if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.rawId->data()), rawIdLength.value(), 1))
118
Optional<bool> isAuthenticatorAttestationResponse;
119
decoder >> isAuthenticatorAttestationResponse;
120
if (!isAuthenticatorAttestationResponse)
122
result.isAuthenticatorAttestationResponse = isAuthenticatorAttestationResponse.value();
124
if (result.isAuthenticatorAttestationResponse) {
125
Optional<uint64_t> attestationObjectLength;
126
decoder >> attestationObjectLength;
127
if (!attestationObjectLength)
130
result.attestationObject = ArrayBuffer::create(attestationObjectLength.value(), sizeof(uint8_t));
131
if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.attestationObject->data()), attestationObjectLength.value(), 1))
137
Optional<uint64_t> authenticatorDataLength;
138
decoder >> authenticatorDataLength;
139
if (!authenticatorDataLength)
142
result.authenticatorData = ArrayBuffer::create(authenticatorDataLength.value(), sizeof(uint8_t));
143
if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.authenticatorData->data()), authenticatorDataLength.value(), 1))
146
Optional<uint64_t> signatureLength;
147
decoder >> signatureLength;
148
if (!signatureLength)
151
result.signature = ArrayBuffer::create(signatureLength.value(), sizeof(uint8_t));
152
if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.signature->data()), signatureLength.value(), 1))
155
Optional<Optional<bool>> appid;
159
result.appid = WTFMove(*appid);
161
Optional<bool> hasUserHandle;
162
decoder >> hasUserHandle;
168
Optional<uint64_t> userHandleLength;
169
decoder >> userHandleLength;
170
if (!userHandleLength)
173
result.userHandle = ArrayBuffer::create(userHandleLength.value(), sizeof(uint8_t));
174
if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.userHandle->data()), userHandleLength.value(), 1))
180
} // namespace WebCore
182
#endif // ENABLE(WEB_AUTHN)