Bug 1420763 - encode webauthn keys as a COSE key; r?jcj
webauthn says[1] that public keys are encoded as COSE keys. I find the COSE
RFC quite circuitous in many respects and so any reviews should check whether
they agree with my understanding of what should be in a COSE key.
The webauthn spec says that the key:
“MUST contain the "alg" parameter and MUST NOT contain
any other optional parameters.”
I don't believe that any of the parameters included are optional but, again, I
don't think the RFC is completely clear.
[1] https://www.w3.org/TR/webauthn/#sec-attested-credential-data
MozReview-Commit-ID: 9cXTv5zGl9v
--- a/dom/webauthn/WebAuthnCBORUtil.cpp
+++ b/dom/webauthn/WebAuthnCBORUtil.cpp
@@ -16,36 +16,32 @@ CBOREncodePublicKeyObj(const CryptoBuffe
/* out */ CryptoBuffer& aPubKeyObj)
{
mozilla::dom::CryptoBuffer xBuf, yBuf;
nsresult rv = U2FDecomposeECKey(aPubKeyBuf, xBuf, yBuf);
if (NS_FAILED(rv)) {
return rv;
}
- /*
- Public Key Object, encoded in CBOR (description is CDDL)
-
- pubKey = $pubKeyFmt
-
- pubKeyFmt /= eccPubKey
- eccPubKey = { alg: eccAlgName, x: biguint, y: biguint }
- eccAlgName = "ES256" / "ES384" / "ES512"
- */
+ // COSE_Key object. See https://tools.ietf.org/html/rfc8152#section-7
cbor::output_dynamic cborPubKeyOut;
cbor::encoder encoder(cborPubKeyOut);
- encoder.write_map(3);
+ encoder.write_map(5);
{
- encoder.write_string("alg");
- encoder.write_string(JWK_ALG_ECDSA_P_256); // Always ES256 for U2F
+ encoder.write_int(1); // kty
+ encoder.write_int(2); // EC2
+ encoder.write_int(3); // alg
+ encoder.write_int(-7); // ES256
- encoder.write_string("x");
+ // 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_string("y");
+ 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;
}