1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "cbor-cpp/src/cbor.h"
8 #include "mozilla/dom/WebAuthnCBORUtil.h"
9 #include "mozilla/dom/WebAuthnUtil.h"
11 namespace mozilla::dom
{
13 nsresult
CBOREncodePublicKeyObj(const CryptoBuffer
& aPubKeyBuf
,
14 /* out */ CryptoBuffer
& aPubKeyObj
) {
15 mozilla::dom::CryptoBuffer xBuf
, yBuf
;
16 nsresult rv
= U2FDecomposeECKey(aPubKeyBuf
, xBuf
, yBuf
);
21 // COSE_Key object. See https://tools.ietf.org/html/rfc8152#section-7
22 cbor::output_dynamic cborPubKeyOut
;
23 cbor::encoder
encoder(cborPubKeyOut
);
26 encoder
.write_int(1); // kty
27 encoder
.write_int(2); // EC2
28 encoder
.write_int(3); // alg
29 encoder
.write_int(-7); // ES256
31 // See https://tools.ietf.org/html/rfc8152#section-13.1
32 encoder
.write_int(-1); // crv
33 encoder
.write_int(1); // P-256
34 encoder
.write_int(-2); // x
35 encoder
.write_bytes(xBuf
.Elements(), xBuf
.Length());
36 encoder
.write_int(-3); // y
37 encoder
.write_bytes(yBuf
.Elements(), yBuf
.Length());
40 if (!aPubKeyObj
.Assign(cborPubKeyOut
.data(), cborPubKeyOut
.size())) {
41 return NS_ERROR_OUT_OF_MEMORY
;
46 nsresult
CBOREncodeFidoU2FAttestationObj(
47 const CryptoBuffer
& aAuthDataBuf
, const CryptoBuffer
& aAttestationCertBuf
,
48 const CryptoBuffer
& aSignatureBuf
,
49 /* out */ CryptoBuffer
& aAttestationObj
) {
51 Attestation Object, encoded in CBOR (description is CDDL)
59 attStmt: u2fStmtFormat
62 x5c: [ attestnCert: bytes, * (caCert: bytes) ],
66 cbor::output_dynamic cborAttOut
;
67 cbor::encoder
encoder(cborAttOut
);
70 encoder
.write_string("fmt");
71 encoder
.write_string("fido-u2f");
73 encoder
.write_string("attStmt");
76 encoder
.write_string("sig");
77 encoder
.write_bytes(aSignatureBuf
.Elements(), aSignatureBuf
.Length());
79 encoder
.write_string("x5c");
80 // U2F wire protocol can only deliver 1 certificate, so it's never a chain
81 encoder
.write_array(1);
82 encoder
.write_bytes(aAttestationCertBuf
.Elements(),
83 aAttestationCertBuf
.Length());
86 encoder
.write_string("authData");
87 encoder
.write_bytes(aAuthDataBuf
.Elements(), aAuthDataBuf
.Length());
90 if (!aAttestationObj
.Assign(cborAttOut
.data(), cborAttOut
.size())) {
91 return NS_ERROR_OUT_OF_MEMORY
;
96 nsresult
CBOREncodeNoneAttestationObj(const CryptoBuffer
& aAuthDataBuf
,
97 /* out */ CryptoBuffer
& aAttestationObj
) {
99 Attestation Object, encoded in CBOR (description is CDDL)
108 cbor::output_dynamic cborAttOut
;
109 cbor::encoder
encoder(cborAttOut
);
110 encoder
.write_map(3);
112 encoder
.write_string("fmt");
113 encoder
.write_string("none");
115 encoder
.write_string("attStmt");
116 encoder
.write_map(0);
118 encoder
.write_string("authData");
119 encoder
.write_bytes(aAuthDataBuf
.Elements(), aAuthDataBuf
.Length());
122 if (!aAttestationObj
.Assign(cborAttOut
.data(), cborAttOut
.size())) {
123 return NS_ERROR_OUT_OF_MEMORY
;
128 } // namespace mozilla::dom