~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#pragma once
 
27
 
 
28
#if ENABLE(WEB_AUTHN)
 
29
 
 
30
#include <JavaScriptCore/ArrayBuffer.h>
 
31
#include <wtf/Forward.h>
 
32
 
 
33
namespace WebCore {
 
34
 
 
35
class AuthenticatorResponse;
 
36
 
 
37
struct AuthenticatorResponseData {
 
38
    bool isAuthenticatorAttestationResponse;
 
39
 
 
40
    // AuthenticatorResponse
 
41
    RefPtr<ArrayBuffer> rawId;
 
42
 
 
43
    // Extensions
 
44
    Optional<bool> appid;
 
45
 
 
46
    // AuthenticatorAttestationResponse
 
47
    RefPtr<ArrayBuffer> attestationObject;
 
48
 
 
49
    // AuthenticatorAssertionResponse
 
50
    RefPtr<ArrayBuffer> authenticatorData;
 
51
    RefPtr<ArrayBuffer> signature;
 
52
    RefPtr<ArrayBuffer> userHandle;
 
53
 
 
54
    template<class Encoder> void encode(Encoder&) const;
 
55
    template<class Decoder> static Optional<AuthenticatorResponseData> decode(Decoder&);
 
56
};
 
57
 
 
58
template<class Encoder>
 
59
void AuthenticatorResponseData::encode(Encoder& encoder) const
 
60
{
 
61
    if (!rawId) {
 
62
        encoder << true;
 
63
        return;
 
64
    }
 
65
    encoder << false;
 
66
 
 
67
    encoder << static_cast<uint64_t>(rawId->byteLength());
 
68
    encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(rawId->data()), rawId->byteLength(), 1);
 
69
 
 
70
    encoder << isAuthenticatorAttestationResponse;
 
71
 
 
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);
 
75
        return;
 
76
    }
 
77
 
 
78
    if (!authenticatorData || !signature)
 
79
        return;
 
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);
 
84
 
 
85
    // Encode AppID before user handle to avoid the userHandle flag.
 
86
    encoder << appid;
 
87
 
 
88
    if (!userHandle) {
 
89
        encoder << false;
 
90
        return;
 
91
    }
 
92
    encoder << true;
 
93
    encoder << static_cast<uint64_t>(userHandle->byteLength());
 
94
    encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(userHandle->data()), userHandle->byteLength(), 1);
 
95
}
 
96
 
 
97
template<class Decoder>
 
98
Optional<AuthenticatorResponseData> AuthenticatorResponseData::decode(Decoder& decoder)
 
99
{
 
100
    AuthenticatorResponseData result;
 
101
 
 
102
    Optional<bool> isEmpty;
 
103
    decoder >> isEmpty;
 
104
    if (!isEmpty)
 
105
        return WTF::nullopt;
 
106
    if (isEmpty.value())
 
107
        return result;
 
108
 
 
109
    Optional<uint64_t> rawIdLength;
 
110
    decoder >> rawIdLength;
 
111
    if (!rawIdLength)
 
112
        return WTF::nullopt;
 
113
 
 
114
    result.rawId = ArrayBuffer::create(rawIdLength.value(), sizeof(uint8_t));
 
115
    if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.rawId->data()), rawIdLength.value(), 1))
 
116
        return WTF::nullopt;
 
117
 
 
118
    Optional<bool> isAuthenticatorAttestationResponse;
 
119
    decoder >> isAuthenticatorAttestationResponse;
 
120
    if (!isAuthenticatorAttestationResponse)
 
121
        return WTF::nullopt;
 
122
    result.isAuthenticatorAttestationResponse = isAuthenticatorAttestationResponse.value();
 
123
 
 
124
    if (result.isAuthenticatorAttestationResponse) {
 
125
        Optional<uint64_t> attestationObjectLength;
 
126
        decoder >> attestationObjectLength;
 
127
        if (!attestationObjectLength)
 
128
            return WTF::nullopt;
 
129
 
 
130
        result.attestationObject = ArrayBuffer::create(attestationObjectLength.value(), sizeof(uint8_t));
 
131
        if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.attestationObject->data()), attestationObjectLength.value(), 1))
 
132
            return WTF::nullopt;
 
133
 
 
134
        return result;
 
135
    }
 
136
 
 
137
    Optional<uint64_t> authenticatorDataLength;
 
138
    decoder >> authenticatorDataLength;
 
139
    if (!authenticatorDataLength)
 
140
        return WTF::nullopt;
 
141
 
 
142
    result.authenticatorData = ArrayBuffer::create(authenticatorDataLength.value(), sizeof(uint8_t));
 
143
    if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.authenticatorData->data()), authenticatorDataLength.value(), 1))
 
144
        return WTF::nullopt;
 
145
 
 
146
    Optional<uint64_t> signatureLength;
 
147
    decoder >> signatureLength;
 
148
    if (!signatureLength)
 
149
        return WTF::nullopt;
 
150
 
 
151
    result.signature = ArrayBuffer::create(signatureLength.value(), sizeof(uint8_t));
 
152
    if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.signature->data()), signatureLength.value(), 1))
 
153
        return WTF::nullopt;
 
154
 
 
155
    Optional<Optional<bool>> appid;
 
156
    decoder >> appid;
 
157
    if (!appid)
 
158
        return WTF::nullopt;
 
159
    result.appid = WTFMove(*appid);
 
160
 
 
161
    Optional<bool> hasUserHandle;
 
162
    decoder >> hasUserHandle;
 
163
    if (!hasUserHandle)
 
164
        return WTF::nullopt;
 
165
    if (!*hasUserHandle)
 
166
        return result;
 
167
 
 
168
    Optional<uint64_t> userHandleLength;
 
169
    decoder >> userHandleLength;
 
170
    if (!userHandleLength)
 
171
        return WTF::nullopt;
 
172
 
 
173
    result.userHandle = ArrayBuffer::create(userHandleLength.value(), sizeof(uint8_t));
 
174
    if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.userHandle->data()), userHandleLength.value(), 1))
 
175
        return WTF::nullopt;
 
176
 
 
177
    return result;
 
178
}
 
179
    
 
180
} // namespace WebCore
 
181
 
 
182
#endif // ENABLE(WEB_AUTHN)