Bug 1816520 - implement getPublicKey and getPublicKeyAlgorithm for AuthenticatorAttestationResponse. r=keeler,webidl,smaug

Differential Revision: https://phabricator.services.mozilla.com/D186375
This commit is contained in:
John Schanck 2023-08-31 18:06:48 +00:00
Родитель 7933f948be
Коммит 539ff71086
6 изменённых файлов: 80 добавлений и 6 удалений

Просмотреть файл

@ -102,4 +102,51 @@ void AuthenticatorAttestationResponse::GetAuthenticatorData(
aValue.set(buffer);
}
void AuthenticatorAttestationResponse::GetPublicKey(
JSContext* aCx, JS::MutableHandle<JSObject*> aValue, ErrorResult& aRv) {
if (!mAttestationObjectParsed) {
nsresult rv = authrs_webauthn_att_obj_constructor(
mAttestationObject, false, getter_AddRefs(mAttestationObjectParsed));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
}
nsTArray<uint8_t> publicKey;
nsresult rv = mAttestationObjectParsed->GetPublicKey(publicKey);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_NOT_AVAILABLE) {
aValue.set(nullptr);
} else {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
}
return;
}
JS::Heap<JSObject*> buffer(
ArrayBuffer::Create(aCx, publicKey.Length(), publicKey.Elements()));
if (!buffer) {
aRv.NoteJSContextException(aCx);
return;
}
aValue.set(buffer);
}
COSEAlgorithmIdentifier AuthenticatorAttestationResponse::GetPublicKeyAlgorithm(
ErrorResult& aRv) {
if (!mAttestationObjectParsed) {
nsresult rv = authrs_webauthn_att_obj_constructor(
mAttestationObject, false, getter_AddRefs(mAttestationObjectParsed));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
}
}
COSEAlgorithmIdentifier alg;
mAttestationObjectParsed->GetPublicKeyAlgorithm(&alg);
return alg;
}
} // namespace mozilla::dom

Просмотреть файл

@ -40,6 +40,11 @@ class AuthenticatorAttestationResponse final : public AuthenticatorResponse {
void GetAuthenticatorData(JSContext* aCx, JS::MutableHandle<JSObject*> aValue,
ErrorResult& aRv);
void GetPublicKey(JSContext* aCx, JS::MutableHandle<JSObject*> aValue,
ErrorResult& aRv);
COSEAlgorithmIdentifier GetPublicKeyAlgorithm(ErrorResult& aRv);
private:
nsTArray<uint8_t> mAttestationObject;
nsCOMPtr<nsIWebAuthnAttObj> mAttestationObjectParsed;

Просмотреть файл

@ -10,6 +10,7 @@ extern crate xpcom;
use authenticator::{
authenticatorservice::{RegisterArgs, SignArgs},
crypto::COSEKeyType,
ctap2::attestation::AttestationObject,
ctap2::commands::get_info::AuthenticatorVersion,
ctap2::server::{
@ -140,6 +141,28 @@ impl WebAuthnAttObj {
// TODO(https://github.com/mozilla/authenticator-rs/issues/302) use to_writer
Ok(self.att_obj.auth_data.to_vec().into())
}
xpcom_method!(get_public_key => GetPublicKey() -> ThinVec<u8>);
fn get_public_key(&self) -> Result<ThinVec<u8>, nsresult> {
let Some(credential_data) = &self.att_obj.auth_data.credential_data else {
return Err(NS_ERROR_FAILURE);
};
// We only support encoding (some) EC2 keys in DER SPKI format.
let COSEKeyType::EC2(ref key) = credential_data.credential_public_key.key else {
return Err(NS_ERROR_NOT_AVAILABLE);
};
Ok(key.der_spki().or(Err(NS_ERROR_NOT_AVAILABLE))?.into())
}
xpcom_method!(get_public_key_algorithm => GetPublicKeyAlgorithm() -> i32);
fn get_public_key_algorithm(&self) -> Result<i32, nsresult> {
if let Some(credential_data) = &self.att_obj.auth_data.credential_data {
// safe to cast to i32 by inspection of defined values
Ok(credential_data.credential_public_key.alg as i32)
} else {
Err(NS_ERROR_FAILURE)
}
}
}
#[xpcom(implement(nsICtapSignResult), atomic)]

Просмотреть файл

@ -139,9 +139,9 @@ interface nsIWebAuthnAttObj : nsISupports {
readonly attribute Array<octet> authenticatorData;
// Bug 1816520
// readonly attribute Array<octet> publicKey
// readonly attribute COSEAlgorithmIdentifier publicKeyAlgorithm;
readonly attribute Array<octet> publicKey;
readonly attribute COSEAlgorithmIdentifier publicKeyAlgorithm;
};
// The nsICtapSignResult interface is used to construct IPDL-defined

Просмотреть файл

@ -35,6 +35,8 @@ interface AuthenticatorResponse {
interface AuthenticatorAttestationResponse : AuthenticatorResponse {
[SameObject, Throws] readonly attribute ArrayBuffer attestationObject;
[Throws] ArrayBuffer getAuthenticatorData();
[Throws] ArrayBuffer? getPublicKey();
[Throws] COSEAlgorithmIdentifier getPublicKeyAlgorithm();
};
[SecureContext, Pref="security.webauth.webauthn",

Просмотреть файл

@ -1,3 +0,0 @@
[createcredential-getpublickey.https.html]
[WebAuthn getPublicKey]
expected: FAIL