mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
4c6fab9bac
Summary: Always replace attestation statements with a "none" attestation. Bug 1430150 will introduce a prompt that asks the user for permission whenever the RP requests "direct" attestation. Only if the user opts in we will forward the attestation statement with the token's certificate and signature. Reviewers: jcj Reviewed By: jcj Bug #: 1416056 Differential Revision: https://phabricator.services.mozilla.com/D567
136 lines
3.8 KiB
C++
136 lines
3.8 KiB
C++
/* -*- 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 {
|
|
namespace 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;
|
|
}
|
|
|
|
}
|
|
}
|