diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/webauthn/WebAuthnCBORUtil.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/webauthn/WebAuthnCBORUtil.cpp')
-rw-r--r-- | dom/webauthn/WebAuthnCBORUtil.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/dom/webauthn/WebAuthnCBORUtil.cpp b/dom/webauthn/WebAuthnCBORUtil.cpp new file mode 100644 index 0000000000..51255e80d8 --- /dev/null +++ b/dom/webauthn/WebAuthnCBORUtil.cpp @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "cbor-cpp/src/cbor.h" +#include "mozilla/dom/WebAuthnCBORUtil.h" +#include "mozilla/dom/WebAuthnUtil.h" + +namespace mozilla::dom { + +nsresult CBOREncodePublicKeyObj(const CryptoBuffer& aPubKeyBuf, + /* out */ CryptoBuffer& aPubKeyObj) { + mozilla::dom::CryptoBuffer xBuf, yBuf; + nsresult rv = U2FDecomposeECKey(aPubKeyBuf, xBuf, yBuf); + if (NS_FAILED(rv)) { + return rv; + } + + // COSE_Key object. See https://tools.ietf.org/html/rfc8152#section-7 + cbor::output_dynamic cborPubKeyOut; + cbor::encoder encoder(cborPubKeyOut); + encoder.write_map(5); + { + encoder.write_int(1); // kty + encoder.write_int(2); // EC2 + encoder.write_int(3); // alg + encoder.write_int(-7); // ES256 + + // See https://tools.ietf.org/html/rfc8152#section-13.1 + encoder.write_int(-1); // crv + encoder.write_int(1); // P-256 + encoder.write_int(-2); // x + encoder.write_bytes(xBuf.Elements(), xBuf.Length()); + encoder.write_int(-3); // y + encoder.write_bytes(yBuf.Elements(), yBuf.Length()); + } + + if (!aPubKeyObj.Assign(cborPubKeyOut.data(), cborPubKeyOut.size())) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsresult CBOREncodeFidoU2FAttestationObj( + const CryptoBuffer& aAuthDataBuf, const CryptoBuffer& aAttestationCertBuf, + const CryptoBuffer& aSignatureBuf, + /* out */ CryptoBuffer& aAttestationObj) { + /* + Attestation Object, encoded in CBOR (description is CDDL) + + attObj = { + authData: bytes, + $$attStmtType + } + $$attStmtType //= ( + fmt: "fido-u2f", + attStmt: u2fStmtFormat + ) + u2fStmtFormat = { + x5c: [ attestnCert: bytes, * (caCert: bytes) ], + sig: bytes + } + */ + cbor::output_dynamic cborAttOut; + cbor::encoder encoder(cborAttOut); + encoder.write_map(3); + { + encoder.write_string("fmt"); + encoder.write_string("fido-u2f"); + + encoder.write_string("attStmt"); + encoder.write_map(2); + { + encoder.write_string("sig"); + encoder.write_bytes(aSignatureBuf.Elements(), aSignatureBuf.Length()); + + encoder.write_string("x5c"); + // U2F wire protocol can only deliver 1 certificate, so it's never a chain + encoder.write_array(1); + encoder.write_bytes(aAttestationCertBuf.Elements(), + aAttestationCertBuf.Length()); + } + + encoder.write_string("authData"); + encoder.write_bytes(aAuthDataBuf.Elements(), aAuthDataBuf.Length()); + } + + if (!aAttestationObj.Assign(cborAttOut.data(), cborAttOut.size())) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsresult CBOREncodeNoneAttestationObj(const CryptoBuffer& aAuthDataBuf, + /* out */ CryptoBuffer& aAttestationObj) { + /* + Attestation Object, encoded in CBOR (description is CDDL) + + $$attStmtType //= ( + fmt: "none", + attStmt: emptyMap + ) + + emptyMap = {} + */ + cbor::output_dynamic cborAttOut; + cbor::encoder encoder(cborAttOut); + encoder.write_map(3); + { + encoder.write_string("fmt"); + encoder.write_string("none"); + + encoder.write_string("attStmt"); + encoder.write_map(0); + + encoder.write_string("authData"); + encoder.write_bytes(aAuthDataBuf.Elements(), aAuthDataBuf.Length()); + } + + if (!aAttestationObj.Assign(cborAttOut.data(), cborAttOut.size())) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +} // namespace mozilla::dom |