Skip to content
Permalink
Browse files
[WebAuthn] CBOR encoded extensions not passed along during assertions
https://bugs.webkit.org/show_bug.cgi?id=242913
rdar://96912101

Reviewed by Chris Dumez.

* Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
(+[_WKWebAuthenticationPanel convertToCoreRequestOptionsWithOptions:]):
* Source/WTF/wtf/cocoa/SpanCocoa.h:
(WTF::asUInt8Span):
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp:
(WebCore::AuthenticationExtensionsClientInputs::fromCBOR):
* Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h:
* Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
(+[_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:]):
(+[_WKWebAuthenticationPanel convertToCoreRequestOptionsWithOptions:]):
Pass along CBOR encoded extension to ASC, use span to avoid copy. Rest of callsites to be fixed in
https://bugs.webkit.org/show_bug.cgi?id=242919.

Canonical link: https://commits.webkit.org/252626@main
  • Loading branch information
pascoej committed Jul 20, 2022
1 parent 0915e75 commit c93cca1a0e69b96291e37540a6b2e69468d09760
Showing 6 changed files with 20 additions and 10 deletions.
@@ -41,6 +41,12 @@ inline Span<const std::byte> asBytes(const RetainPtr<NSData>& data)
return asBytes(data.get());
}

inline Span<const uint8_t> asUInt8Span(NSData* data)
{
return { reinterpret_cast<const uint8_t*>(data.bytes), data.length };
}

}

using WTF::asBytes;
using WTF::asUInt8Span;
@@ -33,7 +33,7 @@

namespace WebCore {

std::optional<AuthenticationExtensionsClientInputs> AuthenticationExtensionsClientInputs::fromCBOR(const Vector<uint8_t>& buffer)
std::optional<AuthenticationExtensionsClientInputs> AuthenticationExtensionsClientInputs::fromCBOR(Span<const uint8_t> buffer)
{
std::optional<cbor::CBORValue> decodedValue = cbor::CBORReader::read(buffer);
if (!decodedValue || !decodedValue->isMap())
@@ -40,7 +40,7 @@ struct AuthenticationExtensionsClientInputs {
template<class Decoder> static std::optional<AuthenticationExtensionsClientInputs> decode(Decoder&);

WEBCORE_EXPORT Vector<uint8_t> toCBOR() const;
WEBCORE_EXPORT static std::optional<AuthenticationExtensionsClientInputs> fromCBOR(const Vector<uint8_t>&);
WEBCORE_EXPORT static std::optional<AuthenticationExtensionsClientInputs> fromCBOR(Span<const uint8_t>);
};

template<class Encoder>
@@ -68,7 +68,7 @@ const char kOutOfRangeIntegerValue[] = "Integer values must be between INT64_MIN

} // namespace

CBORReader::CBORReader(Bytes::const_iterator it, Bytes::const_iterator end)
CBORReader::CBORReader(Bytes::iterator it, Bytes::iterator end)
: m_it(it)
, m_end(end)
, m_errorCode(DecoderError::CBORNoError)
@@ -239,7 +239,7 @@ std::optional<CBORValue> CBORReader::readBytes(uint64_t numBytes)
return std::nullopt;
}

Bytes cborByteString;
Vector<uint8_t> cborByteString;
ASSERT(numBytes <= std::numeric_limits<size_t>::max());
cborByteString.append(m_it, static_cast<size_t>(numBytes));
m_it += numBytes;
@@ -72,7 +72,7 @@ namespace cbor {
class CBORReader {
WTF_MAKE_NONCOPYABLE(CBORReader);
public:
using Bytes = Vector<uint8_t>;
using Bytes = Span<const uint8_t>;

enum class DecoderError {
CBORNoError = 0,
@@ -107,7 +107,7 @@ class CBORReader {
static const char* errorCodeToString(DecoderError errorCode);

private:
CBORReader(Bytes::const_iterator, const Bytes::const_iterator);
CBORReader(Bytes::iterator, const Bytes::iterator);
std::optional<CBORValue> decodeCBOR(int maxNestingLevel);
std::optional<CBORValue> decodeValueToNegative(uint64_t value);
std::optional<CBORValue> decodeValueToUnsigned(uint64_t value);
@@ -126,8 +126,8 @@ class CBORReader {

DecoderError getErrorCode();

Bytes::const_iterator m_it;
const Bytes::const_iterator m_end;
Bytes::iterator m_it;
const Bytes::iterator m_end;
DecoderError m_errorCode;
};

@@ -62,6 +62,7 @@
#import <pal/crypto/CryptoDigest.h>
#import <wtf/BlockPtr.h>
#import <wtf/RetainPtr.h>
#import <wtf/cocoa/SpanCocoa.h>
#import <wtf/cocoa/TypeCastsCocoa.h>
#import <wtf/cocoa/VectorCocoa.h>
#import <wtf/text/Base64.h>
@@ -932,7 +933,7 @@ - (void)cancel
result.authenticatorSelection = authenticatorSelectionCriteria(options.authenticatorSelection);
result.attestationString = toString(attestationConveyancePreference(options.attestation));
if (options.extensionsCBOR)
result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(vectorFromNSData(options.extensionsCBOR));
result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(asUInt8Span(options.extensionsCBOR));
else
result.extensions = authenticationExtensionsClientInputs(options.extensions);
#endif
@@ -1017,7 +1018,10 @@ - (void)makeCredentialWithClientDataHash:(NSData *)clientDataHash options:(_WKPu
result.userVerificationString = toString(userVerification(options.userVerification));
if (auto attachment = authenticatorAttachment(options.authenticatorAttachment))
result.authenticatorAttachmentString = toString(*attachment);
result.extensions = authenticationExtensionsClientInputs(options.extensions);
if (options.extensionsCBOR)
result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(asUInt8Span(options.extensionsCBOR));
else
result.extensions = authenticationExtensionsClientInputs(options.extensions);
#endif

return result;

0 comments on commit c93cca1

Please sign in to comment.