webauthn_rp

WebAuthn RP library.
git clone https://git.philomathiclife.com/repos/webauthn_rp
Log | Files | Refs | README

tests.rs (231588B)


      1 use super::{
      2     super::{
      3         AKP, ALG, AuthenticatorAttachment, EC2, EDDSA, ES256, ES384, Ed25519PubKey, KTY, MLDSA44,
      4         MLDSA65, MLDSA87, MlDsa44PubKey, MlDsa65PubKey, MlDsa87PubKey, OKP, RSA, Registration,
      5         RsaPubKey, UncompressedP256PubKey, UncompressedP384PubKey, cbor,
      6     },
      7     CoseAlgorithmIdentifier,
      8     spki::SubjectPublicKeyInfo as _,
      9 };
     10 use ed25519_dalek::{VerifyingKey, pkcs8::EncodePublicKey as _};
     11 use ml_dsa::{MlDsa44, MlDsa65, MlDsa87, VerifyingKey as MlDsaVerKey};
     12 use p256::{
     13     PublicKey as P256PubKey, Sec1Point as P256Pt, SecretKey as P256Key,
     14     elliptic_curve::sec1::{FromSec1Point as _, ToSec1Point as _},
     15 };
     16 use p384::{PublicKey as P384PubKey, Sec1Point as P384Pt, SecretKey as P384Key};
     17 use rsa::{
     18     BoxedUint, RsaPrivateKey,
     19     sha2::{Digest as _, Sha256},
     20     traits::PublicKeyParts as _,
     21 };
     22 use serde::de::{Error as _, Unexpected};
     23 use serde_json::Error;
     24 #[expect(clippy::unwrap_used, reason = "OK in tests")]
     25 #[test]
     26 fn mldsa87_spki() {
     27     assert!(
     28         MlDsa87PubKey::from_der(
     29             MlDsaVerKey::<MlDsa87>::decode(&[1; 2592].into())
     30                 .to_public_key_der()
     31                 .unwrap()
     32                 .as_bytes()
     33         )
     34         .is_ok_and(|k| k.0 == [1; 2592])
     35     );
     36 }
     37 #[expect(clippy::unwrap_used, reason = "OK in tests")]
     38 #[test]
     39 fn mldsa65_spki() {
     40     assert!(
     41         MlDsa65PubKey::from_der(
     42             MlDsaVerKey::<MlDsa65>::decode(&[1; 1952].into())
     43                 .to_public_key_der()
     44                 .unwrap()
     45                 .as_bytes()
     46         )
     47         .is_ok_and(|k| k.0 == [1; 1952])
     48     );
     49 }
     50 #[expect(clippy::unwrap_used, reason = "OK in tests")]
     51 #[test]
     52 fn mldsa44_spki() {
     53     assert!(
     54         MlDsa44PubKey::from_der(
     55             MlDsaVerKey::<MlDsa44>::decode(&[1; 1312].into())
     56                 .to_public_key_der()
     57                 .unwrap()
     58                 .as_bytes()
     59         )
     60         .is_ok_and(|k| k.0 == [1; 1312])
     61     );
     62 }
     63 #[expect(clippy::unwrap_used, reason = "OK in tests")]
     64 #[test]
     65 fn ed25519_spki() {
     66     assert!(
     67         Ed25519PubKey::from_der(
     68             VerifyingKey::from_bytes(&[1; 32])
     69                 .unwrap()
     70                 .to_public_key_der()
     71                 .unwrap()
     72                 .as_bytes()
     73         )
     74         .is_ok_and(|k| k.0 == [1; 32])
     75     );
     76 }
     77 #[expect(clippy::unwrap_used, reason = "OK in tests")]
     78 #[test]
     79 fn p256_spki() {
     80     let key = P256Key::from_bytes(
     81         &[
     82             137, 133, 36, 206, 163, 47, 255, 5, 76, 144, 163, 141, 40, 109, 108, 240, 246, 115,
     83             178, 237, 169, 68, 6, 129, 92, 21, 238, 127, 55, 158, 207, 95,
     84         ]
     85         .into(),
     86     )
     87     .unwrap()
     88     .public_key();
     89     let enc_key = key.to_sec1_point(false);
     90     assert!(
     91         UncompressedP256PubKey::from_der(key.to_public_key_der().unwrap().as_bytes())
     92             .is_ok_and(|k| *k.0 == **enc_key.x().unwrap() && *k.1 == **enc_key.y().unwrap())
     93     );
     94 }
     95 #[expect(clippy::unwrap_used, reason = "OK in tests")]
     96 #[test]
     97 fn p384_spki() {
     98     let key = P384Key::from_bytes(
     99         &[
    100             158, 99, 156, 49, 190, 211, 85, 167, 28, 2, 80, 57, 31, 22, 17, 38, 85, 78, 232, 42,
    101             45, 199, 154, 243, 136, 251, 84, 34, 5, 120, 208, 91, 61, 248, 64, 144, 87, 1, 32, 86,
    102             220, 68, 182, 11, 105, 223, 75, 70,
    103         ]
    104         .into(),
    105     )
    106     .unwrap()
    107     .public_key();
    108     let enc_key = key.to_sec1_point(false);
    109     assert!(
    110         UncompressedP384PubKey::from_der(key.to_public_key_der().unwrap().as_bytes())
    111             .is_ok_and(|k| *k.0 == **enc_key.x().unwrap() && *k.1 == **enc_key.y().unwrap())
    112     );
    113 }
    114 #[expect(clippy::unwrap_used, reason = "OK in tests")]
    115 #[test]
    116 fn rsa_spki() {
    117     let n = [
    118         111, 183, 124, 133, 38, 167, 70, 148, 44, 50, 30, 60, 121, 14, 38, 37, 96, 114, 107, 195,
    119         248, 64, 79, 36, 237, 140, 43, 27, 94, 74, 102, 152, 135, 102, 184, 150, 186, 206, 185, 19,
    120         165, 209, 48, 98, 98, 9, 3, 205, 208, 82, 250, 105, 132, 201, 73, 62, 60, 165, 100, 128,
    121         153, 9, 41, 118, 66, 95, 236, 214, 73, 135, 197, 68, 184, 10, 27, 116, 204, 145, 50, 174,
    122         58, 42, 183, 181, 119, 232, 126, 252, 217, 96, 162, 190, 103, 122, 64, 87, 145, 45, 32,
    123         207, 17, 239, 223, 3, 35, 14, 112, 119, 124, 141, 123, 208, 239, 105, 81, 217, 151, 162,
    124         190, 17, 88, 182, 176, 158, 81, 200, 42, 166, 133, 48, 23, 236, 55, 117, 248, 233, 151,
    125         203, 122, 155, 231, 46, 177, 20, 20, 151, 64, 222, 239, 226, 7, 21, 254, 81, 202, 64, 232,
    126         161, 235, 22, 51, 246, 207, 213, 0, 229, 138, 46, 222, 205, 157, 108, 139, 253, 230, 80,
    127         50, 2, 122, 212, 163, 100, 180, 114, 12, 113, 52, 56, 99, 188, 42, 198, 212, 23, 182, 222,
    128         56, 221, 200, 79, 96, 239, 221, 135, 10, 17, 106, 183, 56, 104, 68, 94, 198, 196, 35, 200,
    129         83, 204, 26, 185, 204, 212, 31, 183, 19, 111, 233, 13, 72, 93, 53, 65, 111, 59, 242, 122,
    130         160, 244, 162, 126, 38, 235, 156, 47, 88, 39, 132, 153, 79, 0, 133, 78, 7, 218, 165, 241,
    131     ];
    132     let e = 0x0001_0001u32;
    133     let d = [
    134         145, 79, 21, 97, 233, 3, 192, 194, 177, 68, 181, 80, 120, 197, 23, 44, 185, 74, 144, 0,
    135         132, 149, 139, 11, 16, 224, 4, 112, 236, 94, 238, 97, 121, 124, 213, 145, 24, 253, 168, 35,
    136         190, 205, 132, 115, 33, 201, 38, 253, 246, 180, 66, 155, 165, 46, 3, 254, 68, 108, 154,
    137         247, 246, 45, 187, 0, 204, 96, 185, 157, 249, 174, 158, 38, 62, 244, 183, 76, 102, 6, 219,
    138         92, 212, 138, 59, 147, 163, 219, 111, 39, 105, 21, 236, 196, 38, 255, 114, 247, 82, 104,
    139         113, 204, 29, 152, 209, 219, 48, 239, 74, 129, 19, 247, 33, 239, 119, 166, 216, 152, 94,
    140         138, 238, 164, 242, 129, 50, 150, 57, 20, 53, 224, 56, 241, 138, 97, 111, 215, 107, 212,
    141         195, 146, 108, 143, 0, 229, 181, 171, 73, 152, 105, 146, 25, 243, 242, 140, 252, 248, 162,
    142         247, 63, 168, 180, 20, 153, 120, 10, 248, 211, 1, 71, 127, 212, 249, 237, 203, 202, 48, 26,
    143         216, 226, 228, 186, 13, 204, 70, 255, 240, 89, 255, 59, 83, 31, 253, 55, 43, 158, 90, 248,
    144         83, 32, 159, 105, 57, 134, 34, 96, 18, 255, 245, 153, 162, 60, 91, 99, 220, 51, 44, 85,
    145         114, 67, 125, 202, 65, 217, 245, 40, 8, 81, 165, 142, 24, 245, 127, 122, 247, 152, 212, 75,
    146         45, 59, 90, 184, 234, 31, 147, 36, 8, 212, 45, 50, 23, 3, 25, 253, 87, 227, 79, 119, 161,
    147     ];
    148     let p = BoxedUint::from_le_slice_vartime(
    149         [
    150             215, 166, 5, 21, 11, 179, 41, 77, 198, 92, 165, 48, 77, 162, 42, 41, 206, 141, 60, 69,
    151             47, 164, 19, 92, 46, 72, 100, 238, 100, 53, 214, 197, 163, 185, 6, 140, 229, 250, 195,
    152             77, 8, 12, 5, 236, 178, 173, 86, 201, 43, 213, 165, 51, 108, 101, 161, 99, 76, 240, 14,
    153             234, 76, 197, 137, 53, 198, 168, 135, 205, 212, 198, 120, 29, 16, 82, 98, 233, 236,
    154             177, 12, 171, 141, 100, 107, 146, 33, 176, 125, 202, 172, 79, 147, 179, 30, 62, 247,
    155             206, 169, 19, 168, 114, 26, 73, 108, 178, 105, 84, 89, 191, 168, 253, 228, 214, 54, 16,
    156             212, 199, 111, 72, 3, 41, 247, 227, 165, 244, 32, 188, 24, 247,
    157         ]
    158         .as_slice(),
    159     );
    160     let p_2 = BoxedUint::from_le_slice_vartime(
    161         [
    162             41, 25, 198, 240, 134, 206, 121, 57, 11, 5, 134, 192, 212, 77, 229, 197, 14, 78, 85,
    163             212, 190, 114, 179, 188, 21, 171, 174, 12, 104, 74, 15, 164, 136, 173, 62, 177, 141,
    164             213, 93, 102, 147, 83, 59, 124, 146, 59, 175, 213, 55, 27, 25, 248, 154, 29, 39, 85,
    165             50, 235, 134, 60, 203, 106, 186, 195, 190, 185, 71, 169, 142, 236, 92, 11, 250, 187,
    166             198, 8, 201, 184, 120, 178, 227, 87, 63, 243, 89, 227, 234, 184, 28, 252, 112, 211,
    167             193, 69, 23, 92, 5, 72, 93, 53, 69, 159, 73, 160, 105, 244, 249, 94, 214, 173, 9, 236,
    168             4, 255, 129, 11, 224, 140, 252, 168, 57, 143, 176, 241, 60, 219, 90, 250,
    169         ]
    170         .as_slice(),
    171     );
    172     let key = RsaPrivateKey::from_components(
    173         BoxedUint::from_le_slice_vartime(n.as_slice()),
    174         e.into(),
    175         BoxedUint::from_le_slice_vartime(d.as_slice()),
    176         vec![p, p_2],
    177     )
    178     .unwrap()
    179     .to_public_key();
    180     assert!(
    181         RsaPubKey::from_der(key.to_public_key_der().unwrap().as_bytes())
    182             .is_ok_and(|k| *k.0 == *key.n().to_be_bytes() && BoxedUint::from(k.1) == *key.e())
    183     );
    184 }
    185 #[expect(clippy::unwrap_used, reason = "OK in tests")]
    186 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
    187 #[expect(
    188     clippy::cognitive_complexity,
    189     clippy::too_many_lines,
    190     reason = "a lot to test"
    191 )]
    192 #[test]
    193 fn eddsa_registration_deserialize_data_mismatch() {
    194     let c_data_json = serde_json::json!({}).to_string();
    195     let att_obj: [u8; 143] = [
    196         cbor::MAP_3,
    197         cbor::TEXT_3,
    198         b'f',
    199         b'm',
    200         b't',
    201         cbor::TEXT_4,
    202         b'n',
    203         b'o',
    204         b'n',
    205         b'e',
    206         cbor::TEXT_7,
    207         b'a',
    208         b't',
    209         b't',
    210         b'S',
    211         b't',
    212         b'm',
    213         b't',
    214         cbor::MAP_0,
    215         cbor::TEXT_8,
    216         b'a',
    217         b'u',
    218         b't',
    219         b'h',
    220         b'D',
    221         b'a',
    222         b't',
    223         b'a',
    224         cbor::BYTES_INFO_24,
    225         115,
    226         // `rpIdHash`.
    227         0,
    228         0,
    229         0,
    230         0,
    231         0,
    232         0,
    233         0,
    234         0,
    235         0,
    236         0,
    237         0,
    238         0,
    239         0,
    240         0,
    241         0,
    242         0,
    243         0,
    244         0,
    245         0,
    246         0,
    247         0,
    248         0,
    249         0,
    250         0,
    251         0,
    252         0,
    253         0,
    254         0,
    255         0,
    256         0,
    257         0,
    258         0,
    259         // `flags`.
    260         0b0100_0101,
    261         // `signCount`.
    262         0,
    263         0,
    264         0,
    265         0,
    266         // `aaguid`.
    267         0,
    268         0,
    269         0,
    270         0,
    271         0,
    272         0,
    273         0,
    274         0,
    275         0,
    276         0,
    277         0,
    278         0,
    279         0,
    280         0,
    281         0,
    282         0,
    283         // `credentialIdLength`.
    284         0,
    285         16,
    286         // `credentialId`.
    287         0,
    288         0,
    289         0,
    290         0,
    291         0,
    292         0,
    293         0,
    294         0,
    295         0,
    296         0,
    297         0,
    298         0,
    299         0,
    300         0,
    301         0,
    302         0,
    303         // Ed25519 COSE key.
    304         cbor::MAP_4,
    305         KTY,
    306         OKP,
    307         ALG,
    308         EDDSA,
    309         // `crv`.
    310         cbor::NEG_ONE,
    311         // `Ed25519`.
    312         cbor::SIX,
    313         // `x`.
    314         cbor::NEG_TWO,
    315         cbor::BYTES_INFO_24,
    316         32,
    317         // Compressed y-coordinate.
    318         1,
    319         1,
    320         1,
    321         1,
    322         1,
    323         1,
    324         1,
    325         1,
    326         1,
    327         1,
    328         1,
    329         1,
    330         1,
    331         1,
    332         1,
    333         1,
    334         1,
    335         1,
    336         1,
    337         1,
    338         1,
    339         1,
    340         1,
    341         1,
    342         1,
    343         1,
    344         1,
    345         1,
    346         1,
    347         1,
    348         1,
    349         1,
    350     ];
    351     let pub_key = VerifyingKey::from_bytes(&[1; 32])
    352         .unwrap()
    353         .to_public_key_der()
    354         .unwrap();
    355     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
    356     let att_obj_len = att_obj.len();
    357     let auth_data_start = att_obj_len - 113;
    358     let b64_adata = base64url_nopad::encode(&att_obj[auth_data_start..]);
    359     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
    360     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
    361     // Base case is valid.
    362     assert!(
    363         serde_json::from_str::<Registration>(
    364             serde_json::json!({
    365                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    366                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    367                 "response": {
    368                     "clientDataJSON": b64_cdata_json,
    369                     "authenticatorData": b64_adata,
    370                     "transports": ["ble", "usb", "hybrid", "internal", "nfc", "smart-card"],
    371                     "publicKey": b64_key,
    372                     "publicKeyAlgorithm": -8i8,
    373                     "attestationObject": b64_aobj,
    374                 },
    375                 "authenticatorAttachment": "cross-platform",
    376                 "clientExtensionResults": {},
    377                 "type": "public-key"
    378             })
    379             .to_string()
    380             .as_str()
    381         )
    382         .is_ok_and(
    383             |reg| reg.response.client_data_json == c_data_json.as_bytes()
    384                 && reg.response.attestation_object_and_c_data_hash[..att_obj_len] == att_obj
    385                 && reg.response.attestation_object_and_c_data_hash[att_obj_len..]
    386                     == *Sha256::digest(c_data_json.as_bytes())
    387                 && reg.response.transports.count() == 6
    388                 && matches!(
    389                     reg.authenticator_attachment,
    390                     AuthenticatorAttachment::CrossPlatform
    391                 )
    392                 && reg.client_extension_results.cred_props.is_none()
    393                 && reg.client_extension_results.prf.is_none()
    394         )
    395     );
    396     // `id` and `rawId` mismatch.
    397     let mut err = Error::invalid_value(
    398         Unexpected::Bytes(
    399             base64url_nopad::decode(b"ABABABABABABABABABABAA")
    400                 .unwrap()
    401                 .as_slice(),
    402         ),
    403         &format!("id and rawId to match: CredentialId({:?})", [0u8; 16]).as_str(),
    404     )
    405     .to_string()
    406     .into_bytes();
    407     assert_eq!(
    408         serde_json::from_str::<Registration>(
    409             serde_json::json!({
    410                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    411                 "rawId": "ABABABABABABABABABABAA",
    412                 "response": {
    413                     "clientDataJSON": b64_cdata_json,
    414                     "authenticatorData": b64_adata,
    415                     "transports": [],
    416                     "publicKey": b64_key,
    417                     "publicKeyAlgorithm": -8i8,
    418                     "attestationObject": b64_aobj,
    419                 },
    420                 "clientExtensionResults": {},
    421                 "type": "public-key"
    422             })
    423             .to_string()
    424             .as_str()
    425         )
    426         .unwrap_err()
    427         .to_string()
    428         .into_bytes()
    429         .get(..err.len()),
    430         Some(err.as_slice())
    431     );
    432     // missing `id`.
    433     err = Error::missing_field("id").to_string().into_bytes();
    434     assert_eq!(
    435         serde_json::from_str::<Registration>(
    436             serde_json::json!({
    437                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    438                 "response": {
    439                     "clientDataJSON": b64_cdata_json,
    440                     "authenticatorData": b64_adata,
    441                     "transports": [],
    442                     "publicKey": b64_key,
    443                     "publicKeyAlgorithm": -8i8,
    444                     "attestationObject": b64_aobj,
    445                 },
    446                 "clientExtensionResults": {},
    447                 "type": "public-key"
    448             })
    449             .to_string()
    450             .as_str()
    451         )
    452         .unwrap_err()
    453         .to_string()
    454         .into_bytes()
    455         .get(..err.len()),
    456         Some(err.as_slice())
    457     );
    458     // `null` `id`.
    459     err = Error::invalid_type(Unexpected::Other("null"), &"CredentialId")
    460         .to_string()
    461         .into_bytes();
    462     assert_eq!(
    463         serde_json::from_str::<Registration>(
    464             serde_json::json!({
    465                 "id": null,
    466                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    467                 "response": {
    468                     "clientDataJSON": b64_cdata_json,
    469                     "authenticatorData": b64_adata,
    470                     "transports": [],
    471                     "publicKey": b64_key,
    472                     "publicKeyAlgorithm": -8i8,
    473                     "attestationObject": b64_aobj,
    474                 },
    475                 "clientExtensionResults": {},
    476                 "type": "public-key"
    477             })
    478             .to_string()
    479             .as_str()
    480         )
    481         .unwrap_err()
    482         .to_string()
    483         .into_bytes()
    484         .get(..err.len()),
    485         Some(err.as_slice())
    486     );
    487     // missing `rawId`.
    488     err = Error::missing_field("rawId").to_string().into_bytes();
    489     assert_eq!(
    490         serde_json::from_str::<Registration>(
    491             serde_json::json!({
    492                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    493                 "response": {
    494                     "clientDataJSON": b64_cdata_json,
    495                     "authenticatorData": b64_adata,
    496                     "transports": [],
    497                     "publicKey": b64_key,
    498                     "publicKeyAlgorithm": -8i8,
    499                     "attestationObject": b64_aobj,
    500                 },
    501                 "clientExtensionResults": {},
    502                 "type": "public-key"
    503             })
    504             .to_string()
    505             .as_str()
    506         )
    507         .unwrap_err()
    508         .to_string()
    509         .into_bytes()
    510         .get(..err.len()),
    511         Some(err.as_slice())
    512     );
    513     // `null` `rawId`.
    514     err = Error::invalid_type(Unexpected::Other("null"), &"CredentialId")
    515         .to_string()
    516         .into_bytes();
    517     assert_eq!(
    518         serde_json::from_str::<Registration>(
    519             serde_json::json!({
    520                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    521                 "rawId": null,
    522                 "response": {
    523                     "clientDataJSON": b64_cdata_json,
    524                     "authenticatorData": b64_adata,
    525                     "transports": [],
    526                     "publicKey": b64_key,
    527                     "publicKeyAlgorithm": -8i8,
    528                     "attestationObject": b64_aobj,
    529                 },
    530                 "clientExtensionResults": {},
    531                 "type": "public-key"
    532             })
    533             .to_string()
    534             .as_str()
    535         )
    536         .unwrap_err()
    537         .to_string()
    538         .into_bytes()
    539         .get(..err.len()),
    540         Some(err.as_slice())
    541     );
    542     // `id` and the credential id in authenticator data mismatch.
    543     err = Error::invalid_value(
    544         Unexpected::Bytes(
    545             base64url_nopad::decode(b"ABABABABABABABABABABAA")
    546                 .unwrap()
    547                 .as_slice(),
    548         ),
    549         &format!(
    550             "id, rawId, and the credential id in the attested credential data to all match: {:?}",
    551             [0u8; 16]
    552         )
    553         .as_str(),
    554     )
    555     .to_string()
    556     .into_bytes();
    557     assert_eq!(
    558         serde_json::from_str::<Registration>(
    559             serde_json::json!({
    560                 "id": "ABABABABABABABABABABAA",
    561                 "rawId": "ABABABABABABABABABABAA",
    562                 "response": {
    563                     "clientDataJSON": b64_cdata_json,
    564                     "authenticatorData": b64_adata,
    565                     "transports": [],
    566                     "publicKey": b64_key,
    567                     "publicKeyAlgorithm": -8i8,
    568                     "attestationObject": b64_aobj,
    569                 },
    570                 "clientExtensionResults": {},
    571                 "type": "public-key"
    572             })
    573             .to_string()
    574             .as_str()
    575         )
    576         .unwrap_err()
    577         .to_string()
    578         .into_bytes()
    579         .get(..err.len()),
    580         Some(err.as_slice())
    581     );
    582     // `authenticatorData` mismatches `authData` in attestation object.
    583     let mut bad_auth = [0; 113];
    584     bad_auth.copy_from_slice(&att_obj[auth_data_start..]);
    585     bad_auth[113 - 32..].copy_from_slice([0; 32].as_slice());
    586     err = Error::invalid_value(
    587         Unexpected::Bytes(bad_auth.as_slice()),
    588         &format!("authenticator data to match the authenticator data portion of attestation object: {:?}", &att_obj[att_obj_len - bad_auth.len()..]).as_str(),
    589     )
    590     .to_string().into_bytes();
    591     assert_eq!(
    592         serde_json::from_str::<Registration>(
    593             serde_json::json!({
    594                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    595                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    596                 "response": {
    597                     "clientDataJSON": b64_cdata_json,
    598                     "authenticatorData": base64url_nopad::encode(bad_auth.as_slice()),
    599                     "transports": [],
    600                     "publicKey": b64_key,
    601                     "publicKeyAlgorithm": -8i8,
    602                     "attestationObject": b64_aobj,
    603                 },
    604                 "clientExtensionResults": {},
    605                 "type": "public-key"
    606             })
    607             .to_string()
    608             .as_str()
    609         )
    610         .unwrap_err()
    611         .to_string()
    612         .into_bytes()
    613         .get(..err.len()),
    614         Some(err.as_slice())
    615     );
    616     // Missing `authenticatorData`.
    617     err = Error::missing_field("authenticatorData")
    618         .to_string()
    619         .into_bytes();
    620     assert_eq!(
    621         serde_json::from_str::<Registration>(
    622             serde_json::json!({
    623                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    624                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    625                 "response": {
    626                     "clientDataJSON": b64_cdata_json,
    627                     "transports": [],
    628                     "publicKey": b64_key,
    629                     "publicKeyAlgorithm": -8i8,
    630                     "attestationObject": b64_aobj,
    631                 },
    632                 "clientExtensionResults": {},
    633                 "type": "public-key"
    634             })
    635             .to_string()
    636             .as_str()
    637         )
    638         .unwrap_err()
    639         .to_string()
    640         .into_bytes()
    641         .get(..err.len()),
    642         Some(err.as_slice())
    643     );
    644     // `null` `authenticatorData`.
    645     err = Error::invalid_type(Unexpected::Other("null"), &"authenticatorData")
    646         .to_string()
    647         .into_bytes();
    648     assert_eq!(
    649         serde_json::from_str::<Registration>(
    650             serde_json::json!({
    651                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    652                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    653                 "response": {
    654                     "clientDataJSON": b64_cdata_json,
    655                     "transports": [],
    656                     "authenticatorData": null,
    657                     "publicKey": b64_key,
    658                     "publicKeyAlgorithm": -8i8,
    659                     "attestationObject": b64_aobj,
    660                 },
    661                 "clientExtensionResults": {},
    662                 "type": "public-key"
    663             })
    664             .to_string()
    665             .as_str()
    666         )
    667         .unwrap_err()
    668         .to_string()
    669         .into_bytes()
    670         .get(..err.len()),
    671         Some(err.as_slice())
    672     );
    673     // `publicKeyAlgorithm` mismatch.
    674     err = Error::invalid_value(
    675         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
    676         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Eddsa).as_str()
    677     )
    678     .to_string().into_bytes();
    679     assert_eq!(
    680         serde_json::from_str::<Registration>(
    681             serde_json::json!({
    682                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    683                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    684                 "response": {
    685                     "clientDataJSON": b64_cdata_json,
    686                     "authenticatorData": b64_adata,
    687                     "transports": [],
    688                     "publicKey": b64_key,
    689                     "publicKeyAlgorithm": -7i8,
    690                     "attestationObject": b64_aobj,
    691                 },
    692                 "clientExtensionResults": {},
    693                 "type": "public-key"
    694             })
    695             .to_string()
    696             .as_str()
    697         )
    698         .unwrap_err()
    699         .to_string()
    700         .into_bytes()
    701         .get(..err.len()),
    702         Some(err.as_slice())
    703     );
    704     // Missing `publicKeyAlgorithm`.
    705     err = Error::missing_field("publicKeyAlgorithm")
    706         .to_string()
    707         .into_bytes();
    708     assert_eq!(
    709         serde_json::from_str::<Registration>(
    710             serde_json::json!({
    711                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    712                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    713                 "response": {
    714                     "clientDataJSON": b64_cdata_json,
    715                     "authenticatorData": b64_adata,
    716                     "transports": [],
    717                     "publicKey": b64_key,
    718                     "attestationObject": b64_aobj,
    719                 },
    720                 "clientExtensionResults": {},
    721                 "type": "public-key"
    722             })
    723             .to_string()
    724             .as_str()
    725         )
    726         .unwrap_err()
    727         .to_string()
    728         .into_bytes()
    729         .get(..err.len()),
    730         Some(err.as_slice())
    731     );
    732     // `null` `publicKeyAlgorithm`.
    733     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
    734         .to_string()
    735         .into_bytes();
    736     assert_eq!(
    737         serde_json::from_str::<Registration>(
    738             serde_json::json!({
    739                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    740                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    741                 "response": {
    742                     "clientDataJSON": b64_cdata_json,
    743                     "authenticatorData": b64_adata,
    744                     "transports": [],
    745                     "publicKey": b64_key,
    746                     "publicKeyAlgorithm": null,
    747                     "attestationObject": b64_aobj,
    748                 },
    749                 "clientExtensionResults": {},
    750                 "type": "public-key"
    751             })
    752             .to_string()
    753             .as_str()
    754         )
    755         .unwrap_err()
    756         .to_string()
    757         .into_bytes()
    758         .get(..err.len()),
    759         Some(err.as_slice())
    760     );
    761     // `publicKey` mismatch.
    762     err = Error::invalid_value(
    763         Unexpected::Bytes([0; 32].as_slice()),
    764         &format!(
    765             "DER-encoded public key to match the public key within the attestation object: Ed25519(Ed25519PubKey({:?}))",
    766             &att_obj[att_obj.len() - 32..],
    767         )
    768         .as_str(),
    769     )
    770     .to_string().into_bytes();
    771     assert_eq!(serde_json::from_str::<Registration>(
    772         serde_json::json!({
    773             "id": "AAAAAAAAAAAAAAAAAAAAAA",
    774             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    775             "response": {
    776                 "clientDataJSON": b64_cdata_json,
    777                 "authenticatorData": b64_adata,
    778                 "transports": [],
    779                 "publicKey": base64url_nopad::encode(VerifyingKey::from_bytes(&[0; 32]).unwrap().to_public_key_der().unwrap().as_bytes()),
    780                 "publicKeyAlgorithm": -8i8,
    781                 "attestationObject": b64_aobj,
    782             },
    783             "clientExtensionResults": {},
    784             "type": "public-key"
    785         })
    786         .to_string()
    787         .as_str()
    788         )
    789         .unwrap_err().to_string().into_bytes().get(..err.len()),
    790         Some(err.as_slice())
    791     );
    792     // Missing `publicKey` when using EdDSA, ES256, or RS256.
    793     err = Error::missing_field("publicKey").to_string().into_bytes();
    794     assert_eq!(
    795         serde_json::from_str::<Registration>(
    796             serde_json::json!({
    797                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    798                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    799                 "response": {
    800                     "clientDataJSON": b64_cdata_json,
    801                     "authenticatorData": b64_adata,
    802                     "transports": [],
    803                     "publicKeyAlgorithm": -8i8,
    804                     "attestationObject": b64_aobj,
    805                 },
    806                 "clientExtensionResults": {},
    807                 "type": "public-key"
    808             })
    809             .to_string()
    810             .as_str()
    811         )
    812         .unwrap_err()
    813         .to_string()
    814         .into_bytes()
    815         .get(..err.len()),
    816         Some(err.as_slice())
    817     );
    818     // `null` `publicKey` when using EdDSA, ES256, or RS256.
    819     err = Error::invalid_type(Unexpected::Other("null"), &"publicKey")
    820         .to_string()
    821         .into_bytes();
    822     assert_eq!(
    823         serde_json::from_str::<Registration>(
    824             serde_json::json!({
    825                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    826                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    827                 "response": {
    828                     "clientDataJSON": b64_cdata_json,
    829                     "authenticatorData": b64_adata,
    830                     "transports": [],
    831                     "publicKey": null,
    832                     "publicKeyAlgorithm": -8i8,
    833                     "attestationObject": b64_aobj,
    834                 },
    835                 "clientExtensionResults": {},
    836                 "type": "public-key"
    837             })
    838             .to_string()
    839             .as_str()
    840         )
    841         .unwrap_err()
    842         .to_string()
    843         .into_bytes()
    844         .get(..err.len()),
    845         Some(err.as_slice())
    846     );
    847     // Missing `transports`.
    848     err = Error::missing_field("transports").to_string().into_bytes();
    849     assert_eq!(
    850         serde_json::from_str::<Registration>(
    851             serde_json::json!({
    852                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    853                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    854                 "response": {
    855                     "clientDataJSON": b64_cdata_json,
    856                     "authenticatorData": b64_adata,
    857                     "publicKey": b64_key,
    858                     "publicKeyAlgorithm": -8i8,
    859                     "attestationObject": b64_aobj,
    860                 },
    861                 "clientExtensionResults": {},
    862                 "type": "public-key"
    863             })
    864             .to_string()
    865             .as_str()
    866         )
    867         .unwrap_err()
    868         .to_string()
    869         .into_bytes()
    870         .get(..err.len()),
    871         Some(err.as_slice())
    872     );
    873     // Duplicate `transports` are allowed.
    874     assert!(
    875         serde_json::from_str::<Registration>(
    876             serde_json::json!({
    877                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    878                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    879                 "response": {
    880                     "clientDataJSON": b64_cdata_json,
    881                     "authenticatorData": b64_adata,
    882                     "transports": ["usb", "usb"],
    883                     "publicKey": b64_key,
    884                     "publicKeyAlgorithm": -8i8,
    885                     "attestationObject": b64_aobj,
    886                 },
    887                 "clientExtensionResults": {},
    888                 "type": "public-key"
    889             })
    890             .to_string()
    891             .as_str()
    892         )
    893         .is_ok_and(|reg| reg.response.transports.count() == 1)
    894     );
    895     // `null` `transports`.
    896     err = Error::invalid_type(Unexpected::Other("null"), &"transports")
    897         .to_string()
    898         .into_bytes();
    899     assert_eq!(
    900         serde_json::from_str::<Registration>(
    901             serde_json::json!({
    902                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    903                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    904                 "response": {
    905                     "clientDataJSON": b64_cdata_json,
    906                     "authenticatorData": b64_adata,
    907                     "transports": null,
    908                     "publicKey": b64_key,
    909                     "publicKeyAlgorithm": -8i8,
    910                     "attestationObject": b64_aobj,
    911                 },
    912                 "clientExtensionResults": {},
    913                 "type": "public-key"
    914             })
    915             .to_string()
    916             .as_str()
    917         )
    918         .unwrap_err()
    919         .to_string()
    920         .into_bytes()
    921         .get(..err.len()),
    922         Some(err.as_slice())
    923     );
    924     // Unknown `transports`.
    925     err = Error::invalid_value(
    926         Unexpected::Str("Usb"),
    927         &"'ble', 'cable', 'hybrid', 'internal', 'nfc', 'smart-card', or 'usb'",
    928     )
    929     .to_string()
    930     .into_bytes();
    931     assert_eq!(
    932         serde_json::from_str::<Registration>(
    933             serde_json::json!({
    934                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    935                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    936                 "response": {
    937                     "clientDataJSON": b64_cdata_json,
    938                     "authenticatorData": b64_adata,
    939                     "transports": ["Usb"],
    940                     "publicKey": b64_key,
    941                     "publicKeyAlgorithm": -8i8,
    942                     "attestationObject": b64_aobj,
    943                 },
    944                 "clientExtensionResults": {},
    945                 "type": "public-key"
    946             })
    947             .to_string()
    948             .as_str()
    949         )
    950         .unwrap_err()
    951         .to_string()
    952         .into_bytes()
    953         .get(..err.len()),
    954         Some(err.as_slice())
    955     );
    956     // `null` `authenticatorAttachment`.
    957     assert!(
    958         serde_json::from_str::<Registration>(
    959             serde_json::json!({
    960                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    961                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    962                 "response": {
    963                     "clientDataJSON": b64_cdata_json,
    964                     "authenticatorData": b64_adata,
    965                     "transports": [],
    966                     "publicKey": b64_key,
    967                     "publicKeyAlgorithm": -8i8,
    968                     "attestationObject": b64_aobj,
    969                 },
    970                 "authenticatorAttachment": null,
    971                 "clientExtensionResults": {},
    972                 "type": "public-key"
    973             })
    974             .to_string()
    975             .as_str()
    976         )
    977         .is_ok_and(|reg| matches!(reg.authenticator_attachment, AuthenticatorAttachment::None))
    978     );
    979     // Unknown `authenticatorAttachment`.
    980     err = Error::invalid_value(
    981         Unexpected::Str("Platform"),
    982         &"'platform' or 'cross-platform'",
    983     )
    984     .to_string()
    985     .into_bytes();
    986     assert_eq!(
    987         serde_json::from_str::<Registration>(
    988             serde_json::json!({
    989                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
    990                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
    991                 "response": {
    992                     "clientDataJSON": b64_cdata_json,
    993                     "authenticatorData": b64_adata,
    994                     "transports": [],
    995                     "publicKey": b64_key,
    996                     "publicKeyAlgorithm": -8i8,
    997                     "attestationObject": b64_aobj,
    998                 },
    999                 "authenticatorAttachment": "Platform",
   1000                 "clientExtensionResults": {},
   1001                 "type": "public-key"
   1002             })
   1003             .to_string()
   1004             .as_str()
   1005         )
   1006         .unwrap_err()
   1007         .to_string()
   1008         .into_bytes()
   1009         .get(..err.len()),
   1010         Some(err.as_slice())
   1011     );
   1012     // Missing `clientDataJSON`.
   1013     err = Error::missing_field("clientDataJSON")
   1014         .to_string()
   1015         .into_bytes();
   1016     assert_eq!(
   1017         serde_json::from_str::<Registration>(
   1018             serde_json::json!({
   1019                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1020                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1021                 "response": {
   1022                     "authenticatorData": b64_adata,
   1023                     "transports": [],
   1024                     "publicKey": b64_key,
   1025                     "publicKeyAlgorithm": -8i8,
   1026                     "attestationObject": b64_aobj,
   1027                 },
   1028                 "clientExtensionResults": {},
   1029                 "type": "public-key"
   1030             })
   1031             .to_string()
   1032             .as_str()
   1033         )
   1034         .unwrap_err()
   1035         .to_string()
   1036         .into_bytes()
   1037         .get(..err.len()),
   1038         Some(err.as_slice())
   1039     );
   1040     // `null` `clientDataJSON`.
   1041     err = Error::invalid_type(Unexpected::Other("null"), &"base64url-encoded data")
   1042         .to_string()
   1043         .into_bytes();
   1044     assert_eq!(
   1045         serde_json::from_str::<Registration>(
   1046             serde_json::json!({
   1047                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1048                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1049                 "response": {
   1050                     "clientDataJSON": null,
   1051                     "authenticatorData": b64_adata,
   1052                     "transports": [],
   1053                     "publicKey": b64_key,
   1054                     "publicKeyAlgorithm": -8i8,
   1055                     "attestationObject": b64_aobj,
   1056                 },
   1057                 "clientExtensionResults": {},
   1058                 "type": "public-key"
   1059             })
   1060             .to_string()
   1061             .as_str()
   1062         )
   1063         .unwrap_err()
   1064         .to_string()
   1065         .into_bytes()
   1066         .get(..err.len()),
   1067         Some(err.as_slice())
   1068     );
   1069     // Missing `attestationObject`.
   1070     err = Error::missing_field("attestationObject")
   1071         .to_string()
   1072         .into_bytes();
   1073     assert_eq!(
   1074         serde_json::from_str::<Registration>(
   1075             serde_json::json!({
   1076                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1077                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1078                 "response": {
   1079                     "clientDataJSON": b64_cdata_json,
   1080                     "authenticatorData": b64_adata,
   1081                     "transports": [],
   1082                     "publicKey": b64_key,
   1083                     "publicKeyAlgorithm": -8i8,
   1084                 },
   1085                 "clientExtensionResults": {},
   1086                 "type": "public-key"
   1087             })
   1088             .to_string()
   1089             .as_str()
   1090         )
   1091         .unwrap_err()
   1092         .to_string()
   1093         .into_bytes()
   1094         .get(..err.len()),
   1095         Some(err.as_slice())
   1096     );
   1097     // `null` `attestationObject`.
   1098     err = Error::invalid_type(
   1099         Unexpected::Other("null"),
   1100         &"base64url-encoded attestation object",
   1101     )
   1102     .to_string()
   1103     .into_bytes();
   1104     assert_eq!(
   1105         serde_json::from_str::<Registration>(
   1106             serde_json::json!({
   1107                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1108                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1109                 "response": {
   1110                     "clientDataJSON": b64_cdata_json,
   1111                     "authenticatorData": b64_adata,
   1112                     "transports": [],
   1113                     "publicKey": b64_key,
   1114                     "publicKeyAlgorithm": -8i8,
   1115                     "attestationObject": null,
   1116                 },
   1117                 "clientExtensionResults": {},
   1118                 "type": "public-key"
   1119             })
   1120             .to_string()
   1121             .as_str()
   1122         )
   1123         .unwrap_err()
   1124         .to_string()
   1125         .into_bytes()
   1126         .get(..err.len()),
   1127         Some(err.as_slice())
   1128     );
   1129     // Missing `response`.
   1130     err = Error::missing_field("response").to_string().into_bytes();
   1131     assert_eq!(
   1132         serde_json::from_str::<Registration>(
   1133             serde_json::json!({
   1134                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1135                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1136                 "clientExtensionResults": {},
   1137                 "type": "public-key"
   1138             })
   1139             .to_string()
   1140             .as_str()
   1141         )
   1142         .unwrap_err()
   1143         .to_string()
   1144         .into_bytes()
   1145         .get(..err.len()),
   1146         Some(err.as_slice())
   1147     );
   1148     // `null` `response`.
   1149     err = Error::invalid_type(Unexpected::Other("null"), &"AuthenticatorAttestation")
   1150         .to_string()
   1151         .into_bytes();
   1152     assert_eq!(
   1153         serde_json::from_str::<Registration>(
   1154             serde_json::json!({
   1155                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1156                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1157                 "response": null,
   1158                 "clientExtensionResults": {},
   1159                 "type": "public-key"
   1160             })
   1161             .to_string()
   1162             .as_str()
   1163         )
   1164         .unwrap_err()
   1165         .to_string()
   1166         .into_bytes()
   1167         .get(..err.len()),
   1168         Some(err.as_slice())
   1169     );
   1170     // Empty `response`.
   1171     err = Error::missing_field("clientDataJSON")
   1172         .to_string()
   1173         .into_bytes();
   1174     assert_eq!(
   1175         serde_json::from_str::<Registration>(
   1176             serde_json::json!({
   1177                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1178                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1179                 "response": {},
   1180                 "clientExtensionResults": {},
   1181                 "type": "public-key"
   1182             })
   1183             .to_string()
   1184             .as_str()
   1185         )
   1186         .unwrap_err()
   1187         .to_string()
   1188         .into_bytes()
   1189         .get(..err.len()),
   1190         Some(err.as_slice())
   1191     );
   1192     // Missing `clientExtensionResults`.
   1193     err = Error::missing_field("clientExtensionResults")
   1194         .to_string()
   1195         .into_bytes();
   1196     assert_eq!(
   1197         serde_json::from_str::<Registration>(
   1198             serde_json::json!({
   1199                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1200                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1201                 "response": {
   1202                     "clientDataJSON": b64_cdata_json,
   1203                     "authenticatorData": b64_adata,
   1204                     "transports": [],
   1205                     "publicKey": b64_key,
   1206                     "publicKeyAlgorithm": -8i8,
   1207                     "attestationObject": b64_aobj,
   1208                 },
   1209                 "type": "public-key"
   1210             })
   1211             .to_string()
   1212             .as_str()
   1213         )
   1214         .unwrap_err()
   1215         .to_string()
   1216         .into_bytes()
   1217         .get(..err.len()),
   1218         Some(err.as_slice())
   1219     );
   1220     // `null` `clientExtensionResults`.
   1221     err = Error::invalid_type(
   1222         Unexpected::Other("null"),
   1223         &"clientExtensionResults to be a map of allowed client extensions",
   1224     )
   1225     .to_string()
   1226     .into_bytes();
   1227     assert_eq!(
   1228         serde_json::from_str::<Registration>(
   1229             serde_json::json!({
   1230                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1231                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1232                 "response": {
   1233                     "clientDataJSON": b64_cdata_json,
   1234                     "authenticatorData": b64_adata,
   1235                     "transports": [],
   1236                     "publicKey": b64_key,
   1237                     "publicKeyAlgorithm": -8i8,
   1238                     "attestationObject": b64_aobj,
   1239                 },
   1240                 "clientExtensionResults": null,
   1241                 "type": "public-key"
   1242             })
   1243             .to_string()
   1244             .as_str()
   1245         )
   1246         .unwrap_err()
   1247         .to_string()
   1248         .into_bytes()
   1249         .get(..err.len()),
   1250         Some(err.as_slice())
   1251     );
   1252     // Missing `type`.
   1253     err = Error::missing_field("type").to_string().into_bytes();
   1254     assert_eq!(
   1255         serde_json::from_str::<Registration>(
   1256             serde_json::json!({
   1257                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1258                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1259                 "response": {
   1260                     "clientDataJSON": b64_cdata_json,
   1261                     "authenticatorData": b64_adata,
   1262                     "transports": [],
   1263                     "publicKey": b64_key,
   1264                     "publicKeyAlgorithm": -8i8,
   1265                     "attestationObject": b64_aobj,
   1266                 },
   1267                 "clientExtensionResults": {},
   1268             })
   1269             .to_string()
   1270             .as_str()
   1271         )
   1272         .unwrap_err()
   1273         .to_string()
   1274         .into_bytes()
   1275         .get(..err.len()),
   1276         Some(err.as_slice())
   1277     );
   1278     // `null` `type`.
   1279     err = Error::invalid_type(Unexpected::Other("null"), &"public-key")
   1280         .to_string()
   1281         .into_bytes();
   1282     assert_eq!(
   1283         serde_json::from_str::<Registration>(
   1284             serde_json::json!({
   1285                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1286                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1287                 "response": {
   1288                     "clientDataJSON": b64_cdata_json,
   1289                     "authenticatorData": b64_adata,
   1290                     "transports": [],
   1291                     "publicKey": b64_key,
   1292                     "publicKeyAlgorithm": -8i8,
   1293                     "attestationObject": b64_aobj,
   1294                 },
   1295                 "clientExtensionResults": {},
   1296                 "type": null
   1297             })
   1298             .to_string()
   1299             .as_str()
   1300         )
   1301         .unwrap_err()
   1302         .to_string()
   1303         .into_bytes()
   1304         .get(..err.len()),
   1305         Some(err.as_slice())
   1306     );
   1307     // Not exactly `public-type` `type`.
   1308     err = Error::invalid_value(Unexpected::Str("Public-key"), &"public-key")
   1309         .to_string()
   1310         .into_bytes();
   1311     assert_eq!(
   1312         serde_json::from_str::<Registration>(
   1313             serde_json::json!({
   1314                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1315                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1316                 "response": {
   1317                     "clientDataJSON": b64_cdata_json,
   1318                     "authenticatorData": b64_adata,
   1319                     "transports": [],
   1320                     "publicKey": b64_key,
   1321                     "publicKeyAlgorithm": -8i8,
   1322                     "attestationObject": b64_aobj,
   1323                 },
   1324                 "clientExtensionResults": {},
   1325                 "type": "Public-key"
   1326             })
   1327             .to_string()
   1328             .as_str()
   1329         )
   1330         .unwrap_err()
   1331         .to_string()
   1332         .into_bytes()
   1333         .get(..err.len()),
   1334         Some(err.as_slice())
   1335     );
   1336     // `null`.
   1337     err = Error::invalid_type(Unexpected::Other("null"), &"PublicKeyCredential")
   1338         .to_string()
   1339         .into_bytes();
   1340     assert_eq!(
   1341         serde_json::from_str::<Registration>(serde_json::json!(null).to_string().as_str())
   1342             .unwrap_err()
   1343             .to_string()
   1344             .into_bytes()
   1345             .get(..err.len()),
   1346         Some(err.as_slice())
   1347     );
   1348     // Empty.
   1349     err = Error::missing_field("response").to_string().into_bytes();
   1350     assert_eq!(
   1351         serde_json::from_str::<Registration>(serde_json::json!({}).to_string().as_str())
   1352             .unwrap_err()
   1353             .to_string()
   1354             .into_bytes()
   1355             .get(..err.len()),
   1356         Some(err.as_slice())
   1357     );
   1358     // Unknown field in `response`.
   1359     err = Error::unknown_field(
   1360         "foo",
   1361         [
   1362             "clientDataJSON",
   1363             "attestationObject",
   1364             "authenticatorData",
   1365             "transports",
   1366             "publicKey",
   1367             "publicKeyAlgorithm",
   1368         ]
   1369         .as_slice(),
   1370     )
   1371     .to_string()
   1372     .into_bytes();
   1373     assert_eq!(
   1374         serde_json::from_str::<Registration>(
   1375             serde_json::json!({
   1376                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1377                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1378                 "response": {
   1379                     "clientDataJSON": b64_cdata_json,
   1380                     "authenticatorData": b64_adata,
   1381                     "transports": [],
   1382                     "publicKey": b64_key,
   1383                     "publicKeyAlgorithm": -8i8,
   1384                     "attestationObject": b64_aobj,
   1385                     "foo": true,
   1386                 },
   1387                 "clientExtensionResults": {},
   1388                 "type": "public-key"
   1389             })
   1390             .to_string()
   1391             .as_str()
   1392         )
   1393         .unwrap_err()
   1394         .to_string()
   1395         .into_bytes()
   1396         .get(..err.len()),
   1397         Some(err.as_slice())
   1398     );
   1399     // Duplicate field in `response`.
   1400     err = Error::duplicate_field("transports")
   1401         .to_string()
   1402         .into_bytes();
   1403     assert_eq!(
   1404         serde_json::from_str::<Registration>(
   1405             format!(
   1406                 "{{
   1407                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1408                    \"rawId\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1409                    \"response\": {{
   1410                        \"clientDataJSON\": \"{b64_cdata_json}\",
   1411                        \"authenticatorData\": \"{b64_adata}\",
   1412                        \"transports\": [],
   1413                        \"publicKey\": \"{b64_key}\",
   1414                        \"publicKeyAlgorithm\": -8,
   1415                        \"attestationObject\": \"{b64_aobj}\",
   1416                        \"transports\": []
   1417                    }},
   1418                    \"clientExtensionResults\": {{}},
   1419                    \"type\": \"public-key\"
   1420                         
   1421                  }}"
   1422             )
   1423             .as_str()
   1424         )
   1425         .unwrap_err()
   1426         .to_string()
   1427         .into_bytes()
   1428         .get(..err.len()),
   1429         Some(err.as_slice())
   1430     );
   1431     // Unknown field in `PublicKeyCredential`.
   1432     err = Error::unknown_field(
   1433         "foo",
   1434         [
   1435             "id",
   1436             "type",
   1437             "rawId",
   1438             "response",
   1439             "authenticatorAttachment",
   1440             "clientExtensionResults",
   1441         ]
   1442         .as_slice(),
   1443     )
   1444     .to_string()
   1445     .into_bytes();
   1446     assert_eq!(
   1447         serde_json::from_str::<Registration>(
   1448             serde_json::json!({
   1449                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1450                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1451                 "response": {
   1452                     "clientDataJSON": b64_cdata_json,
   1453                     "authenticatorData": b64_adata,
   1454                     "transports": [],
   1455                     "publicKey": b64_key,
   1456                     "publicKeyAlgorithm": -8i8,
   1457                     "attestationObject": b64_aobj
   1458                 },
   1459                 "clientExtensionResults": {},
   1460                 "type": "public-key",
   1461                 "foo": true,
   1462             })
   1463             .to_string()
   1464             .as_str()
   1465         )
   1466         .unwrap_err()
   1467         .to_string()
   1468         .into_bytes()
   1469         .get(..err.len()),
   1470         Some(err.as_slice())
   1471     );
   1472     // Duplicate field in `PublicKeyCredential`.
   1473     err = Error::duplicate_field("id").to_string().into_bytes();
   1474     assert_eq!(
   1475         serde_json::from_str::<Registration>(
   1476             format!(
   1477                 "{{
   1478                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1479                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1480                    \"rawId\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1481                    \"response\": {{
   1482                        \"clientDataJSON\": \"{b64_cdata_json}\",
   1483                        \"authenticatorData\": \"{b64_adata}\",
   1484                        \"transports\": [],
   1485                        \"publicKey\": \"{b64_key}\",
   1486                        \"publicKeyAlgorithm\": -8,
   1487                        \"attestationObject\": \"{b64_aobj}\"
   1488                    }},
   1489                    \"clientExtensionResults\": {{}},
   1490                    \"type\": \"public-key\"
   1491                         
   1492                  }}"
   1493             )
   1494             .as_str()
   1495         )
   1496         .unwrap_err()
   1497         .to_string()
   1498         .into_bytes()
   1499         .get(..err.len()),
   1500         Some(err.as_slice())
   1501     );
   1502 }
   1503 #[expect(clippy::unwrap_used, reason = "OK in tests")]
   1504 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
   1505 #[expect(
   1506     clippy::cognitive_complexity,
   1507     clippy::too_many_lines,
   1508     reason = "a lot to test"
   1509 )]
   1510 #[test]
   1511 fn client_extensions() {
   1512     let c_data_json = serde_json::json!({}).to_string();
   1513     let att_obj: [u8; 143] = [
   1514         cbor::MAP_3,
   1515         cbor::TEXT_3,
   1516         b'f',
   1517         b'm',
   1518         b't',
   1519         cbor::TEXT_4,
   1520         b'n',
   1521         b'o',
   1522         b'n',
   1523         b'e',
   1524         cbor::TEXT_7,
   1525         b'a',
   1526         b't',
   1527         b't',
   1528         b'S',
   1529         b't',
   1530         b'm',
   1531         b't',
   1532         cbor::MAP_0,
   1533         cbor::TEXT_8,
   1534         b'a',
   1535         b'u',
   1536         b't',
   1537         b'h',
   1538         b'D',
   1539         b'a',
   1540         b't',
   1541         b'a',
   1542         cbor::BYTES_INFO_24,
   1543         113,
   1544         // `rpIdHash`.
   1545         0,
   1546         0,
   1547         0,
   1548         0,
   1549         0,
   1550         0,
   1551         0,
   1552         0,
   1553         0,
   1554         0,
   1555         0,
   1556         0,
   1557         0,
   1558         0,
   1559         0,
   1560         0,
   1561         0,
   1562         0,
   1563         0,
   1564         0,
   1565         0,
   1566         0,
   1567         0,
   1568         0,
   1569         0,
   1570         0,
   1571         0,
   1572         0,
   1573         0,
   1574         0,
   1575         0,
   1576         0,
   1577         // `flags`.
   1578         0b0100_0101,
   1579         // `signCount`.
   1580         0,
   1581         0,
   1582         0,
   1583         0,
   1584         // `aaguid`.
   1585         0,
   1586         0,
   1587         0,
   1588         0,
   1589         0,
   1590         0,
   1591         0,
   1592         0,
   1593         0,
   1594         0,
   1595         0,
   1596         0,
   1597         0,
   1598         0,
   1599         0,
   1600         0,
   1601         // `credentialIdLength`.
   1602         0,
   1603         16,
   1604         // `credentialId`.
   1605         0,
   1606         0,
   1607         0,
   1608         0,
   1609         0,
   1610         0,
   1611         0,
   1612         0,
   1613         0,
   1614         0,
   1615         0,
   1616         0,
   1617         0,
   1618         0,
   1619         0,
   1620         0,
   1621         // Ed25519 COSE key.
   1622         cbor::MAP_4,
   1623         KTY,
   1624         OKP,
   1625         ALG,
   1626         EDDSA,
   1627         // `crv`.
   1628         cbor::NEG_ONE,
   1629         // `Ed25519`.
   1630         cbor::SIX,
   1631         // `x`.
   1632         cbor::NEG_TWO,
   1633         cbor::BYTES_INFO_24,
   1634         32,
   1635         // Compressed y-coordinate.
   1636         1,
   1637         1,
   1638         1,
   1639         1,
   1640         1,
   1641         1,
   1642         1,
   1643         1,
   1644         1,
   1645         1,
   1646         1,
   1647         1,
   1648         1,
   1649         1,
   1650         1,
   1651         1,
   1652         1,
   1653         1,
   1654         1,
   1655         1,
   1656         1,
   1657         1,
   1658         1,
   1659         1,
   1660         1,
   1661         1,
   1662         1,
   1663         1,
   1664         1,
   1665         1,
   1666         1,
   1667         1,
   1668     ];
   1669     let pub_key = VerifyingKey::from_bytes(&[1; 32])
   1670         .unwrap()
   1671         .to_public_key_der()
   1672         .unwrap();
   1673     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
   1674     let b64_adata = base64url_nopad::encode(&att_obj[att_obj.len() - 113..]);
   1675     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
   1676     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
   1677     // Base case is valid.
   1678     assert!(
   1679         serde_json::from_str::<Registration>(
   1680             serde_json::json!({
   1681                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1682                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1683                 "response": {
   1684                     "clientDataJSON": b64_cdata_json,
   1685                     "authenticatorData": b64_adata,
   1686                     "transports": [],
   1687                     "publicKey": b64_key,
   1688                     "publicKeyAlgorithm": -8i8,
   1689                     "attestationObject": b64_aobj,
   1690                 },
   1691                 "clientExtensionResults": {},
   1692                 "type": "public-key"
   1693             })
   1694             .to_string()
   1695             .as_str()
   1696         )
   1697         .is_ok_and(
   1698             |reg| reg.response.client_data_json == c_data_json.as_bytes()
   1699                 && reg.response.attestation_object_and_c_data_hash[..att_obj.len()] == att_obj
   1700                 && reg.response.attestation_object_and_c_data_hash[att_obj.len()..]
   1701                     == *Sha256::digest(c_data_json.as_bytes())
   1702                 && reg.response.transports.is_empty()
   1703                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
   1704                 && reg.client_extension_results.cred_props.is_none()
   1705                 && reg.client_extension_results.prf.is_none()
   1706         )
   1707     );
   1708     // `null` `credProps`.
   1709     assert!(
   1710         serde_json::from_str::<Registration>(
   1711             serde_json::json!({
   1712                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1713                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1714                 "response": {
   1715                     "clientDataJSON": b64_cdata_json,
   1716                     "authenticatorData": b64_adata,
   1717                     "transports": [],
   1718                     "publicKey": b64_key,
   1719                     "publicKeyAlgorithm": -8i8,
   1720                     "attestationObject": b64_aobj,
   1721                 },
   1722                 "clientExtensionResults": {
   1723                     "credProps": null
   1724                 },
   1725                 "type": "public-key"
   1726             })
   1727             .to_string()
   1728             .as_str()
   1729         )
   1730         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   1731             && reg.client_extension_results.prf.is_none())
   1732     );
   1733     // `null` `prf`.
   1734     assert!(
   1735         serde_json::from_str::<Registration>(
   1736             serde_json::json!({
   1737                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1738                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1739                 "response": {
   1740                     "clientDataJSON": b64_cdata_json,
   1741                     "authenticatorData": b64_adata,
   1742                     "transports": [],
   1743                     "publicKey": b64_key,
   1744                     "publicKeyAlgorithm": -8i8,
   1745                     "attestationObject": b64_aobj,
   1746                 },
   1747                 "clientExtensionResults": {
   1748                     "prf": null
   1749                 },
   1750                 "type": "public-key"
   1751             })
   1752             .to_string()
   1753             .as_str()
   1754         )
   1755         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   1756             && reg.client_extension_results.prf.is_none())
   1757     );
   1758     // Unknown `clientExtensionResults`.
   1759     let mut err = Error::unknown_field("CredProps", ["credProps", "prf"].as_slice())
   1760         .to_string()
   1761         .into_bytes();
   1762     assert_eq!(
   1763         serde_json::from_str::<Registration>(
   1764             serde_json::json!({
   1765                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1766                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1767                 "response": {
   1768                     "clientDataJSON": b64_cdata_json,
   1769                     "authenticatorData": b64_adata,
   1770                     "transports": [],
   1771                     "publicKey": b64_key,
   1772                     "publicKeyAlgorithm": -8i8,
   1773                     "attestationObject": b64_aobj,
   1774                 },
   1775                 "clientExtensionResults": {
   1776                     "CredProps": {
   1777                         "rk": true
   1778                     }
   1779                 },
   1780                 "type": "public-key"
   1781             })
   1782             .to_string()
   1783             .as_str()
   1784         )
   1785         .unwrap_err()
   1786         .to_string()
   1787         .into_bytes()
   1788         .get(..err.len()),
   1789         Some(err.as_slice())
   1790     );
   1791     // Duplicate field.
   1792     err = Error::duplicate_field("credProps").to_string().into_bytes();
   1793     assert_eq!(
   1794         serde_json::from_str::<Registration>(
   1795             format!(
   1796                 "{{
   1797                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1798                    \"rawId\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   1799                    \"response\": {{
   1800                        \"clientDataJSON\": \"{b64_cdata_json}\",
   1801                        \"authenticatorData\": \"{b64_adata}\",
   1802                        \"transports\": [],
   1803                        \"publicKey\": \"{b64_key}\",
   1804                        \"publicKeyAlgorithm\": -8,
   1805                        \"attestationObject\": \"{b64_aobj}\"
   1806                    }},
   1807                    \"clientExtensionResults\": {{
   1808                        \"credProps\": null,
   1809                        \"credProps\": null
   1810                    }},
   1811                    \"type\": \"public-key\"
   1812                  }}"
   1813             )
   1814             .as_str()
   1815         )
   1816         .unwrap_err()
   1817         .to_string()
   1818         .into_bytes()
   1819         .get(..err.len()),
   1820         Some(err.as_slice())
   1821     );
   1822     // `null` `rk`.
   1823     assert!(
   1824         serde_json::from_str::<Registration>(
   1825             serde_json::json!({
   1826                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1827                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1828                 "response": {
   1829                     "clientDataJSON": b64_cdata_json,
   1830                     "authenticatorData": b64_adata,
   1831                     "transports": [],
   1832                     "publicKey": b64_key,
   1833                     "publicKeyAlgorithm": -8i8,
   1834                     "attestationObject": b64_aobj,
   1835                 },
   1836                 "clientExtensionResults": {
   1837                     "credProps": {
   1838                         "rk": null
   1839                     }
   1840                 },
   1841                 "type": "public-key"
   1842             })
   1843             .to_string()
   1844             .as_str()
   1845         )
   1846         .is_ok_and(|reg| reg
   1847             .client_extension_results
   1848             .cred_props
   1849             .is_some_and(|props| props.rk.is_none())
   1850             && reg.client_extension_results.prf.is_none())
   1851     );
   1852     // Missing `rk`.
   1853     assert!(
   1854         serde_json::from_str::<Registration>(
   1855             serde_json::json!({
   1856                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1857                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1858                 "response": {
   1859                     "clientDataJSON": b64_cdata_json,
   1860                     "authenticatorData": b64_adata,
   1861                     "transports": [],
   1862                     "publicKey": b64_key,
   1863                     "publicKeyAlgorithm": -8i8,
   1864                     "attestationObject": b64_aobj,
   1865                 },
   1866                 "clientExtensionResults": {
   1867                     "credProps": {}
   1868                 },
   1869                 "type": "public-key"
   1870             })
   1871             .to_string()
   1872             .as_str()
   1873         )
   1874         .is_ok_and(|reg| reg
   1875             .client_extension_results
   1876             .cred_props
   1877             .is_some_and(|props| props.rk.is_none())
   1878             && reg.client_extension_results.prf.is_none())
   1879     );
   1880     // `true` rk`.
   1881     assert!(
   1882         serde_json::from_str::<Registration>(
   1883             serde_json::json!({
   1884                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1885                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1886                 "response": {
   1887                     "clientDataJSON": b64_cdata_json,
   1888                     "authenticatorData": b64_adata,
   1889                     "transports": [],
   1890                     "publicKey": b64_key,
   1891                     "publicKeyAlgorithm": -8i8,
   1892                     "attestationObject": b64_aobj,
   1893                 },
   1894                 "clientExtensionResults": {
   1895                     "credProps": {
   1896                         "rk": true
   1897                     }
   1898                 },
   1899                 "type": "public-key"
   1900             })
   1901             .to_string()
   1902             .as_str()
   1903         )
   1904         .is_ok_and(|reg| reg
   1905             .client_extension_results
   1906             .cred_props
   1907             .is_some_and(|props| props.rk.unwrap_or_default())
   1908             && reg.client_extension_results.prf.is_none())
   1909     );
   1910     // `false` rk`.
   1911     assert!(
   1912         serde_json::from_str::<Registration>(
   1913             serde_json::json!({
   1914                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1915                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1916                 "response": {
   1917                     "clientDataJSON": b64_cdata_json,
   1918                     "authenticatorData": b64_adata,
   1919                     "transports": [],
   1920                     "publicKey": b64_key,
   1921                     "publicKeyAlgorithm": -8i8,
   1922                     "attestationObject": b64_aobj,
   1923                 },
   1924                 "clientExtensionResults": {
   1925                     "credProps": {
   1926                         "rk": false
   1927                     }
   1928                 },
   1929                 "type": "public-key"
   1930             })
   1931             .to_string()
   1932             .as_str()
   1933         )
   1934         .is_ok_and(|reg| reg
   1935             .client_extension_results
   1936             .cred_props
   1937             .is_some_and(|props| props.rk.is_some_and(|rk| !rk))
   1938             && reg.client_extension_results.prf.is_none())
   1939     );
   1940     // Invalid `rk`.
   1941     err = Error::invalid_type(Unexpected::Unsigned(3), &"a boolean")
   1942         .to_string()
   1943         .into_bytes();
   1944     assert_eq!(
   1945         serde_json::from_str::<Registration>(
   1946             serde_json::json!({
   1947                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1948                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1949                 "response": {
   1950                     "clientDataJSON": b64_cdata_json,
   1951                     "authenticatorData": b64_adata,
   1952                     "transports": [],
   1953                     "publicKey": b64_key,
   1954                     "publicKeyAlgorithm": -8i8,
   1955                     "attestationObject": b64_aobj,
   1956                 },
   1957                 "clientExtensionResults": {
   1958                     "credProps": {
   1959                         "rk": 3u8
   1960                     }
   1961                 },
   1962                 "type": "public-key"
   1963             })
   1964             .to_string()
   1965             .as_str()
   1966         )
   1967         .unwrap_err()
   1968         .to_string()
   1969         .into_bytes()
   1970         .get(..err.len()),
   1971         Some(err.as_slice())
   1972     );
   1973     // Unknown `credProps` field.
   1974     err = Error::unknown_field("Rk", ["rk"].as_slice())
   1975         .to_string()
   1976         .into_bytes();
   1977     assert_eq!(
   1978         serde_json::from_str::<Registration>(
   1979             serde_json::json!({
   1980                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   1981                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   1982                 "response": {
   1983                     "clientDataJSON": b64_cdata_json,
   1984                     "authenticatorData": b64_adata,
   1985                     "transports": [],
   1986                     "publicKey": b64_key,
   1987                     "publicKeyAlgorithm": -8i8,
   1988                     "attestationObject": b64_aobj,
   1989                 },
   1990                 "clientExtensionResults": {
   1991                     "credProps": {
   1992                         "Rk": true,
   1993                     }
   1994                 },
   1995                 "type": "public-key"
   1996             })
   1997             .to_string()
   1998             .as_str()
   1999         )
   2000         .unwrap_err()
   2001         .to_string()
   2002         .into_bytes()
   2003         .get(..err.len()),
   2004         Some(err.as_slice())
   2005     );
   2006     // Duplicate field in `credProps`.
   2007     err = Error::duplicate_field("rk").to_string().into_bytes();
   2008     assert_eq!(
   2009         serde_json::from_str::<Registration>(
   2010             format!(
   2011                 "{{
   2012                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   2013                    \"rawId\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   2014                    \"response\": {{
   2015                        \"clientDataJSON\": \"{b64_cdata_json}\",
   2016                        \"authenticatorData\": \"{b64_adata}\",
   2017                        \"transports\": [],
   2018                        \"publicKey\": \"{b64_key}\",
   2019                        \"publicKeyAlgorithm\": -8,
   2020                        \"attestationObject\": \"{b64_aobj}\"
   2021                    }},
   2022                    \"clientExtensionResults\": {{
   2023                        \"credProps\": {{
   2024                            \"rk\": true,
   2025                            \"rk\": true
   2026                        }}
   2027                    }},
   2028                    \"type\": \"public-key\"
   2029                  }}"
   2030             )
   2031             .as_str()
   2032         )
   2033         .unwrap_err()
   2034         .to_string()
   2035         .into_bytes()
   2036         .get(..err.len()),
   2037         Some(err.as_slice())
   2038     );
   2039     // `null` `enabled`.
   2040     err = Error::invalid_type(Unexpected::Other("null"), &"a boolean")
   2041         .to_string()
   2042         .into_bytes();
   2043     assert_eq!(
   2044         serde_json::from_str::<Registration>(
   2045             serde_json::json!({
   2046                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2047                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2048                 "response": {
   2049                     "clientDataJSON": b64_cdata_json,
   2050                     "authenticatorData": b64_adata,
   2051                     "transports": [],
   2052                     "publicKey": b64_key,
   2053                     "publicKeyAlgorithm": -8i8,
   2054                     "attestationObject": b64_aobj,
   2055                 },
   2056                 "clientExtensionResults": {
   2057                     "prf": {
   2058                         "enabled": null
   2059                     }
   2060                 },
   2061                 "type": "public-key"
   2062             })
   2063             .to_string()
   2064             .as_str()
   2065         )
   2066         .unwrap_err()
   2067         .to_string()
   2068         .into_bytes()
   2069         .get(..err.len()),
   2070         Some(err.as_slice())
   2071     );
   2072     // Missing `enabled`.
   2073     err = Error::missing_field("enabled").to_string().into_bytes();
   2074     assert_eq!(
   2075         serde_json::from_str::<Registration>(
   2076             serde_json::json!({
   2077                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2078                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2079                 "response": {
   2080                     "clientDataJSON": b64_cdata_json,
   2081                     "authenticatorData": b64_adata,
   2082                     "transports": [],
   2083                     "publicKey": b64_key,
   2084                     "publicKeyAlgorithm": -8i8,
   2085                     "attestationObject": b64_aobj,
   2086                 },
   2087                 "clientExtensionResults": {
   2088                     "prf": {}
   2089                 },
   2090                 "type": "public-key"
   2091             })
   2092             .to_string()
   2093             .as_str()
   2094         )
   2095         .unwrap_err()
   2096         .to_string()
   2097         .into_bytes()
   2098         .get(..err.len()),
   2099         Some(err.as_slice())
   2100     );
   2101     // `true` `enabled`.
   2102     assert!(
   2103         serde_json::from_str::<Registration>(
   2104             serde_json::json!({
   2105                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2106                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2107                 "response": {
   2108                     "clientDataJSON": b64_cdata_json,
   2109                     "authenticatorData": b64_adata,
   2110                     "transports": [],
   2111                     "publicKey": b64_key,
   2112                     "publicKeyAlgorithm": -8i8,
   2113                     "attestationObject": b64_aobj,
   2114                 },
   2115                 "clientExtensionResults": {
   2116                     "prf": {
   2117                         "enabled": true
   2118                     }
   2119                 },
   2120                 "type": "public-key"
   2121             })
   2122             .to_string()
   2123             .as_str()
   2124         )
   2125         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   2126             && reg
   2127                 .client_extension_results
   2128                 .prf
   2129                 .is_some_and(|prf| prf.enabled))
   2130     );
   2131     // `false` `enabled`.
   2132     assert!(
   2133         serde_json::from_str::<Registration>(
   2134             serde_json::json!({
   2135                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2136                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2137                 "response": {
   2138                     "clientDataJSON": b64_cdata_json,
   2139                     "authenticatorData": b64_adata,
   2140                     "transports": [],
   2141                     "publicKey": b64_key,
   2142                     "publicKeyAlgorithm": -8i8,
   2143                     "attestationObject": b64_aobj,
   2144                 },
   2145                 "clientExtensionResults": {
   2146                     "prf": {
   2147                         "enabled": false,
   2148                     }
   2149                 },
   2150                 "type": "public-key"
   2151             })
   2152             .to_string()
   2153             .as_str()
   2154         )
   2155         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   2156             && reg
   2157                 .client_extension_results
   2158                 .prf
   2159                 .is_some_and(|prf| !prf.enabled))
   2160     );
   2161     // Invalid `enabled`.
   2162     err = Error::invalid_type(Unexpected::Unsigned(3), &"a boolean")
   2163         .to_string()
   2164         .into_bytes();
   2165     assert_eq!(
   2166         serde_json::from_str::<Registration>(
   2167             serde_json::json!({
   2168                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2169                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2170                 "response": {
   2171                     "clientDataJSON": b64_cdata_json,
   2172                     "authenticatorData": b64_adata,
   2173                     "transports": [],
   2174                     "publicKey": b64_key,
   2175                     "publicKeyAlgorithm": -8i8,
   2176                     "attestationObject": b64_aobj,
   2177                 },
   2178                 "clientExtensionResults": {
   2179                     "prf": {
   2180                         "enabled": 3u8
   2181                     }
   2182                 },
   2183                 "type": "public-key"
   2184             })
   2185             .to_string()
   2186             .as_str()
   2187         )
   2188         .unwrap_err()
   2189         .to_string()
   2190         .into_bytes()
   2191         .get(..err.len()),
   2192         Some(err.as_slice())
   2193     );
   2194     // `null` `results` with `enabled` `true`.
   2195     assert!(
   2196         serde_json::from_str::<Registration>(
   2197             serde_json::json!({
   2198                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2199                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2200                 "response": {
   2201                     "clientDataJSON": b64_cdata_json,
   2202                     "authenticatorData": b64_adata,
   2203                     "transports": [],
   2204                     "publicKey": b64_key,
   2205                     "publicKeyAlgorithm": -8i8,
   2206                     "attestationObject": b64_aobj,
   2207                 },
   2208                 "clientExtensionResults": {
   2209                     "prf": {
   2210                         "enabled": true,
   2211                         "results": null,
   2212                     }
   2213                 },
   2214                 "type": "public-key"
   2215             })
   2216             .to_string()
   2217             .as_str()
   2218         )
   2219         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   2220             && reg
   2221                 .client_extension_results
   2222                 .prf
   2223                 .is_some_and(|prf| prf.enabled))
   2224     );
   2225     // `null` `results` with `enabled` `false`.
   2226     err = Error::custom(
   2227         "prf must not have 'results', including a null 'results', if 'enabled' is false",
   2228     )
   2229     .to_string()
   2230     .into_bytes();
   2231     assert_eq!(
   2232         serde_json::from_str::<Registration>(
   2233             serde_json::json!({
   2234                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2235                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2236                 "response": {
   2237                     "clientDataJSON": b64_cdata_json,
   2238                     "authenticatorData": b64_adata,
   2239                     "transports": [],
   2240                     "publicKey": b64_key,
   2241                     "publicKeyAlgorithm": -8i8,
   2242                     "attestationObject": b64_aobj,
   2243                 },
   2244                 "clientExtensionResults": {
   2245                     "prf": {
   2246                         "enabled": false,
   2247                         "results": null
   2248                     }
   2249                 },
   2250                 "type": "public-key"
   2251             })
   2252             .to_string()
   2253             .as_str()
   2254         )
   2255         .unwrap_err()
   2256         .to_string()
   2257         .into_bytes()
   2258         .get(..err.len()),
   2259         Some(err.as_slice())
   2260     );
   2261     // Duplicate field in `prf`.
   2262     err = Error::duplicate_field("enabled").to_string().into_bytes();
   2263     assert_eq!(
   2264         serde_json::from_str::<Registration>(
   2265             format!(
   2266                 "{{
   2267                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   2268                    \"rawId\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   2269                    \"response\": {{
   2270                        \"clientDataJSON\": \"{b64_cdata_json}\",
   2271                        \"authenticatorData\": \"{b64_adata}\",
   2272                        \"transports\": [],
   2273                        \"publicKey\": \"{b64_key}\",
   2274                        \"publicKeyAlgorithm\": -8,
   2275                        \"attestationObject\": \"{b64_aobj}\"
   2276                    }},
   2277                    \"clientExtensionResults\": {{
   2278                        \"prf\": {{
   2279                            \"enabled\": true,
   2280                            \"enabled\": true
   2281                        }}
   2282                    }},
   2283                    \"type\": \"public-key\"
   2284                  }}"
   2285             )
   2286             .as_str()
   2287         )
   2288         .unwrap_err()
   2289         .to_string()
   2290         .into_bytes()
   2291         .get(..err.len()),
   2292         Some(err.as_slice())
   2293     );
   2294     // Missing `first`.
   2295     err = Error::missing_field("first").to_string().into_bytes();
   2296     assert_eq!(
   2297         serde_json::from_str::<Registration>(
   2298             serde_json::json!({
   2299                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2300                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2301                 "response": {
   2302                     "clientDataJSON": b64_cdata_json,
   2303                     "authenticatorData": b64_adata,
   2304                     "transports": [],
   2305                     "publicKey": b64_key,
   2306                     "publicKeyAlgorithm": -8i8,
   2307                     "attestationObject": b64_aobj,
   2308                 },
   2309                 "clientExtensionResults": {
   2310                     "prf": {
   2311                         "enabled": true,
   2312                         "results": {},
   2313                     }
   2314                 },
   2315                 "type": "public-key"
   2316             })
   2317             .to_string()
   2318             .as_str()
   2319         )
   2320         .unwrap_err()
   2321         .to_string()
   2322         .into_bytes()
   2323         .get(..err.len()),
   2324         Some(err.as_slice())
   2325     );
   2326     // `null` `first`.
   2327     assert!(
   2328         serde_json::from_str::<Registration>(
   2329             serde_json::json!({
   2330                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2331                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2332                 "response": {
   2333                     "clientDataJSON": b64_cdata_json,
   2334                     "authenticatorData": b64_adata,
   2335                     "transports": [],
   2336                     "publicKey": b64_key,
   2337                     "publicKeyAlgorithm": -8i8,
   2338                     "attestationObject": b64_aobj,
   2339                 },
   2340                 "clientExtensionResults": {
   2341                     "prf": {
   2342                         "enabled": true,
   2343                         "results": {
   2344                             "first": null
   2345                         },
   2346                     }
   2347                 },
   2348                 "type": "public-key"
   2349             })
   2350             .to_string()
   2351             .as_str()
   2352         )
   2353         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   2354             && reg
   2355                 .client_extension_results
   2356                 .prf
   2357                 .is_some_and(|prf| prf.enabled))
   2358     );
   2359     // `null` `second`.
   2360     assert!(
   2361         serde_json::from_str::<Registration>(
   2362             serde_json::json!({
   2363                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2364                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2365                 "response": {
   2366                     "clientDataJSON": b64_cdata_json,
   2367                     "authenticatorData": b64_adata,
   2368                     "transports": [],
   2369                     "publicKey": b64_key,
   2370                     "publicKeyAlgorithm": -8i8,
   2371                     "attestationObject": b64_aobj,
   2372                 },
   2373                 "clientExtensionResults": {
   2374                     "prf": {
   2375                         "enabled": true,
   2376                         "results": {
   2377                             "first": null,
   2378                             "second": null
   2379                         },
   2380                     }
   2381                 },
   2382                 "type": "public-key"
   2383             })
   2384             .to_string()
   2385             .as_str()
   2386         )
   2387         .is_ok_and(|reg| reg.client_extension_results.cred_props.is_none()
   2388             && reg
   2389                 .client_extension_results
   2390                 .prf
   2391                 .is_some_and(|prf| prf.enabled))
   2392     );
   2393     // Non-`null` `first`.
   2394     err = Error::invalid_type(Unexpected::Option, &"null")
   2395         .to_string()
   2396         .into_bytes();
   2397     assert_eq!(
   2398         serde_json::from_str::<Registration>(
   2399             serde_json::json!({
   2400                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2401                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2402                 "response": {
   2403                     "clientDataJSON": b64_cdata_json,
   2404                     "authenticatorData": b64_adata,
   2405                     "transports": [],
   2406                     "publicKey": b64_key,
   2407                     "publicKeyAlgorithm": -8i8,
   2408                     "attestationObject": b64_aobj,
   2409                 },
   2410                 "clientExtensionResults": {
   2411                     "prf": {
   2412                         "enabled": true,
   2413                         "results": {
   2414                             "first": ""
   2415                         },
   2416                     }
   2417                 },
   2418                 "type": "public-key"
   2419             })
   2420             .to_string()
   2421             .as_str()
   2422         )
   2423         .unwrap_err()
   2424         .to_string()
   2425         .into_bytes()
   2426         .get(..err.len()),
   2427         Some(err.as_slice())
   2428     );
   2429     // Non-`null` `second`.
   2430     err = Error::invalid_type(Unexpected::Option, &"null")
   2431         .to_string()
   2432         .into_bytes();
   2433     assert_eq!(
   2434         serde_json::from_str::<Registration>(
   2435             serde_json::json!({
   2436                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2437                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2438                 "response": {
   2439                     "clientDataJSON": b64_cdata_json,
   2440                     "authenticatorData": b64_adata,
   2441                     "transports": [],
   2442                     "publicKey": b64_key,
   2443                     "publicKeyAlgorithm": -8i8,
   2444                     "attestationObject": b64_aobj,
   2445                 },
   2446                 "clientExtensionResults": {
   2447                     "prf": {
   2448                         "enabled": true,
   2449                         "results": {
   2450                             "first": null,
   2451                             "second": ""
   2452                         },
   2453                     }
   2454                 },
   2455                 "type": "public-key"
   2456             })
   2457             .to_string()
   2458             .as_str()
   2459         )
   2460         .unwrap_err()
   2461         .to_string()
   2462         .into_bytes()
   2463         .get(..err.len()),
   2464         Some(err.as_slice())
   2465     );
   2466     // Unknown `prf` field.
   2467     err = Error::unknown_field("Results", ["enabled", "results"].as_slice())
   2468         .to_string()
   2469         .into_bytes();
   2470     assert_eq!(
   2471         serde_json::from_str::<Registration>(
   2472             serde_json::json!({
   2473                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2474                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2475                 "response": {
   2476                     "clientDataJSON": b64_cdata_json,
   2477                     "authenticatorData": b64_adata,
   2478                     "transports": [],
   2479                     "publicKey": b64_key,
   2480                     "publicKeyAlgorithm": -8i8,
   2481                     "attestationObject": b64_aobj,
   2482                 },
   2483                 "clientExtensionResults": {
   2484                     "prf": {
   2485                         "enabled": true,
   2486                         "Results": null
   2487                     }
   2488                 },
   2489                 "type": "public-key"
   2490             })
   2491             .to_string()
   2492             .as_str()
   2493         )
   2494         .unwrap_err()
   2495         .to_string()
   2496         .into_bytes()
   2497         .get(..err.len()),
   2498         Some(err.as_slice())
   2499     );
   2500     // Unknown `results` field.
   2501     err = Error::unknown_field("Second", ["first", "second"].as_slice())
   2502         .to_string()
   2503         .into_bytes();
   2504     assert_eq!(
   2505         serde_json::from_str::<Registration>(
   2506             serde_json::json!({
   2507                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   2508                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   2509                 "response": {
   2510                     "clientDataJSON": b64_cdata_json,
   2511                     "authenticatorData": b64_adata,
   2512                     "transports": [],
   2513                     "publicKey": b64_key,
   2514                     "publicKeyAlgorithm": -8i8,
   2515                     "attestationObject": b64_aobj,
   2516                 },
   2517                 "clientExtensionResults": {
   2518                     "prf": {
   2519                         "enabled": true,
   2520                         "results": {
   2521                             "first": null,
   2522                             "Second": null
   2523                         }
   2524                     }
   2525                 },
   2526                 "type": "public-key"
   2527             })
   2528             .to_string()
   2529             .as_str()
   2530         )
   2531         .unwrap_err()
   2532         .to_string()
   2533         .into_bytes()
   2534         .get(..err.len()),
   2535         Some(err.as_slice())
   2536     );
   2537     // Duplicate field in `results`.
   2538     err = Error::duplicate_field("first").to_string().into_bytes();
   2539     assert_eq!(
   2540         serde_json::from_str::<Registration>(
   2541             format!(
   2542                 "{{
   2543                    \"id\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   2544                    \"rawId\": \"AAAAAAAAAAAAAAAAAAAAAA\",
   2545                    \"response\": {{
   2546                        \"clientDataJSON\": \"{b64_cdata_json}\",
   2547                        \"authenticatorData\": \"{b64_adata}\",
   2548                        \"transports\": [],
   2549                        \"publicKey\": \"{b64_key}\",
   2550                        \"publicKeyAlgorithm\": -8,
   2551                        \"attestationObject\": \"{b64_aobj}\"
   2552                    }},
   2553                    \"clientExtensionResults\": {{
   2554                        \"prf\": {{
   2555                            \"enabled\": true,
   2556                            \"results\": {{
   2557                                \"first\": null,
   2558                                \"first\": null
   2559                            }}
   2560                        }}
   2561                    }},
   2562                    \"type\": \"public-key\"
   2563                  }}"
   2564             )
   2565             .as_str()
   2566         )
   2567         .unwrap_err()
   2568         .to_string()
   2569         .into_bytes()
   2570         .get(..err.len()),
   2571         Some(err.as_slice())
   2572     );
   2573 }
   2574 #[expect(
   2575     clippy::assertions_on_result_states,
   2576     clippy::unwrap_used,
   2577     reason = "OK in tests"
   2578 )]
   2579 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
   2580 #[expect(clippy::too_many_lines, reason = "a lot to test")]
   2581 #[test]
   2582 fn mldsa87_registration_deserialize_data_mismatch() {
   2583     let c_data_json = serde_json::json!({}).to_string();
   2584     let att_obj: [u8; 2704] = [
   2585         cbor::MAP_3,
   2586         cbor::TEXT_3,
   2587         b'f',
   2588         b'm',
   2589         b't',
   2590         cbor::TEXT_4,
   2591         b'n',
   2592         b'o',
   2593         b'n',
   2594         b'e',
   2595         cbor::TEXT_7,
   2596         b'a',
   2597         b't',
   2598         b't',
   2599         b'S',
   2600         b't',
   2601         b'm',
   2602         b't',
   2603         cbor::MAP_0,
   2604         cbor::TEXT_8,
   2605         b'a',
   2606         b'u',
   2607         b't',
   2608         b'h',
   2609         b'D',
   2610         b'a',
   2611         b't',
   2612         b'a',
   2613         cbor::BYTES_INFO_25,
   2614         10,
   2615         113,
   2616         // `rpIdHash`.
   2617         0,
   2618         0,
   2619         0,
   2620         0,
   2621         0,
   2622         0,
   2623         0,
   2624         0,
   2625         0,
   2626         0,
   2627         0,
   2628         0,
   2629         0,
   2630         0,
   2631         0,
   2632         0,
   2633         0,
   2634         0,
   2635         0,
   2636         0,
   2637         0,
   2638         0,
   2639         0,
   2640         0,
   2641         0,
   2642         0,
   2643         0,
   2644         0,
   2645         0,
   2646         0,
   2647         0,
   2648         0,
   2649         // `flags`.
   2650         0b0100_0101,
   2651         // `signCount`.
   2652         0,
   2653         0,
   2654         0,
   2655         0,
   2656         // `aaguid`.
   2657         0,
   2658         0,
   2659         0,
   2660         0,
   2661         0,
   2662         0,
   2663         0,
   2664         0,
   2665         0,
   2666         0,
   2667         0,
   2668         0,
   2669         0,
   2670         0,
   2671         0,
   2672         0,
   2673         // `credentialIdLength`.
   2674         0,
   2675         16,
   2676         // `credentialId`.
   2677         0,
   2678         0,
   2679         0,
   2680         0,
   2681         0,
   2682         0,
   2683         0,
   2684         0,
   2685         0,
   2686         0,
   2687         0,
   2688         0,
   2689         0,
   2690         0,
   2691         0,
   2692         0,
   2693         // ML-DSA-87 COSE key.
   2694         cbor::MAP_3,
   2695         KTY,
   2696         AKP,
   2697         ALG,
   2698         cbor::NEG_INFO_24,
   2699         MLDSA87,
   2700         // `pub`.
   2701         cbor::NEG_ONE,
   2702         cbor::BYTES_INFO_25,
   2703         10,
   2704         32,
   2705         // Encoded key.
   2706         1,
   2707         1,
   2708         1,
   2709         1,
   2710         1,
   2711         1,
   2712         1,
   2713         1,
   2714         1,
   2715         1,
   2716         1,
   2717         1,
   2718         1,
   2719         1,
   2720         1,
   2721         1,
   2722         1,
   2723         1,
   2724         1,
   2725         1,
   2726         1,
   2727         1,
   2728         1,
   2729         1,
   2730         1,
   2731         1,
   2732         1,
   2733         1,
   2734         1,
   2735         1,
   2736         1,
   2737         1,
   2738         1,
   2739         1,
   2740         1,
   2741         1,
   2742         1,
   2743         1,
   2744         1,
   2745         1,
   2746         1,
   2747         1,
   2748         1,
   2749         1,
   2750         1,
   2751         1,
   2752         1,
   2753         1,
   2754         1,
   2755         1,
   2756         1,
   2757         1,
   2758         1,
   2759         1,
   2760         1,
   2761         1,
   2762         1,
   2763         1,
   2764         1,
   2765         1,
   2766         1,
   2767         1,
   2768         1,
   2769         1,
   2770         1,
   2771         1,
   2772         1,
   2773         1,
   2774         1,
   2775         1,
   2776         1,
   2777         1,
   2778         1,
   2779         1,
   2780         1,
   2781         1,
   2782         1,
   2783         1,
   2784         1,
   2785         1,
   2786         1,
   2787         1,
   2788         1,
   2789         1,
   2790         1,
   2791         1,
   2792         1,
   2793         1,
   2794         1,
   2795         1,
   2796         1,
   2797         1,
   2798         1,
   2799         1,
   2800         1,
   2801         1,
   2802         1,
   2803         1,
   2804         1,
   2805         1,
   2806         1,
   2807         1,
   2808         1,
   2809         1,
   2810         1,
   2811         1,
   2812         1,
   2813         1,
   2814         1,
   2815         1,
   2816         1,
   2817         1,
   2818         1,
   2819         1,
   2820         1,
   2821         1,
   2822         1,
   2823         1,
   2824         1,
   2825         1,
   2826         1,
   2827         1,
   2828         1,
   2829         1,
   2830         1,
   2831         1,
   2832         1,
   2833         1,
   2834         1,
   2835         1,
   2836         1,
   2837         1,
   2838         1,
   2839         1,
   2840         1,
   2841         1,
   2842         1,
   2843         1,
   2844         1,
   2845         1,
   2846         1,
   2847         1,
   2848         1,
   2849         1,
   2850         1,
   2851         1,
   2852         1,
   2853         1,
   2854         1,
   2855         1,
   2856         1,
   2857         1,
   2858         1,
   2859         1,
   2860         1,
   2861         1,
   2862         1,
   2863         1,
   2864         1,
   2865         1,
   2866         1,
   2867         1,
   2868         1,
   2869         1,
   2870         1,
   2871         1,
   2872         1,
   2873         1,
   2874         1,
   2875         1,
   2876         1,
   2877         1,
   2878         1,
   2879         1,
   2880         1,
   2881         1,
   2882         1,
   2883         1,
   2884         1,
   2885         1,
   2886         1,
   2887         1,
   2888         1,
   2889         1,
   2890         1,
   2891         1,
   2892         1,
   2893         1,
   2894         1,
   2895         1,
   2896         1,
   2897         1,
   2898         1,
   2899         1,
   2900         1,
   2901         1,
   2902         1,
   2903         1,
   2904         1,
   2905         1,
   2906         1,
   2907         1,
   2908         1,
   2909         1,
   2910         1,
   2911         1,
   2912         1,
   2913         1,
   2914         1,
   2915         1,
   2916         1,
   2917         1,
   2918         1,
   2919         1,
   2920         1,
   2921         1,
   2922         1,
   2923         1,
   2924         1,
   2925         1,
   2926         1,
   2927         1,
   2928         1,
   2929         1,
   2930         1,
   2931         1,
   2932         1,
   2933         1,
   2934         1,
   2935         1,
   2936         1,
   2937         1,
   2938         1,
   2939         1,
   2940         1,
   2941         1,
   2942         1,
   2943         1,
   2944         1,
   2945         1,
   2946         1,
   2947         1,
   2948         1,
   2949         1,
   2950         1,
   2951         1,
   2952         1,
   2953         1,
   2954         1,
   2955         1,
   2956         1,
   2957         1,
   2958         1,
   2959         1,
   2960         1,
   2961         1,
   2962         1,
   2963         1,
   2964         1,
   2965         1,
   2966         1,
   2967         1,
   2968         1,
   2969         1,
   2970         1,
   2971         1,
   2972         1,
   2973         1,
   2974         1,
   2975         1,
   2976         1,
   2977         1,
   2978         1,
   2979         1,
   2980         1,
   2981         1,
   2982         1,
   2983         1,
   2984         1,
   2985         1,
   2986         1,
   2987         1,
   2988         1,
   2989         1,
   2990         1,
   2991         1,
   2992         1,
   2993         1,
   2994         1,
   2995         1,
   2996         1,
   2997         1,
   2998         1,
   2999         1,
   3000         1,
   3001         1,
   3002         1,
   3003         1,
   3004         1,
   3005         1,
   3006         1,
   3007         1,
   3008         1,
   3009         1,
   3010         1,
   3011         1,
   3012         1,
   3013         1,
   3014         1,
   3015         1,
   3016         1,
   3017         1,
   3018         1,
   3019         1,
   3020         1,
   3021         1,
   3022         1,
   3023         1,
   3024         1,
   3025         1,
   3026         1,
   3027         1,
   3028         1,
   3029         1,
   3030         1,
   3031         1,
   3032         1,
   3033         1,
   3034         1,
   3035         1,
   3036         1,
   3037         1,
   3038         1,
   3039         1,
   3040         1,
   3041         1,
   3042         1,
   3043         1,
   3044         1,
   3045         1,
   3046         1,
   3047         1,
   3048         1,
   3049         1,
   3050         1,
   3051         1,
   3052         1,
   3053         1,
   3054         1,
   3055         1,
   3056         1,
   3057         1,
   3058         1,
   3059         1,
   3060         1,
   3061         1,
   3062         1,
   3063         1,
   3064         1,
   3065         1,
   3066         1,
   3067         1,
   3068         1,
   3069         1,
   3070         1,
   3071         1,
   3072         1,
   3073         1,
   3074         1,
   3075         1,
   3076         1,
   3077         1,
   3078         1,
   3079         1,
   3080         1,
   3081         1,
   3082         1,
   3083         1,
   3084         1,
   3085         1,
   3086         1,
   3087         1,
   3088         1,
   3089         1,
   3090         1,
   3091         1,
   3092         1,
   3093         1,
   3094         1,
   3095         1,
   3096         1,
   3097         1,
   3098         1,
   3099         1,
   3100         1,
   3101         1,
   3102         1,
   3103         1,
   3104         1,
   3105         1,
   3106         1,
   3107         1,
   3108         1,
   3109         1,
   3110         1,
   3111         1,
   3112         1,
   3113         1,
   3114         1,
   3115         1,
   3116         1,
   3117         1,
   3118         1,
   3119         1,
   3120         1,
   3121         1,
   3122         1,
   3123         1,
   3124         1,
   3125         1,
   3126         1,
   3127         1,
   3128         1,
   3129         1,
   3130         1,
   3131         1,
   3132         1,
   3133         1,
   3134         1,
   3135         1,
   3136         1,
   3137         1,
   3138         1,
   3139         1,
   3140         1,
   3141         1,
   3142         1,
   3143         1,
   3144         1,
   3145         1,
   3146         1,
   3147         1,
   3148         1,
   3149         1,
   3150         1,
   3151         1,
   3152         1,
   3153         1,
   3154         1,
   3155         1,
   3156         1,
   3157         1,
   3158         1,
   3159         1,
   3160         1,
   3161         1,
   3162         1,
   3163         1,
   3164         1,
   3165         1,
   3166         1,
   3167         1,
   3168         1,
   3169         1,
   3170         1,
   3171         1,
   3172         1,
   3173         1,
   3174         1,
   3175         1,
   3176         1,
   3177         1,
   3178         1,
   3179         1,
   3180         1,
   3181         1,
   3182         1,
   3183         1,
   3184         1,
   3185         1,
   3186         1,
   3187         1,
   3188         1,
   3189         1,
   3190         1,
   3191         1,
   3192         1,
   3193         1,
   3194         1,
   3195         1,
   3196         1,
   3197         1,
   3198         1,
   3199         1,
   3200         1,
   3201         1,
   3202         1,
   3203         1,
   3204         1,
   3205         1,
   3206         1,
   3207         1,
   3208         1,
   3209         1,
   3210         1,
   3211         1,
   3212         1,
   3213         1,
   3214         1,
   3215         1,
   3216         1,
   3217         1,
   3218         1,
   3219         1,
   3220         1,
   3221         1,
   3222         1,
   3223         1,
   3224         1,
   3225         1,
   3226         1,
   3227         1,
   3228         1,
   3229         1,
   3230         1,
   3231         1,
   3232         1,
   3233         1,
   3234         1,
   3235         1,
   3236         1,
   3237         1,
   3238         1,
   3239         1,
   3240         1,
   3241         1,
   3242         1,
   3243         1,
   3244         1,
   3245         1,
   3246         1,
   3247         1,
   3248         1,
   3249         1,
   3250         1,
   3251         1,
   3252         1,
   3253         1,
   3254         1,
   3255         1,
   3256         1,
   3257         1,
   3258         1,
   3259         1,
   3260         1,
   3261         1,
   3262         1,
   3263         1,
   3264         1,
   3265         1,
   3266         1,
   3267         1,
   3268         1,
   3269         1,
   3270         1,
   3271         1,
   3272         1,
   3273         1,
   3274         1,
   3275         1,
   3276         1,
   3277         1,
   3278         1,
   3279         1,
   3280         1,
   3281         1,
   3282         1,
   3283         1,
   3284         1,
   3285         1,
   3286         1,
   3287         1,
   3288         1,
   3289         1,
   3290         1,
   3291         1,
   3292         1,
   3293         1,
   3294         1,
   3295         1,
   3296         1,
   3297         1,
   3298         1,
   3299         1,
   3300         1,
   3301         1,
   3302         1,
   3303         1,
   3304         1,
   3305         1,
   3306         1,
   3307         1,
   3308         1,
   3309         1,
   3310         1,
   3311         1,
   3312         1,
   3313         1,
   3314         1,
   3315         1,
   3316         1,
   3317         1,
   3318         1,
   3319         1,
   3320         1,
   3321         1,
   3322         1,
   3323         1,
   3324         1,
   3325         1,
   3326         1,
   3327         1,
   3328         1,
   3329         1,
   3330         1,
   3331         1,
   3332         1,
   3333         1,
   3334         1,
   3335         1,
   3336         1,
   3337         1,
   3338         1,
   3339         1,
   3340         1,
   3341         1,
   3342         1,
   3343         1,
   3344         1,
   3345         1,
   3346         1,
   3347         1,
   3348         1,
   3349         1,
   3350         1,
   3351         1,
   3352         1,
   3353         1,
   3354         1,
   3355         1,
   3356         1,
   3357         1,
   3358         1,
   3359         1,
   3360         1,
   3361         1,
   3362         1,
   3363         1,
   3364         1,
   3365         1,
   3366         1,
   3367         1,
   3368         1,
   3369         1,
   3370         1,
   3371         1,
   3372         1,
   3373         1,
   3374         1,
   3375         1,
   3376         1,
   3377         1,
   3378         1,
   3379         1,
   3380         1,
   3381         1,
   3382         1,
   3383         1,
   3384         1,
   3385         1,
   3386         1,
   3387         1,
   3388         1,
   3389         1,
   3390         1,
   3391         1,
   3392         1,
   3393         1,
   3394         1,
   3395         1,
   3396         1,
   3397         1,
   3398         1,
   3399         1,
   3400         1,
   3401         1,
   3402         1,
   3403         1,
   3404         1,
   3405         1,
   3406         1,
   3407         1,
   3408         1,
   3409         1,
   3410         1,
   3411         1,
   3412         1,
   3413         1,
   3414         1,
   3415         1,
   3416         1,
   3417         1,
   3418         1,
   3419         1,
   3420         1,
   3421         1,
   3422         1,
   3423         1,
   3424         1,
   3425         1,
   3426         1,
   3427         1,
   3428         1,
   3429         1,
   3430         1,
   3431         1,
   3432         1,
   3433         1,
   3434         1,
   3435         1,
   3436         1,
   3437         1,
   3438         1,
   3439         1,
   3440         1,
   3441         1,
   3442         1,
   3443         1,
   3444         1,
   3445         1,
   3446         1,
   3447         1,
   3448         1,
   3449         1,
   3450         1,
   3451         1,
   3452         1,
   3453         1,
   3454         1,
   3455         1,
   3456         1,
   3457         1,
   3458         1,
   3459         1,
   3460         1,
   3461         1,
   3462         1,
   3463         1,
   3464         1,
   3465         1,
   3466         1,
   3467         1,
   3468         1,
   3469         1,
   3470         1,
   3471         1,
   3472         1,
   3473         1,
   3474         1,
   3475         1,
   3476         1,
   3477         1,
   3478         1,
   3479         1,
   3480         1,
   3481         1,
   3482         1,
   3483         1,
   3484         1,
   3485         1,
   3486         1,
   3487         1,
   3488         1,
   3489         1,
   3490         1,
   3491         1,
   3492         1,
   3493         1,
   3494         1,
   3495         1,
   3496         1,
   3497         1,
   3498         1,
   3499         1,
   3500         1,
   3501         1,
   3502         1,
   3503         1,
   3504         1,
   3505         1,
   3506         1,
   3507         1,
   3508         1,
   3509         1,
   3510         1,
   3511         1,
   3512         1,
   3513         1,
   3514         1,
   3515         1,
   3516         1,
   3517         1,
   3518         1,
   3519         1,
   3520         1,
   3521         1,
   3522         1,
   3523         1,
   3524         1,
   3525         1,
   3526         1,
   3527         1,
   3528         1,
   3529         1,
   3530         1,
   3531         1,
   3532         1,
   3533         1,
   3534         1,
   3535         1,
   3536         1,
   3537         1,
   3538         1,
   3539         1,
   3540         1,
   3541         1,
   3542         1,
   3543         1,
   3544         1,
   3545         1,
   3546         1,
   3547         1,
   3548         1,
   3549         1,
   3550         1,
   3551         1,
   3552         1,
   3553         1,
   3554         1,
   3555         1,
   3556         1,
   3557         1,
   3558         1,
   3559         1,
   3560         1,
   3561         1,
   3562         1,
   3563         1,
   3564         1,
   3565         1,
   3566         1,
   3567         1,
   3568         1,
   3569         1,
   3570         1,
   3571         1,
   3572         1,
   3573         1,
   3574         1,
   3575         1,
   3576         1,
   3577         1,
   3578         1,
   3579         1,
   3580         1,
   3581         1,
   3582         1,
   3583         1,
   3584         1,
   3585         1,
   3586         1,
   3587         1,
   3588         1,
   3589         1,
   3590         1,
   3591         1,
   3592         1,
   3593         1,
   3594         1,
   3595         1,
   3596         1,
   3597         1,
   3598         1,
   3599         1,
   3600         1,
   3601         1,
   3602         1,
   3603         1,
   3604         1,
   3605         1,
   3606         1,
   3607         1,
   3608         1,
   3609         1,
   3610         1,
   3611         1,
   3612         1,
   3613         1,
   3614         1,
   3615         1,
   3616         1,
   3617         1,
   3618         1,
   3619         1,
   3620         1,
   3621         1,
   3622         1,
   3623         1,
   3624         1,
   3625         1,
   3626         1,
   3627         1,
   3628         1,
   3629         1,
   3630         1,
   3631         1,
   3632         1,
   3633         1,
   3634         1,
   3635         1,
   3636         1,
   3637         1,
   3638         1,
   3639         1,
   3640         1,
   3641         1,
   3642         1,
   3643         1,
   3644         1,
   3645         1,
   3646         1,
   3647         1,
   3648         1,
   3649         1,
   3650         1,
   3651         1,
   3652         1,
   3653         1,
   3654         1,
   3655         1,
   3656         1,
   3657         1,
   3658         1,
   3659         1,
   3660         1,
   3661         1,
   3662         1,
   3663         1,
   3664         1,
   3665         1,
   3666         1,
   3667         1,
   3668         1,
   3669         1,
   3670         1,
   3671         1,
   3672         1,
   3673         1,
   3674         1,
   3675         1,
   3676         1,
   3677         1,
   3678         1,
   3679         1,
   3680         1,
   3681         1,
   3682         1,
   3683         1,
   3684         1,
   3685         1,
   3686         1,
   3687         1,
   3688         1,
   3689         1,
   3690         1,
   3691         1,
   3692         1,
   3693         1,
   3694         1,
   3695         1,
   3696         1,
   3697         1,
   3698         1,
   3699         1,
   3700         1,
   3701         1,
   3702         1,
   3703         1,
   3704         1,
   3705         1,
   3706         1,
   3707         1,
   3708         1,
   3709         1,
   3710         1,
   3711         1,
   3712         1,
   3713         1,
   3714         1,
   3715         1,
   3716         1,
   3717         1,
   3718         1,
   3719         1,
   3720         1,
   3721         1,
   3722         1,
   3723         1,
   3724         1,
   3725         1,
   3726         1,
   3727         1,
   3728         1,
   3729         1,
   3730         1,
   3731         1,
   3732         1,
   3733         1,
   3734         1,
   3735         1,
   3736         1,
   3737         1,
   3738         1,
   3739         1,
   3740         1,
   3741         1,
   3742         1,
   3743         1,
   3744         1,
   3745         1,
   3746         1,
   3747         1,
   3748         1,
   3749         1,
   3750         1,
   3751         1,
   3752         1,
   3753         1,
   3754         1,
   3755         1,
   3756         1,
   3757         1,
   3758         1,
   3759         1,
   3760         1,
   3761         1,
   3762         1,
   3763         1,
   3764         1,
   3765         1,
   3766         1,
   3767         1,
   3768         1,
   3769         1,
   3770         1,
   3771         1,
   3772         1,
   3773         1,
   3774         1,
   3775         1,
   3776         1,
   3777         1,
   3778         1,
   3779         1,
   3780         1,
   3781         1,
   3782         1,
   3783         1,
   3784         1,
   3785         1,
   3786         1,
   3787         1,
   3788         1,
   3789         1,
   3790         1,
   3791         1,
   3792         1,
   3793         1,
   3794         1,
   3795         1,
   3796         1,
   3797         1,
   3798         1,
   3799         1,
   3800         1,
   3801         1,
   3802         1,
   3803         1,
   3804         1,
   3805         1,
   3806         1,
   3807         1,
   3808         1,
   3809         1,
   3810         1,
   3811         1,
   3812         1,
   3813         1,
   3814         1,
   3815         1,
   3816         1,
   3817         1,
   3818         1,
   3819         1,
   3820         1,
   3821         1,
   3822         1,
   3823         1,
   3824         1,
   3825         1,
   3826         1,
   3827         1,
   3828         1,
   3829         1,
   3830         1,
   3831         1,
   3832         1,
   3833         1,
   3834         1,
   3835         1,
   3836         1,
   3837         1,
   3838         1,
   3839         1,
   3840         1,
   3841         1,
   3842         1,
   3843         1,
   3844         1,
   3845         1,
   3846         1,
   3847         1,
   3848         1,
   3849         1,
   3850         1,
   3851         1,
   3852         1,
   3853         1,
   3854         1,
   3855         1,
   3856         1,
   3857         1,
   3858         1,
   3859         1,
   3860         1,
   3861         1,
   3862         1,
   3863         1,
   3864         1,
   3865         1,
   3866         1,
   3867         1,
   3868         1,
   3869         1,
   3870         1,
   3871         1,
   3872         1,
   3873         1,
   3874         1,
   3875         1,
   3876         1,
   3877         1,
   3878         1,
   3879         1,
   3880         1,
   3881         1,
   3882         1,
   3883         1,
   3884         1,
   3885         1,
   3886         1,
   3887         1,
   3888         1,
   3889         1,
   3890         1,
   3891         1,
   3892         1,
   3893         1,
   3894         1,
   3895         1,
   3896         1,
   3897         1,
   3898         1,
   3899         1,
   3900         1,
   3901         1,
   3902         1,
   3903         1,
   3904         1,
   3905         1,
   3906         1,
   3907         1,
   3908         1,
   3909         1,
   3910         1,
   3911         1,
   3912         1,
   3913         1,
   3914         1,
   3915         1,
   3916         1,
   3917         1,
   3918         1,
   3919         1,
   3920         1,
   3921         1,
   3922         1,
   3923         1,
   3924         1,
   3925         1,
   3926         1,
   3927         1,
   3928         1,
   3929         1,
   3930         1,
   3931         1,
   3932         1,
   3933         1,
   3934         1,
   3935         1,
   3936         1,
   3937         1,
   3938         1,
   3939         1,
   3940         1,
   3941         1,
   3942         1,
   3943         1,
   3944         1,
   3945         1,
   3946         1,
   3947         1,
   3948         1,
   3949         1,
   3950         1,
   3951         1,
   3952         1,
   3953         1,
   3954         1,
   3955         1,
   3956         1,
   3957         1,
   3958         1,
   3959         1,
   3960         1,
   3961         1,
   3962         1,
   3963         1,
   3964         1,
   3965         1,
   3966         1,
   3967         1,
   3968         1,
   3969         1,
   3970         1,
   3971         1,
   3972         1,
   3973         1,
   3974         1,
   3975         1,
   3976         1,
   3977         1,
   3978         1,
   3979         1,
   3980         1,
   3981         1,
   3982         1,
   3983         1,
   3984         1,
   3985         1,
   3986         1,
   3987         1,
   3988         1,
   3989         1,
   3990         1,
   3991         1,
   3992         1,
   3993         1,
   3994         1,
   3995         1,
   3996         1,
   3997         1,
   3998         1,
   3999         1,
   4000         1,
   4001         1,
   4002         1,
   4003         1,
   4004         1,
   4005         1,
   4006         1,
   4007         1,
   4008         1,
   4009         1,
   4010         1,
   4011         1,
   4012         1,
   4013         1,
   4014         1,
   4015         1,
   4016         1,
   4017         1,
   4018         1,
   4019         1,
   4020         1,
   4021         1,
   4022         1,
   4023         1,
   4024         1,
   4025         1,
   4026         1,
   4027         1,
   4028         1,
   4029         1,
   4030         1,
   4031         1,
   4032         1,
   4033         1,
   4034         1,
   4035         1,
   4036         1,
   4037         1,
   4038         1,
   4039         1,
   4040         1,
   4041         1,
   4042         1,
   4043         1,
   4044         1,
   4045         1,
   4046         1,
   4047         1,
   4048         1,
   4049         1,
   4050         1,
   4051         1,
   4052         1,
   4053         1,
   4054         1,
   4055         1,
   4056         1,
   4057         1,
   4058         1,
   4059         1,
   4060         1,
   4061         1,
   4062         1,
   4063         1,
   4064         1,
   4065         1,
   4066         1,
   4067         1,
   4068         1,
   4069         1,
   4070         1,
   4071         1,
   4072         1,
   4073         1,
   4074         1,
   4075         1,
   4076         1,
   4077         1,
   4078         1,
   4079         1,
   4080         1,
   4081         1,
   4082         1,
   4083         1,
   4084         1,
   4085         1,
   4086         1,
   4087         1,
   4088         1,
   4089         1,
   4090         1,
   4091         1,
   4092         1,
   4093         1,
   4094         1,
   4095         1,
   4096         1,
   4097         1,
   4098         1,
   4099         1,
   4100         1,
   4101         1,
   4102         1,
   4103         1,
   4104         1,
   4105         1,
   4106         1,
   4107         1,
   4108         1,
   4109         1,
   4110         1,
   4111         1,
   4112         1,
   4113         1,
   4114         1,
   4115         1,
   4116         1,
   4117         1,
   4118         1,
   4119         1,
   4120         1,
   4121         1,
   4122         1,
   4123         1,
   4124         1,
   4125         1,
   4126         1,
   4127         1,
   4128         1,
   4129         1,
   4130         1,
   4131         1,
   4132         1,
   4133         1,
   4134         1,
   4135         1,
   4136         1,
   4137         1,
   4138         1,
   4139         1,
   4140         1,
   4141         1,
   4142         1,
   4143         1,
   4144         1,
   4145         1,
   4146         1,
   4147         1,
   4148         1,
   4149         1,
   4150         1,
   4151         1,
   4152         1,
   4153         1,
   4154         1,
   4155         1,
   4156         1,
   4157         1,
   4158         1,
   4159         1,
   4160         1,
   4161         1,
   4162         1,
   4163         1,
   4164         1,
   4165         1,
   4166         1,
   4167         1,
   4168         1,
   4169         1,
   4170         1,
   4171         1,
   4172         1,
   4173         1,
   4174         1,
   4175         1,
   4176         1,
   4177         1,
   4178         1,
   4179         1,
   4180         1,
   4181         1,
   4182         1,
   4183         1,
   4184         1,
   4185         1,
   4186         1,
   4187         1,
   4188         1,
   4189         1,
   4190         1,
   4191         1,
   4192         1,
   4193         1,
   4194         1,
   4195         1,
   4196         1,
   4197         1,
   4198         1,
   4199         1,
   4200         1,
   4201         1,
   4202         1,
   4203         1,
   4204         1,
   4205         1,
   4206         1,
   4207         1,
   4208         1,
   4209         1,
   4210         1,
   4211         1,
   4212         1,
   4213         1,
   4214         1,
   4215         1,
   4216         1,
   4217         1,
   4218         1,
   4219         1,
   4220         1,
   4221         1,
   4222         1,
   4223         1,
   4224         1,
   4225         1,
   4226         1,
   4227         1,
   4228         1,
   4229         1,
   4230         1,
   4231         1,
   4232         1,
   4233         1,
   4234         1,
   4235         1,
   4236         1,
   4237         1,
   4238         1,
   4239         1,
   4240         1,
   4241         1,
   4242         1,
   4243         1,
   4244         1,
   4245         1,
   4246         1,
   4247         1,
   4248         1,
   4249         1,
   4250         1,
   4251         1,
   4252         1,
   4253         1,
   4254         1,
   4255         1,
   4256         1,
   4257         1,
   4258         1,
   4259         1,
   4260         1,
   4261         1,
   4262         1,
   4263         1,
   4264         1,
   4265         1,
   4266         1,
   4267         1,
   4268         1,
   4269         1,
   4270         1,
   4271         1,
   4272         1,
   4273         1,
   4274         1,
   4275         1,
   4276         1,
   4277         1,
   4278         1,
   4279         1,
   4280         1,
   4281         1,
   4282         1,
   4283         1,
   4284         1,
   4285         1,
   4286         1,
   4287         1,
   4288         1,
   4289         1,
   4290         1,
   4291         1,
   4292         1,
   4293         1,
   4294         1,
   4295         1,
   4296         1,
   4297         1,
   4298         1,
   4299         1,
   4300         1,
   4301         1,
   4302         1,
   4303         1,
   4304         1,
   4305         1,
   4306         1,
   4307         1,
   4308         1,
   4309         1,
   4310         1,
   4311         1,
   4312         1,
   4313         1,
   4314         1,
   4315         1,
   4316         1,
   4317         1,
   4318         1,
   4319         1,
   4320         1,
   4321         1,
   4322         1,
   4323         1,
   4324         1,
   4325         1,
   4326         1,
   4327         1,
   4328         1,
   4329         1,
   4330         1,
   4331         1,
   4332         1,
   4333         1,
   4334         1,
   4335         1,
   4336         1,
   4337         1,
   4338         1,
   4339         1,
   4340         1,
   4341         1,
   4342         1,
   4343         1,
   4344         1,
   4345         1,
   4346         1,
   4347         1,
   4348         1,
   4349         1,
   4350         1,
   4351         1,
   4352         1,
   4353         1,
   4354         1,
   4355         1,
   4356         1,
   4357         1,
   4358         1,
   4359         1,
   4360         1,
   4361         1,
   4362         1,
   4363         1,
   4364         1,
   4365         1,
   4366         1,
   4367         1,
   4368         1,
   4369         1,
   4370         1,
   4371         1,
   4372         1,
   4373         1,
   4374         1,
   4375         1,
   4376         1,
   4377         1,
   4378         1,
   4379         1,
   4380         1,
   4381         1,
   4382         1,
   4383         1,
   4384         1,
   4385         1,
   4386         1,
   4387         1,
   4388         1,
   4389         1,
   4390         1,
   4391         1,
   4392         1,
   4393         1,
   4394         1,
   4395         1,
   4396         1,
   4397         1,
   4398         1,
   4399         1,
   4400         1,
   4401         1,
   4402         1,
   4403         1,
   4404         1,
   4405         1,
   4406         1,
   4407         1,
   4408         1,
   4409         1,
   4410         1,
   4411         1,
   4412         1,
   4413         1,
   4414         1,
   4415         1,
   4416         1,
   4417         1,
   4418         1,
   4419         1,
   4420         1,
   4421         1,
   4422         1,
   4423         1,
   4424         1,
   4425         1,
   4426         1,
   4427         1,
   4428         1,
   4429         1,
   4430         1,
   4431         1,
   4432         1,
   4433         1,
   4434         1,
   4435         1,
   4436         1,
   4437         1,
   4438         1,
   4439         1,
   4440         1,
   4441         1,
   4442         1,
   4443         1,
   4444         1,
   4445         1,
   4446         1,
   4447         1,
   4448         1,
   4449         1,
   4450         1,
   4451         1,
   4452         1,
   4453         1,
   4454         1,
   4455         1,
   4456         1,
   4457         1,
   4458         1,
   4459         1,
   4460         1,
   4461         1,
   4462         1,
   4463         1,
   4464         1,
   4465         1,
   4466         1,
   4467         1,
   4468         1,
   4469         1,
   4470         1,
   4471         1,
   4472         1,
   4473         1,
   4474         1,
   4475         1,
   4476         1,
   4477         1,
   4478         1,
   4479         1,
   4480         1,
   4481         1,
   4482         1,
   4483         1,
   4484         1,
   4485         1,
   4486         1,
   4487         1,
   4488         1,
   4489         1,
   4490         1,
   4491         1,
   4492         1,
   4493         1,
   4494         1,
   4495         1,
   4496         1,
   4497         1,
   4498         1,
   4499         1,
   4500         1,
   4501         1,
   4502         1,
   4503         1,
   4504         1,
   4505         1,
   4506         1,
   4507         1,
   4508         1,
   4509         1,
   4510         1,
   4511         1,
   4512         1,
   4513         1,
   4514         1,
   4515         1,
   4516         1,
   4517         1,
   4518         1,
   4519         1,
   4520         1,
   4521         1,
   4522         1,
   4523         1,
   4524         1,
   4525         1,
   4526         1,
   4527         1,
   4528         1,
   4529         1,
   4530         1,
   4531         1,
   4532         1,
   4533         1,
   4534         1,
   4535         1,
   4536         1,
   4537         1,
   4538         1,
   4539         1,
   4540         1,
   4541         1,
   4542         1,
   4543         1,
   4544         1,
   4545         1,
   4546         1,
   4547         1,
   4548         1,
   4549         1,
   4550         1,
   4551         1,
   4552         1,
   4553         1,
   4554         1,
   4555         1,
   4556         1,
   4557         1,
   4558         1,
   4559         1,
   4560         1,
   4561         1,
   4562         1,
   4563         1,
   4564         1,
   4565         1,
   4566         1,
   4567         1,
   4568         1,
   4569         1,
   4570         1,
   4571         1,
   4572         1,
   4573         1,
   4574         1,
   4575         1,
   4576         1,
   4577         1,
   4578         1,
   4579         1,
   4580         1,
   4581         1,
   4582         1,
   4583         1,
   4584         1,
   4585         1,
   4586         1,
   4587         1,
   4588         1,
   4589         1,
   4590         1,
   4591         1,
   4592         1,
   4593         1,
   4594         1,
   4595         1,
   4596         1,
   4597         1,
   4598         1,
   4599         1,
   4600         1,
   4601         1,
   4602         1,
   4603         1,
   4604         1,
   4605         1,
   4606         1,
   4607         1,
   4608         1,
   4609         1,
   4610         1,
   4611         1,
   4612         1,
   4613         1,
   4614         1,
   4615         1,
   4616         1,
   4617         1,
   4618         1,
   4619         1,
   4620         1,
   4621         1,
   4622         1,
   4623         1,
   4624         1,
   4625         1,
   4626         1,
   4627         1,
   4628         1,
   4629         1,
   4630         1,
   4631         1,
   4632         1,
   4633         1,
   4634         1,
   4635         1,
   4636         1,
   4637         1,
   4638         1,
   4639         1,
   4640         1,
   4641         1,
   4642         1,
   4643         1,
   4644         1,
   4645         1,
   4646         1,
   4647         1,
   4648         1,
   4649         1,
   4650         1,
   4651         1,
   4652         1,
   4653         1,
   4654         1,
   4655         1,
   4656         1,
   4657         1,
   4658         1,
   4659         1,
   4660         1,
   4661         1,
   4662         1,
   4663         1,
   4664         1,
   4665         1,
   4666         1,
   4667         1,
   4668         1,
   4669         1,
   4670         1,
   4671         1,
   4672         1,
   4673         1,
   4674         1,
   4675         1,
   4676         1,
   4677         1,
   4678         1,
   4679         1,
   4680         1,
   4681         1,
   4682         1,
   4683         1,
   4684         1,
   4685         1,
   4686         1,
   4687         1,
   4688         1,
   4689         1,
   4690         1,
   4691         1,
   4692         1,
   4693         1,
   4694         1,
   4695         1,
   4696         1,
   4697         1,
   4698         1,
   4699         1,
   4700         1,
   4701         1,
   4702         1,
   4703         1,
   4704         1,
   4705         1,
   4706         1,
   4707         1,
   4708         1,
   4709         1,
   4710         1,
   4711         1,
   4712         1,
   4713         1,
   4714         1,
   4715         1,
   4716         1,
   4717         1,
   4718         1,
   4719         1,
   4720         1,
   4721         1,
   4722         1,
   4723         1,
   4724         1,
   4725         1,
   4726         1,
   4727         1,
   4728         1,
   4729         1,
   4730         1,
   4731         1,
   4732         1,
   4733         1,
   4734         1,
   4735         1,
   4736         1,
   4737         1,
   4738         1,
   4739         1,
   4740         1,
   4741         1,
   4742         1,
   4743         1,
   4744         1,
   4745         1,
   4746         1,
   4747         1,
   4748         1,
   4749         1,
   4750         1,
   4751         1,
   4752         1,
   4753         1,
   4754         1,
   4755         1,
   4756         1,
   4757         1,
   4758         1,
   4759         1,
   4760         1,
   4761         1,
   4762         1,
   4763         1,
   4764         1,
   4765         1,
   4766         1,
   4767         1,
   4768         1,
   4769         1,
   4770         1,
   4771         1,
   4772         1,
   4773         1,
   4774         1,
   4775         1,
   4776         1,
   4777         1,
   4778         1,
   4779         1,
   4780         1,
   4781         1,
   4782         1,
   4783         1,
   4784         1,
   4785         1,
   4786         1,
   4787         1,
   4788         1,
   4789         1,
   4790         1,
   4791         1,
   4792         1,
   4793         1,
   4794         1,
   4795         1,
   4796         1,
   4797         1,
   4798         1,
   4799         1,
   4800         1,
   4801         1,
   4802         1,
   4803         1,
   4804         1,
   4805         1,
   4806         1,
   4807         1,
   4808         1,
   4809         1,
   4810         1,
   4811         1,
   4812         1,
   4813         1,
   4814         1,
   4815         1,
   4816         1,
   4817         1,
   4818         1,
   4819         1,
   4820         1,
   4821         1,
   4822         1,
   4823         1,
   4824         1,
   4825         1,
   4826         1,
   4827         1,
   4828         1,
   4829         1,
   4830         1,
   4831         1,
   4832         1,
   4833         1,
   4834         1,
   4835         1,
   4836         1,
   4837         1,
   4838         1,
   4839         1,
   4840         1,
   4841         1,
   4842         1,
   4843         1,
   4844         1,
   4845         1,
   4846         1,
   4847         1,
   4848         1,
   4849         1,
   4850         1,
   4851         1,
   4852         1,
   4853         1,
   4854         1,
   4855         1,
   4856         1,
   4857         1,
   4858         1,
   4859         1,
   4860         1,
   4861         1,
   4862         1,
   4863         1,
   4864         1,
   4865         1,
   4866         1,
   4867         1,
   4868         1,
   4869         1,
   4870         1,
   4871         1,
   4872         1,
   4873         1,
   4874         1,
   4875         1,
   4876         1,
   4877         1,
   4878         1,
   4879         1,
   4880         1,
   4881         1,
   4882         1,
   4883         1,
   4884         1,
   4885         1,
   4886         1,
   4887         1,
   4888         1,
   4889         1,
   4890         1,
   4891         1,
   4892         1,
   4893         1,
   4894         1,
   4895         1,
   4896         1,
   4897         1,
   4898         1,
   4899         1,
   4900         1,
   4901         1,
   4902         1,
   4903         1,
   4904         1,
   4905         1,
   4906         1,
   4907         1,
   4908         1,
   4909         1,
   4910         1,
   4911         1,
   4912         1,
   4913         1,
   4914         1,
   4915         1,
   4916         1,
   4917         1,
   4918         1,
   4919         1,
   4920         1,
   4921         1,
   4922         1,
   4923         1,
   4924         1,
   4925         1,
   4926         1,
   4927         1,
   4928         1,
   4929         1,
   4930         1,
   4931         1,
   4932         1,
   4933         1,
   4934         1,
   4935         1,
   4936         1,
   4937         1,
   4938         1,
   4939         1,
   4940         1,
   4941         1,
   4942         1,
   4943         1,
   4944         1,
   4945         1,
   4946         1,
   4947         1,
   4948         1,
   4949         1,
   4950         1,
   4951         1,
   4952         1,
   4953         1,
   4954         1,
   4955         1,
   4956         1,
   4957         1,
   4958         1,
   4959         1,
   4960         1,
   4961         1,
   4962         1,
   4963         1,
   4964         1,
   4965         1,
   4966         1,
   4967         1,
   4968         1,
   4969         1,
   4970         1,
   4971         1,
   4972         1,
   4973         1,
   4974         1,
   4975         1,
   4976         1,
   4977         1,
   4978         1,
   4979         1,
   4980         1,
   4981         1,
   4982         1,
   4983         1,
   4984         1,
   4985         1,
   4986         1,
   4987         1,
   4988         1,
   4989         1,
   4990         1,
   4991         1,
   4992         1,
   4993         1,
   4994         1,
   4995         1,
   4996         1,
   4997         1,
   4998         1,
   4999         1,
   5000         1,
   5001         1,
   5002         1,
   5003         1,
   5004         1,
   5005         1,
   5006         1,
   5007         1,
   5008         1,
   5009         1,
   5010         1,
   5011         1,
   5012         1,
   5013         1,
   5014         1,
   5015         1,
   5016         1,
   5017         1,
   5018         1,
   5019         1,
   5020         1,
   5021         1,
   5022         1,
   5023         1,
   5024         1,
   5025         1,
   5026         1,
   5027         1,
   5028         1,
   5029         1,
   5030         1,
   5031         1,
   5032         1,
   5033         1,
   5034         1,
   5035         1,
   5036         1,
   5037         1,
   5038         1,
   5039         1,
   5040         1,
   5041         1,
   5042         1,
   5043         1,
   5044         1,
   5045         1,
   5046         1,
   5047         1,
   5048         1,
   5049         1,
   5050         1,
   5051         1,
   5052         1,
   5053         1,
   5054         1,
   5055         1,
   5056         1,
   5057         1,
   5058         1,
   5059         1,
   5060         1,
   5061         1,
   5062         1,
   5063         1,
   5064         1,
   5065         1,
   5066         1,
   5067         1,
   5068         1,
   5069         1,
   5070         1,
   5071         1,
   5072         1,
   5073         1,
   5074         1,
   5075         1,
   5076         1,
   5077         1,
   5078         1,
   5079         1,
   5080         1,
   5081         1,
   5082         1,
   5083         1,
   5084         1,
   5085         1,
   5086         1,
   5087         1,
   5088         1,
   5089         1,
   5090         1,
   5091         1,
   5092         1,
   5093         1,
   5094         1,
   5095         1,
   5096         1,
   5097         1,
   5098         1,
   5099         1,
   5100         1,
   5101         1,
   5102         1,
   5103         1,
   5104         1,
   5105         1,
   5106         1,
   5107         1,
   5108         1,
   5109         1,
   5110         1,
   5111         1,
   5112         1,
   5113         1,
   5114         1,
   5115         1,
   5116         1,
   5117         1,
   5118         1,
   5119         1,
   5120         1,
   5121         1,
   5122         1,
   5123         1,
   5124         1,
   5125         1,
   5126         1,
   5127         1,
   5128         1,
   5129         1,
   5130         1,
   5131         1,
   5132         1,
   5133         1,
   5134         1,
   5135         1,
   5136         1,
   5137         1,
   5138         1,
   5139         1,
   5140         1,
   5141         1,
   5142         1,
   5143         1,
   5144         1,
   5145         1,
   5146         1,
   5147         1,
   5148         1,
   5149         1,
   5150         1,
   5151         1,
   5152         1,
   5153         1,
   5154         1,
   5155         1,
   5156         1,
   5157         1,
   5158         1,
   5159         1,
   5160         1,
   5161         1,
   5162         1,
   5163         1,
   5164         1,
   5165         1,
   5166         1,
   5167         1,
   5168         1,
   5169         1,
   5170         1,
   5171         1,
   5172         1,
   5173         1,
   5174         1,
   5175         1,
   5176         1,
   5177         1,
   5178         1,
   5179         1,
   5180         1,
   5181         1,
   5182         1,
   5183         1,
   5184         1,
   5185         1,
   5186         1,
   5187         1,
   5188         1,
   5189         1,
   5190         1,
   5191         1,
   5192         1,
   5193         1,
   5194         1,
   5195         1,
   5196         1,
   5197         1,
   5198         1,
   5199         1,
   5200         1,
   5201         1,
   5202         1,
   5203         1,
   5204         1,
   5205         1,
   5206         1,
   5207         1,
   5208         1,
   5209         1,
   5210         1,
   5211         1,
   5212         1,
   5213         1,
   5214         1,
   5215         1,
   5216         1,
   5217         1,
   5218         1,
   5219         1,
   5220         1,
   5221         1,
   5222         1,
   5223         1,
   5224         1,
   5225         1,
   5226         1,
   5227         1,
   5228         1,
   5229         1,
   5230         1,
   5231         1,
   5232         1,
   5233         1,
   5234         1,
   5235         1,
   5236         1,
   5237         1,
   5238         1,
   5239         1,
   5240         1,
   5241         1,
   5242         1,
   5243         1,
   5244         1,
   5245         1,
   5246         1,
   5247         1,
   5248         1,
   5249         1,
   5250         1,
   5251         1,
   5252         1,
   5253         1,
   5254         1,
   5255         1,
   5256         1,
   5257         1,
   5258         1,
   5259         1,
   5260         1,
   5261         1,
   5262         1,
   5263         1,
   5264         1,
   5265         1,
   5266         1,
   5267         1,
   5268         1,
   5269         1,
   5270         1,
   5271         1,
   5272         1,
   5273         1,
   5274         1,
   5275         1,
   5276         1,
   5277         1,
   5278         1,
   5279         1,
   5280         1,
   5281         1,
   5282         1,
   5283         1,
   5284         1,
   5285         1,
   5286         1,
   5287         1,
   5288         1,
   5289         1,
   5290         1,
   5291         1,
   5292         1,
   5293         1,
   5294         1,
   5295         1,
   5296         1,
   5297         1,
   5298     ];
   5299     let pub_key = MlDsaVerKey::<MlDsa87>::decode(&[1u8; 2592].into())
   5300         .to_public_key_der()
   5301         .unwrap();
   5302     let att_obj_len = att_obj.len();
   5303     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
   5304     let b64_adata = base64url_nopad::encode(&att_obj[att_obj_len - 2673..]);
   5305     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
   5306     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
   5307     // Base case is valid.
   5308     assert!(
   5309         serde_json::from_str::<Registration>(
   5310             serde_json::json!({
   5311                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5312                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5313                 "response": {
   5314                     "clientDataJSON": b64_cdata_json,
   5315                     "authenticatorData": b64_adata,
   5316                     "transports": [],
   5317                     "publicKey": b64_key,
   5318                     "publicKeyAlgorithm": -50i8,
   5319                     "attestationObject": b64_aobj,
   5320                 },
   5321                 "clientExtensionResults": {},
   5322                 "type": "public-key"
   5323             })
   5324             .to_string()
   5325             .as_str()
   5326         )
   5327         .is_ok_and(
   5328             |reg| reg.response.client_data_json == c_data_json.as_bytes()
   5329                 && reg.response.attestation_object_and_c_data_hash[..att_obj_len] == att_obj
   5330                 && reg.response.attestation_object_and_c_data_hash[att_obj_len..]
   5331                     == *Sha256::digest(c_data_json.as_bytes())
   5332                 && reg.response.transports.is_empty()
   5333                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
   5334                 && reg.client_extension_results.cred_props.is_none()
   5335                 && reg.client_extension_results.prf.is_none()
   5336         )
   5337     );
   5338     // `publicKeyAlgorithm` mismatch.
   5339     let mut err = Error::invalid_value(
   5340         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Eddsa).as_str()),
   5341         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa87).as_str()
   5342     )
   5343     .to_string().into_bytes();
   5344     assert_eq!(
   5345         serde_json::from_str::<Registration>(
   5346             serde_json::json!({
   5347                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5348                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5349                 "response": {
   5350                     "clientDataJSON": b64_cdata_json,
   5351                     "authenticatorData": b64_adata,
   5352                     "transports": [],
   5353                     "publicKey": b64_key,
   5354                     "publicKeyAlgorithm": -8i8,
   5355                     "attestationObject": b64_aobj,
   5356                 },
   5357                 "clientExtensionResults": {},
   5358                 "type": "public-key"
   5359             })
   5360             .to_string()
   5361             .as_str()
   5362         )
   5363         .unwrap_err()
   5364         .to_string()
   5365         .into_bytes()
   5366         .get(..err.len()),
   5367         Some(err.as_slice())
   5368     );
   5369     // Missing `publicKeyAlgorithm`.
   5370     err = Error::missing_field("publicKeyAlgorithm")
   5371         .to_string()
   5372         .into_bytes();
   5373     assert_eq!(
   5374         serde_json::from_str::<Registration>(
   5375             serde_json::json!({
   5376                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5377                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5378                 "response": {
   5379                     "clientDataJSON": b64_cdata_json,
   5380                     "authenticatorData": b64_adata,
   5381                     "transports": [],
   5382                     "publicKey": b64_key,
   5383                     "attestationObject": b64_aobj,
   5384                 },
   5385                 "clientExtensionResults": {},
   5386                 "type": "public-key"
   5387             })
   5388             .to_string()
   5389             .as_str()
   5390         )
   5391         .unwrap_err()
   5392         .to_string()
   5393         .into_bytes()
   5394         .get(..err.len()),
   5395         Some(err.as_slice())
   5396     );
   5397     // `null` `publicKeyAlgorithm`.
   5398     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
   5399         .to_string()
   5400         .into_bytes();
   5401     assert_eq!(
   5402         serde_json::from_str::<Registration>(
   5403             serde_json::json!({
   5404                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5405                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5406                 "response": {
   5407                     "clientDataJSON": b64_cdata_json,
   5408                     "authenticatorData": b64_adata,
   5409                     "transports": [],
   5410                     "publicKey": b64_key,
   5411                     "publicKeyAlgorithm": null,
   5412                     "attestationObject": b64_aobj,
   5413                 },
   5414                 "clientExtensionResults": {},
   5415                 "type": "public-key"
   5416             })
   5417             .to_string()
   5418             .as_str()
   5419         )
   5420         .unwrap_err()
   5421         .to_string()
   5422         .into_bytes()
   5423         .get(..err.len()),
   5424         Some(err.as_slice())
   5425     );
   5426     // `publicKey` mismatch.
   5427     let bad_pub_key = MlDsaVerKey::<MlDsa87>::decode(&[2; 2592].into());
   5428     err = Error::invalid_value(
   5429         Unexpected::Bytes([0; 32].as_slice()),
   5430         &format!(
   5431             "DER-encoded public key to match the public key within the attestation object: MlDsa87(MlDsa87PubKey({:?}))",
   5432             &[1u8; 2592]
   5433         )
   5434         .as_str(),
   5435     )
   5436     .to_string().into_bytes();
   5437     assert_eq!(serde_json::from_str::<Registration>(
   5438         serde_json::json!({
   5439             "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5440             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5441             "response": {
   5442                 "clientDataJSON": b64_cdata_json,
   5443                 "authenticatorData": b64_adata,
   5444                 "transports": [],
   5445                 "publicKey": base64url_nopad::encode(bad_pub_key.to_public_key_der().unwrap().as_bytes()),
   5446                 "publicKeyAlgorithm": -50i8,
   5447                 "attestationObject": b64_aobj,
   5448             },
   5449             "clientExtensionResults": {},
   5450             "type": "public-key"
   5451         })
   5452         .to_string()
   5453         .as_str()
   5454         )
   5455         .unwrap_err().to_string().into_bytes().get(..err.len()),
   5456         Some(err.as_slice())
   5457     );
   5458     // Missing `publicKey` is allowed when not using EdDSA, ES256, or RS256.
   5459     assert!(
   5460         serde_json::from_str::<Registration>(
   5461             serde_json::json!({
   5462                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5463                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5464                 "response": {
   5465                     "clientDataJSON": b64_cdata_json,
   5466                     "authenticatorData": b64_adata,
   5467                     "transports": [],
   5468                     "publicKeyAlgorithm": -50i8,
   5469                     "attestationObject": b64_aobj,
   5470                 },
   5471                 "clientExtensionResults": {},
   5472                 "type": "public-key"
   5473             })
   5474             .to_string()
   5475             .as_str()
   5476         )
   5477         .is_ok()
   5478     );
   5479     // `publicKeyAlgorithm` mismatch when `publicKey` does not exist.
   5480     err = Error::invalid_value(
   5481         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
   5482         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa87).as_str()
   5483     )
   5484     .to_string().into_bytes();
   5485     assert_eq!(
   5486         serde_json::from_str::<Registration>(
   5487             serde_json::json!({
   5488                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5489                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5490                 "response": {
   5491                     "clientDataJSON": b64_cdata_json,
   5492                     "authenticatorData": b64_adata,
   5493                     "transports": [],
   5494                     "publicKeyAlgorithm": -7i8,
   5495                     "attestationObject": b64_aobj,
   5496                 },
   5497                 "clientExtensionResults": {},
   5498                 "type": "public-key"
   5499             })
   5500             .to_string()
   5501             .as_str()
   5502         )
   5503         .unwrap_err()
   5504         .to_string()
   5505         .into_bytes()
   5506         .get(..err.len()),
   5507         Some(err.as_slice())
   5508     );
   5509     // `null` `publicKey` is allowed when not using EdDSA, ES256, or RS256.
   5510     assert!(
   5511         serde_json::from_str::<Registration>(
   5512             serde_json::json!({
   5513                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5514                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5515                 "response": {
   5516                     "clientDataJSON": b64_cdata_json,
   5517                     "authenticatorData": b64_adata,
   5518                     "transports": [],
   5519                     "publicKey": null,
   5520                     "publicKeyAlgorithm": -50i8,
   5521                     "attestationObject": b64_aobj,
   5522                 },
   5523                 "clientExtensionResults": {},
   5524                 "type": "public-key"
   5525             })
   5526             .to_string()
   5527             .as_str()
   5528         )
   5529         .is_ok()
   5530     );
   5531     // `publicKeyAlgorithm` mismatch when `publicKey` is null.
   5532     err = Error::invalid_value(
   5533         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
   5534         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa87).as_str()
   5535     )
   5536     .to_string().into_bytes();
   5537     assert_eq!(
   5538         serde_json::from_str::<Registration>(
   5539             serde_json::json!({
   5540                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   5541                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   5542                 "response": {
   5543                     "clientDataJSON": b64_cdata_json,
   5544                     "authenticatorData": b64_adata,
   5545                     "transports": [],
   5546                     "publicKey": null,
   5547                     "publicKeyAlgorithm": -7i8,
   5548                     "attestationObject": b64_aobj,
   5549                 },
   5550                 "clientExtensionResults": {},
   5551                 "type": "public-key"
   5552             })
   5553             .to_string()
   5554             .as_str()
   5555         )
   5556         .unwrap_err()
   5557         .to_string()
   5558         .into_bytes()
   5559         .get(..err.len()),
   5560         Some(err.as_slice())
   5561     );
   5562 }
   5563 #[expect(
   5564     clippy::assertions_on_result_states,
   5565     clippy::unwrap_used,
   5566     reason = "OK in tests"
   5567 )]
   5568 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
   5569 #[expect(clippy::too_many_lines, reason = "a lot to test")]
   5570 #[test]
   5571 fn mldsa65_registration_deserialize_data_mismatch() {
   5572     let c_data_json = serde_json::json!({}).to_string();
   5573     let att_obj: [u8; 2064] = [
   5574         cbor::MAP_3,
   5575         cbor::TEXT_3,
   5576         b'f',
   5577         b'm',
   5578         b't',
   5579         cbor::TEXT_4,
   5580         b'n',
   5581         b'o',
   5582         b'n',
   5583         b'e',
   5584         cbor::TEXT_7,
   5585         b'a',
   5586         b't',
   5587         b't',
   5588         b'S',
   5589         b't',
   5590         b'm',
   5591         b't',
   5592         cbor::MAP_0,
   5593         cbor::TEXT_8,
   5594         b'a',
   5595         b'u',
   5596         b't',
   5597         b'h',
   5598         b'D',
   5599         b'a',
   5600         b't',
   5601         b'a',
   5602         cbor::BYTES_INFO_25,
   5603         7,
   5604         241,
   5605         // `rpIdHash`.
   5606         0,
   5607         0,
   5608         0,
   5609         0,
   5610         0,
   5611         0,
   5612         0,
   5613         0,
   5614         0,
   5615         0,
   5616         0,
   5617         0,
   5618         0,
   5619         0,
   5620         0,
   5621         0,
   5622         0,
   5623         0,
   5624         0,
   5625         0,
   5626         0,
   5627         0,
   5628         0,
   5629         0,
   5630         0,
   5631         0,
   5632         0,
   5633         0,
   5634         0,
   5635         0,
   5636         0,
   5637         0,
   5638         // `flags`.
   5639         0b0100_0101,
   5640         // `signCount`.
   5641         0,
   5642         0,
   5643         0,
   5644         0,
   5645         // `aaguid`.
   5646         0,
   5647         0,
   5648         0,
   5649         0,
   5650         0,
   5651         0,
   5652         0,
   5653         0,
   5654         0,
   5655         0,
   5656         0,
   5657         0,
   5658         0,
   5659         0,
   5660         0,
   5661         0,
   5662         // `credentialIdLength`.
   5663         0,
   5664         16,
   5665         // `credentialId`.
   5666         0,
   5667         0,
   5668         0,
   5669         0,
   5670         0,
   5671         0,
   5672         0,
   5673         0,
   5674         0,
   5675         0,
   5676         0,
   5677         0,
   5678         0,
   5679         0,
   5680         0,
   5681         0,
   5682         // ML-DSA-65 COSE key.
   5683         cbor::MAP_3,
   5684         KTY,
   5685         AKP,
   5686         ALG,
   5687         cbor::NEG_INFO_24,
   5688         MLDSA65,
   5689         // `pub`.
   5690         cbor::NEG_ONE,
   5691         cbor::BYTES_INFO_25,
   5692         7,
   5693         160,
   5694         // Encoded key.
   5695         1,
   5696         1,
   5697         1,
   5698         1,
   5699         1,
   5700         1,
   5701         1,
   5702         1,
   5703         1,
   5704         1,
   5705         1,
   5706         1,
   5707         1,
   5708         1,
   5709         1,
   5710         1,
   5711         1,
   5712         1,
   5713         1,
   5714         1,
   5715         1,
   5716         1,
   5717         1,
   5718         1,
   5719         1,
   5720         1,
   5721         1,
   5722         1,
   5723         1,
   5724         1,
   5725         1,
   5726         1,
   5727         1,
   5728         1,
   5729         1,
   5730         1,
   5731         1,
   5732         1,
   5733         1,
   5734         1,
   5735         1,
   5736         1,
   5737         1,
   5738         1,
   5739         1,
   5740         1,
   5741         1,
   5742         1,
   5743         1,
   5744         1,
   5745         1,
   5746         1,
   5747         1,
   5748         1,
   5749         1,
   5750         1,
   5751         1,
   5752         1,
   5753         1,
   5754         1,
   5755         1,
   5756         1,
   5757         1,
   5758         1,
   5759         1,
   5760         1,
   5761         1,
   5762         1,
   5763         1,
   5764         1,
   5765         1,
   5766         1,
   5767         1,
   5768         1,
   5769         1,
   5770         1,
   5771         1,
   5772         1,
   5773         1,
   5774         1,
   5775         1,
   5776         1,
   5777         1,
   5778         1,
   5779         1,
   5780         1,
   5781         1,
   5782         1,
   5783         1,
   5784         1,
   5785         1,
   5786         1,
   5787         1,
   5788         1,
   5789         1,
   5790         1,
   5791         1,
   5792         1,
   5793         1,
   5794         1,
   5795         1,
   5796         1,
   5797         1,
   5798         1,
   5799         1,
   5800         1,
   5801         1,
   5802         1,
   5803         1,
   5804         1,
   5805         1,
   5806         1,
   5807         1,
   5808         1,
   5809         1,
   5810         1,
   5811         1,
   5812         1,
   5813         1,
   5814         1,
   5815         1,
   5816         1,
   5817         1,
   5818         1,
   5819         1,
   5820         1,
   5821         1,
   5822         1,
   5823         1,
   5824         1,
   5825         1,
   5826         1,
   5827         1,
   5828         1,
   5829         1,
   5830         1,
   5831         1,
   5832         1,
   5833         1,
   5834         1,
   5835         1,
   5836         1,
   5837         1,
   5838         1,
   5839         1,
   5840         1,
   5841         1,
   5842         1,
   5843         1,
   5844         1,
   5845         1,
   5846         1,
   5847         1,
   5848         1,
   5849         1,
   5850         1,
   5851         1,
   5852         1,
   5853         1,
   5854         1,
   5855         1,
   5856         1,
   5857         1,
   5858         1,
   5859         1,
   5860         1,
   5861         1,
   5862         1,
   5863         1,
   5864         1,
   5865         1,
   5866         1,
   5867         1,
   5868         1,
   5869         1,
   5870         1,
   5871         1,
   5872         1,
   5873         1,
   5874         1,
   5875         1,
   5876         1,
   5877         1,
   5878         1,
   5879         1,
   5880         1,
   5881         1,
   5882         1,
   5883         1,
   5884         1,
   5885         1,
   5886         1,
   5887         1,
   5888         1,
   5889         1,
   5890         1,
   5891         1,
   5892         1,
   5893         1,
   5894         1,
   5895         1,
   5896         1,
   5897         1,
   5898         1,
   5899         1,
   5900         1,
   5901         1,
   5902         1,
   5903         1,
   5904         1,
   5905         1,
   5906         1,
   5907         1,
   5908         1,
   5909         1,
   5910         1,
   5911         1,
   5912         1,
   5913         1,
   5914         1,
   5915         1,
   5916         1,
   5917         1,
   5918         1,
   5919         1,
   5920         1,
   5921         1,
   5922         1,
   5923         1,
   5924         1,
   5925         1,
   5926         1,
   5927         1,
   5928         1,
   5929         1,
   5930         1,
   5931         1,
   5932         1,
   5933         1,
   5934         1,
   5935         1,
   5936         1,
   5937         1,
   5938         1,
   5939         1,
   5940         1,
   5941         1,
   5942         1,
   5943         1,
   5944         1,
   5945         1,
   5946         1,
   5947         1,
   5948         1,
   5949         1,
   5950         1,
   5951         1,
   5952         1,
   5953         1,
   5954         1,
   5955         1,
   5956         1,
   5957         1,
   5958         1,
   5959         1,
   5960         1,
   5961         1,
   5962         1,
   5963         1,
   5964         1,
   5965         1,
   5966         1,
   5967         1,
   5968         1,
   5969         1,
   5970         1,
   5971         1,
   5972         1,
   5973         1,
   5974         1,
   5975         1,
   5976         1,
   5977         1,
   5978         1,
   5979         1,
   5980         1,
   5981         1,
   5982         1,
   5983         1,
   5984         1,
   5985         1,
   5986         1,
   5987         1,
   5988         1,
   5989         1,
   5990         1,
   5991         1,
   5992         1,
   5993         1,
   5994         1,
   5995         1,
   5996         1,
   5997         1,
   5998         1,
   5999         1,
   6000         1,
   6001         1,
   6002         1,
   6003         1,
   6004         1,
   6005         1,
   6006         1,
   6007         1,
   6008         1,
   6009         1,
   6010         1,
   6011         1,
   6012         1,
   6013         1,
   6014         1,
   6015         1,
   6016         1,
   6017         1,
   6018         1,
   6019         1,
   6020         1,
   6021         1,
   6022         1,
   6023         1,
   6024         1,
   6025         1,
   6026         1,
   6027         1,
   6028         1,
   6029         1,
   6030         1,
   6031         1,
   6032         1,
   6033         1,
   6034         1,
   6035         1,
   6036         1,
   6037         1,
   6038         1,
   6039         1,
   6040         1,
   6041         1,
   6042         1,
   6043         1,
   6044         1,
   6045         1,
   6046         1,
   6047         1,
   6048         1,
   6049         1,
   6050         1,
   6051         1,
   6052         1,
   6053         1,
   6054         1,
   6055         1,
   6056         1,
   6057         1,
   6058         1,
   6059         1,
   6060         1,
   6061         1,
   6062         1,
   6063         1,
   6064         1,
   6065         1,
   6066         1,
   6067         1,
   6068         1,
   6069         1,
   6070         1,
   6071         1,
   6072         1,
   6073         1,
   6074         1,
   6075         1,
   6076         1,
   6077         1,
   6078         1,
   6079         1,
   6080         1,
   6081         1,
   6082         1,
   6083         1,
   6084         1,
   6085         1,
   6086         1,
   6087         1,
   6088         1,
   6089         1,
   6090         1,
   6091         1,
   6092         1,
   6093         1,
   6094         1,
   6095         1,
   6096         1,
   6097         1,
   6098         1,
   6099         1,
   6100         1,
   6101         1,
   6102         1,
   6103         1,
   6104         1,
   6105         1,
   6106         1,
   6107         1,
   6108         1,
   6109         1,
   6110         1,
   6111         1,
   6112         1,
   6113         1,
   6114         1,
   6115         1,
   6116         1,
   6117         1,
   6118         1,
   6119         1,
   6120         1,
   6121         1,
   6122         1,
   6123         1,
   6124         1,
   6125         1,
   6126         1,
   6127         1,
   6128         1,
   6129         1,
   6130         1,
   6131         1,
   6132         1,
   6133         1,
   6134         1,
   6135         1,
   6136         1,
   6137         1,
   6138         1,
   6139         1,
   6140         1,
   6141         1,
   6142         1,
   6143         1,
   6144         1,
   6145         1,
   6146         1,
   6147         1,
   6148         1,
   6149         1,
   6150         1,
   6151         1,
   6152         1,
   6153         1,
   6154         1,
   6155         1,
   6156         1,
   6157         1,
   6158         1,
   6159         1,
   6160         1,
   6161         1,
   6162         1,
   6163         1,
   6164         1,
   6165         1,
   6166         1,
   6167         1,
   6168         1,
   6169         1,
   6170         1,
   6171         1,
   6172         1,
   6173         1,
   6174         1,
   6175         1,
   6176         1,
   6177         1,
   6178         1,
   6179         1,
   6180         1,
   6181         1,
   6182         1,
   6183         1,
   6184         1,
   6185         1,
   6186         1,
   6187         1,
   6188         1,
   6189         1,
   6190         1,
   6191         1,
   6192         1,
   6193         1,
   6194         1,
   6195         1,
   6196         1,
   6197         1,
   6198         1,
   6199         1,
   6200         1,
   6201         1,
   6202         1,
   6203         1,
   6204         1,
   6205         1,
   6206         1,
   6207         1,
   6208         1,
   6209         1,
   6210         1,
   6211         1,
   6212         1,
   6213         1,
   6214         1,
   6215         1,
   6216         1,
   6217         1,
   6218         1,
   6219         1,
   6220         1,
   6221         1,
   6222         1,
   6223         1,
   6224         1,
   6225         1,
   6226         1,
   6227         1,
   6228         1,
   6229         1,
   6230         1,
   6231         1,
   6232         1,
   6233         1,
   6234         1,
   6235         1,
   6236         1,
   6237         1,
   6238         1,
   6239         1,
   6240         1,
   6241         1,
   6242         1,
   6243         1,
   6244         1,
   6245         1,
   6246         1,
   6247         1,
   6248         1,
   6249         1,
   6250         1,
   6251         1,
   6252         1,
   6253         1,
   6254         1,
   6255         1,
   6256         1,
   6257         1,
   6258         1,
   6259         1,
   6260         1,
   6261         1,
   6262         1,
   6263         1,
   6264         1,
   6265         1,
   6266         1,
   6267         1,
   6268         1,
   6269         1,
   6270         1,
   6271         1,
   6272         1,
   6273         1,
   6274         1,
   6275         1,
   6276         1,
   6277         1,
   6278         1,
   6279         1,
   6280         1,
   6281         1,
   6282         1,
   6283         1,
   6284         1,
   6285         1,
   6286         1,
   6287         1,
   6288         1,
   6289         1,
   6290         1,
   6291         1,
   6292         1,
   6293         1,
   6294         1,
   6295         1,
   6296         1,
   6297         1,
   6298         1,
   6299         1,
   6300         1,
   6301         1,
   6302         1,
   6303         1,
   6304         1,
   6305         1,
   6306         1,
   6307         1,
   6308         1,
   6309         1,
   6310         1,
   6311         1,
   6312         1,
   6313         1,
   6314         1,
   6315         1,
   6316         1,
   6317         1,
   6318         1,
   6319         1,
   6320         1,
   6321         1,
   6322         1,
   6323         1,
   6324         1,
   6325         1,
   6326         1,
   6327         1,
   6328         1,
   6329         1,
   6330         1,
   6331         1,
   6332         1,
   6333         1,
   6334         1,
   6335         1,
   6336         1,
   6337         1,
   6338         1,
   6339         1,
   6340         1,
   6341         1,
   6342         1,
   6343         1,
   6344         1,
   6345         1,
   6346         1,
   6347         1,
   6348         1,
   6349         1,
   6350         1,
   6351         1,
   6352         1,
   6353         1,
   6354         1,
   6355         1,
   6356         1,
   6357         1,
   6358         1,
   6359         1,
   6360         1,
   6361         1,
   6362         1,
   6363         1,
   6364         1,
   6365         1,
   6366         1,
   6367         1,
   6368         1,
   6369         1,
   6370         1,
   6371         1,
   6372         1,
   6373         1,
   6374         1,
   6375         1,
   6376         1,
   6377         1,
   6378         1,
   6379         1,
   6380         1,
   6381         1,
   6382         1,
   6383         1,
   6384         1,
   6385         1,
   6386         1,
   6387         1,
   6388         1,
   6389         1,
   6390         1,
   6391         1,
   6392         1,
   6393         1,
   6394         1,
   6395         1,
   6396         1,
   6397         1,
   6398         1,
   6399         1,
   6400         1,
   6401         1,
   6402         1,
   6403         1,
   6404         1,
   6405         1,
   6406         1,
   6407         1,
   6408         1,
   6409         1,
   6410         1,
   6411         1,
   6412         1,
   6413         1,
   6414         1,
   6415         1,
   6416         1,
   6417         1,
   6418         1,
   6419         1,
   6420         1,
   6421         1,
   6422         1,
   6423         1,
   6424         1,
   6425         1,
   6426         1,
   6427         1,
   6428         1,
   6429         1,
   6430         1,
   6431         1,
   6432         1,
   6433         1,
   6434         1,
   6435         1,
   6436         1,
   6437         1,
   6438         1,
   6439         1,
   6440         1,
   6441         1,
   6442         1,
   6443         1,
   6444         1,
   6445         1,
   6446         1,
   6447         1,
   6448         1,
   6449         1,
   6450         1,
   6451         1,
   6452         1,
   6453         1,
   6454         1,
   6455         1,
   6456         1,
   6457         1,
   6458         1,
   6459         1,
   6460         1,
   6461         1,
   6462         1,
   6463         1,
   6464         1,
   6465         1,
   6466         1,
   6467         1,
   6468         1,
   6469         1,
   6470         1,
   6471         1,
   6472         1,
   6473         1,
   6474         1,
   6475         1,
   6476         1,
   6477         1,
   6478         1,
   6479         1,
   6480         1,
   6481         1,
   6482         1,
   6483         1,
   6484         1,
   6485         1,
   6486         1,
   6487         1,
   6488         1,
   6489         1,
   6490         1,
   6491         1,
   6492         1,
   6493         1,
   6494         1,
   6495         1,
   6496         1,
   6497         1,
   6498         1,
   6499         1,
   6500         1,
   6501         1,
   6502         1,
   6503         1,
   6504         1,
   6505         1,
   6506         1,
   6507         1,
   6508         1,
   6509         1,
   6510         1,
   6511         1,
   6512         1,
   6513         1,
   6514         1,
   6515         1,
   6516         1,
   6517         1,
   6518         1,
   6519         1,
   6520         1,
   6521         1,
   6522         1,
   6523         1,
   6524         1,
   6525         1,
   6526         1,
   6527         1,
   6528         1,
   6529         1,
   6530         1,
   6531         1,
   6532         1,
   6533         1,
   6534         1,
   6535         1,
   6536         1,
   6537         1,
   6538         1,
   6539         1,
   6540         1,
   6541         1,
   6542         1,
   6543         1,
   6544         1,
   6545         1,
   6546         1,
   6547         1,
   6548         1,
   6549         1,
   6550         1,
   6551         1,
   6552         1,
   6553         1,
   6554         1,
   6555         1,
   6556         1,
   6557         1,
   6558         1,
   6559         1,
   6560         1,
   6561         1,
   6562         1,
   6563         1,
   6564         1,
   6565         1,
   6566         1,
   6567         1,
   6568         1,
   6569         1,
   6570         1,
   6571         1,
   6572         1,
   6573         1,
   6574         1,
   6575         1,
   6576         1,
   6577         1,
   6578         1,
   6579         1,
   6580         1,
   6581         1,
   6582         1,
   6583         1,
   6584         1,
   6585         1,
   6586         1,
   6587         1,
   6588         1,
   6589         1,
   6590         1,
   6591         1,
   6592         1,
   6593         1,
   6594         1,
   6595         1,
   6596         1,
   6597         1,
   6598         1,
   6599         1,
   6600         1,
   6601         1,
   6602         1,
   6603         1,
   6604         1,
   6605         1,
   6606         1,
   6607         1,
   6608         1,
   6609         1,
   6610         1,
   6611         1,
   6612         1,
   6613         1,
   6614         1,
   6615         1,
   6616         1,
   6617         1,
   6618         1,
   6619         1,
   6620         1,
   6621         1,
   6622         1,
   6623         1,
   6624         1,
   6625         1,
   6626         1,
   6627         1,
   6628         1,
   6629         1,
   6630         1,
   6631         1,
   6632         1,
   6633         1,
   6634         1,
   6635         1,
   6636         1,
   6637         1,
   6638         1,
   6639         1,
   6640         1,
   6641         1,
   6642         1,
   6643         1,
   6644         1,
   6645         1,
   6646         1,
   6647         1,
   6648         1,
   6649         1,
   6650         1,
   6651         1,
   6652         1,
   6653         1,
   6654         1,
   6655         1,
   6656         1,
   6657         1,
   6658         1,
   6659         1,
   6660         1,
   6661         1,
   6662         1,
   6663         1,
   6664         1,
   6665         1,
   6666         1,
   6667         1,
   6668         1,
   6669         1,
   6670         1,
   6671         1,
   6672         1,
   6673         1,
   6674         1,
   6675         1,
   6676         1,
   6677         1,
   6678         1,
   6679         1,
   6680         1,
   6681         1,
   6682         1,
   6683         1,
   6684         1,
   6685         1,
   6686         1,
   6687         1,
   6688         1,
   6689         1,
   6690         1,
   6691         1,
   6692         1,
   6693         1,
   6694         1,
   6695         1,
   6696         1,
   6697         1,
   6698         1,
   6699         1,
   6700         1,
   6701         1,
   6702         1,
   6703         1,
   6704         1,
   6705         1,
   6706         1,
   6707         1,
   6708         1,
   6709         1,
   6710         1,
   6711         1,
   6712         1,
   6713         1,
   6714         1,
   6715         1,
   6716         1,
   6717         1,
   6718         1,
   6719         1,
   6720         1,
   6721         1,
   6722         1,
   6723         1,
   6724         1,
   6725         1,
   6726         1,
   6727         1,
   6728         1,
   6729         1,
   6730         1,
   6731         1,
   6732         1,
   6733         1,
   6734         1,
   6735         1,
   6736         1,
   6737         1,
   6738         1,
   6739         1,
   6740         1,
   6741         1,
   6742         1,
   6743         1,
   6744         1,
   6745         1,
   6746         1,
   6747         1,
   6748         1,
   6749         1,
   6750         1,
   6751         1,
   6752         1,
   6753         1,
   6754         1,
   6755         1,
   6756         1,
   6757         1,
   6758         1,
   6759         1,
   6760         1,
   6761         1,
   6762         1,
   6763         1,
   6764         1,
   6765         1,
   6766         1,
   6767         1,
   6768         1,
   6769         1,
   6770         1,
   6771         1,
   6772         1,
   6773         1,
   6774         1,
   6775         1,
   6776         1,
   6777         1,
   6778         1,
   6779         1,
   6780         1,
   6781         1,
   6782         1,
   6783         1,
   6784         1,
   6785         1,
   6786         1,
   6787         1,
   6788         1,
   6789         1,
   6790         1,
   6791         1,
   6792         1,
   6793         1,
   6794         1,
   6795         1,
   6796         1,
   6797         1,
   6798         1,
   6799         1,
   6800         1,
   6801         1,
   6802         1,
   6803         1,
   6804         1,
   6805         1,
   6806         1,
   6807         1,
   6808         1,
   6809         1,
   6810         1,
   6811         1,
   6812         1,
   6813         1,
   6814         1,
   6815         1,
   6816         1,
   6817         1,
   6818         1,
   6819         1,
   6820         1,
   6821         1,
   6822         1,
   6823         1,
   6824         1,
   6825         1,
   6826         1,
   6827         1,
   6828         1,
   6829         1,
   6830         1,
   6831         1,
   6832         1,
   6833         1,
   6834         1,
   6835         1,
   6836         1,
   6837         1,
   6838         1,
   6839         1,
   6840         1,
   6841         1,
   6842         1,
   6843         1,
   6844         1,
   6845         1,
   6846         1,
   6847         1,
   6848         1,
   6849         1,
   6850         1,
   6851         1,
   6852         1,
   6853         1,
   6854         1,
   6855         1,
   6856         1,
   6857         1,
   6858         1,
   6859         1,
   6860         1,
   6861         1,
   6862         1,
   6863         1,
   6864         1,
   6865         1,
   6866         1,
   6867         1,
   6868         1,
   6869         1,
   6870         1,
   6871         1,
   6872         1,
   6873         1,
   6874         1,
   6875         1,
   6876         1,
   6877         1,
   6878         1,
   6879         1,
   6880         1,
   6881         1,
   6882         1,
   6883         1,
   6884         1,
   6885         1,
   6886         1,
   6887         1,
   6888         1,
   6889         1,
   6890         1,
   6891         1,
   6892         1,
   6893         1,
   6894         1,
   6895         1,
   6896         1,
   6897         1,
   6898         1,
   6899         1,
   6900         1,
   6901         1,
   6902         1,
   6903         1,
   6904         1,
   6905         1,
   6906         1,
   6907         1,
   6908         1,
   6909         1,
   6910         1,
   6911         1,
   6912         1,
   6913         1,
   6914         1,
   6915         1,
   6916         1,
   6917         1,
   6918         1,
   6919         1,
   6920         1,
   6921         1,
   6922         1,
   6923         1,
   6924         1,
   6925         1,
   6926         1,
   6927         1,
   6928         1,
   6929         1,
   6930         1,
   6931         1,
   6932         1,
   6933         1,
   6934         1,
   6935         1,
   6936         1,
   6937         1,
   6938         1,
   6939         1,
   6940         1,
   6941         1,
   6942         1,
   6943         1,
   6944         1,
   6945         1,
   6946         1,
   6947         1,
   6948         1,
   6949         1,
   6950         1,
   6951         1,
   6952         1,
   6953         1,
   6954         1,
   6955         1,
   6956         1,
   6957         1,
   6958         1,
   6959         1,
   6960         1,
   6961         1,
   6962         1,
   6963         1,
   6964         1,
   6965         1,
   6966         1,
   6967         1,
   6968         1,
   6969         1,
   6970         1,
   6971         1,
   6972         1,
   6973         1,
   6974         1,
   6975         1,
   6976         1,
   6977         1,
   6978         1,
   6979         1,
   6980         1,
   6981         1,
   6982         1,
   6983         1,
   6984         1,
   6985         1,
   6986         1,
   6987         1,
   6988         1,
   6989         1,
   6990         1,
   6991         1,
   6992         1,
   6993         1,
   6994         1,
   6995         1,
   6996         1,
   6997         1,
   6998         1,
   6999         1,
   7000         1,
   7001         1,
   7002         1,
   7003         1,
   7004         1,
   7005         1,
   7006         1,
   7007         1,
   7008         1,
   7009         1,
   7010         1,
   7011         1,
   7012         1,
   7013         1,
   7014         1,
   7015         1,
   7016         1,
   7017         1,
   7018         1,
   7019         1,
   7020         1,
   7021         1,
   7022         1,
   7023         1,
   7024         1,
   7025         1,
   7026         1,
   7027         1,
   7028         1,
   7029         1,
   7030         1,
   7031         1,
   7032         1,
   7033         1,
   7034         1,
   7035         1,
   7036         1,
   7037         1,
   7038         1,
   7039         1,
   7040         1,
   7041         1,
   7042         1,
   7043         1,
   7044         1,
   7045         1,
   7046         1,
   7047         1,
   7048         1,
   7049         1,
   7050         1,
   7051         1,
   7052         1,
   7053         1,
   7054         1,
   7055         1,
   7056         1,
   7057         1,
   7058         1,
   7059         1,
   7060         1,
   7061         1,
   7062         1,
   7063         1,
   7064         1,
   7065         1,
   7066         1,
   7067         1,
   7068         1,
   7069         1,
   7070         1,
   7071         1,
   7072         1,
   7073         1,
   7074         1,
   7075         1,
   7076         1,
   7077         1,
   7078         1,
   7079         1,
   7080         1,
   7081         1,
   7082         1,
   7083         1,
   7084         1,
   7085         1,
   7086         1,
   7087         1,
   7088         1,
   7089         1,
   7090         1,
   7091         1,
   7092         1,
   7093         1,
   7094         1,
   7095         1,
   7096         1,
   7097         1,
   7098         1,
   7099         1,
   7100         1,
   7101         1,
   7102         1,
   7103         1,
   7104         1,
   7105         1,
   7106         1,
   7107         1,
   7108         1,
   7109         1,
   7110         1,
   7111         1,
   7112         1,
   7113         1,
   7114         1,
   7115         1,
   7116         1,
   7117         1,
   7118         1,
   7119         1,
   7120         1,
   7121         1,
   7122         1,
   7123         1,
   7124         1,
   7125         1,
   7126         1,
   7127         1,
   7128         1,
   7129         1,
   7130         1,
   7131         1,
   7132         1,
   7133         1,
   7134         1,
   7135         1,
   7136         1,
   7137         1,
   7138         1,
   7139         1,
   7140         1,
   7141         1,
   7142         1,
   7143         1,
   7144         1,
   7145         1,
   7146         1,
   7147         1,
   7148         1,
   7149         1,
   7150         1,
   7151         1,
   7152         1,
   7153         1,
   7154         1,
   7155         1,
   7156         1,
   7157         1,
   7158         1,
   7159         1,
   7160         1,
   7161         1,
   7162         1,
   7163         1,
   7164         1,
   7165         1,
   7166         1,
   7167         1,
   7168         1,
   7169         1,
   7170         1,
   7171         1,
   7172         1,
   7173         1,
   7174         1,
   7175         1,
   7176         1,
   7177         1,
   7178         1,
   7179         1,
   7180         1,
   7181         1,
   7182         1,
   7183         1,
   7184         1,
   7185         1,
   7186         1,
   7187         1,
   7188         1,
   7189         1,
   7190         1,
   7191         1,
   7192         1,
   7193         1,
   7194         1,
   7195         1,
   7196         1,
   7197         1,
   7198         1,
   7199         1,
   7200         1,
   7201         1,
   7202         1,
   7203         1,
   7204         1,
   7205         1,
   7206         1,
   7207         1,
   7208         1,
   7209         1,
   7210         1,
   7211         1,
   7212         1,
   7213         1,
   7214         1,
   7215         1,
   7216         1,
   7217         1,
   7218         1,
   7219         1,
   7220         1,
   7221         1,
   7222         1,
   7223         1,
   7224         1,
   7225         1,
   7226         1,
   7227         1,
   7228         1,
   7229         1,
   7230         1,
   7231         1,
   7232         1,
   7233         1,
   7234         1,
   7235         1,
   7236         1,
   7237         1,
   7238         1,
   7239         1,
   7240         1,
   7241         1,
   7242         1,
   7243         1,
   7244         1,
   7245         1,
   7246         1,
   7247         1,
   7248         1,
   7249         1,
   7250         1,
   7251         1,
   7252         1,
   7253         1,
   7254         1,
   7255         1,
   7256         1,
   7257         1,
   7258         1,
   7259         1,
   7260         1,
   7261         1,
   7262         1,
   7263         1,
   7264         1,
   7265         1,
   7266         1,
   7267         1,
   7268         1,
   7269         1,
   7270         1,
   7271         1,
   7272         1,
   7273         1,
   7274         1,
   7275         1,
   7276         1,
   7277         1,
   7278         1,
   7279         1,
   7280         1,
   7281         1,
   7282         1,
   7283         1,
   7284         1,
   7285         1,
   7286         1,
   7287         1,
   7288         1,
   7289         1,
   7290         1,
   7291         1,
   7292         1,
   7293         1,
   7294         1,
   7295         1,
   7296         1,
   7297         1,
   7298         1,
   7299         1,
   7300         1,
   7301         1,
   7302         1,
   7303         1,
   7304         1,
   7305         1,
   7306         1,
   7307         1,
   7308         1,
   7309         1,
   7310         1,
   7311         1,
   7312         1,
   7313         1,
   7314         1,
   7315         1,
   7316         1,
   7317         1,
   7318         1,
   7319         1,
   7320         1,
   7321         1,
   7322         1,
   7323         1,
   7324         1,
   7325         1,
   7326         1,
   7327         1,
   7328         1,
   7329         1,
   7330         1,
   7331         1,
   7332         1,
   7333         1,
   7334         1,
   7335         1,
   7336         1,
   7337         1,
   7338         1,
   7339         1,
   7340         1,
   7341         1,
   7342         1,
   7343         1,
   7344         1,
   7345         1,
   7346         1,
   7347         1,
   7348         1,
   7349         1,
   7350         1,
   7351         1,
   7352         1,
   7353         1,
   7354         1,
   7355         1,
   7356         1,
   7357         1,
   7358         1,
   7359         1,
   7360         1,
   7361         1,
   7362         1,
   7363         1,
   7364         1,
   7365         1,
   7366         1,
   7367         1,
   7368         1,
   7369         1,
   7370         1,
   7371         1,
   7372         1,
   7373         1,
   7374         1,
   7375         1,
   7376         1,
   7377         1,
   7378         1,
   7379         1,
   7380         1,
   7381         1,
   7382         1,
   7383         1,
   7384         1,
   7385         1,
   7386         1,
   7387         1,
   7388         1,
   7389         1,
   7390         1,
   7391         1,
   7392         1,
   7393         1,
   7394         1,
   7395         1,
   7396         1,
   7397         1,
   7398         1,
   7399         1,
   7400         1,
   7401         1,
   7402         1,
   7403         1,
   7404         1,
   7405         1,
   7406         1,
   7407         1,
   7408         1,
   7409         1,
   7410         1,
   7411         1,
   7412         1,
   7413         1,
   7414         1,
   7415         1,
   7416         1,
   7417         1,
   7418         1,
   7419         1,
   7420         1,
   7421         1,
   7422         1,
   7423         1,
   7424         1,
   7425         1,
   7426         1,
   7427         1,
   7428         1,
   7429         1,
   7430         1,
   7431         1,
   7432         1,
   7433         1,
   7434         1,
   7435         1,
   7436         1,
   7437         1,
   7438         1,
   7439         1,
   7440         1,
   7441         1,
   7442         1,
   7443         1,
   7444         1,
   7445         1,
   7446         1,
   7447         1,
   7448         1,
   7449         1,
   7450         1,
   7451         1,
   7452         1,
   7453         1,
   7454         1,
   7455         1,
   7456         1,
   7457         1,
   7458         1,
   7459         1,
   7460         1,
   7461         1,
   7462         1,
   7463         1,
   7464         1,
   7465         1,
   7466         1,
   7467         1,
   7468         1,
   7469         1,
   7470         1,
   7471         1,
   7472         1,
   7473         1,
   7474         1,
   7475         1,
   7476         1,
   7477         1,
   7478         1,
   7479         1,
   7480         1,
   7481         1,
   7482         1,
   7483         1,
   7484         1,
   7485         1,
   7486         1,
   7487         1,
   7488         1,
   7489         1,
   7490         1,
   7491         1,
   7492         1,
   7493         1,
   7494         1,
   7495         1,
   7496         1,
   7497         1,
   7498         1,
   7499         1,
   7500         1,
   7501         1,
   7502         1,
   7503         1,
   7504         1,
   7505         1,
   7506         1,
   7507         1,
   7508         1,
   7509         1,
   7510         1,
   7511         1,
   7512         1,
   7513         1,
   7514         1,
   7515         1,
   7516         1,
   7517         1,
   7518         1,
   7519         1,
   7520         1,
   7521         1,
   7522         1,
   7523         1,
   7524         1,
   7525         1,
   7526         1,
   7527         1,
   7528         1,
   7529         1,
   7530         1,
   7531         1,
   7532         1,
   7533         1,
   7534         1,
   7535         1,
   7536         1,
   7537         1,
   7538         1,
   7539         1,
   7540         1,
   7541         1,
   7542         1,
   7543         1,
   7544         1,
   7545         1,
   7546         1,
   7547         1,
   7548         1,
   7549         1,
   7550         1,
   7551         1,
   7552         1,
   7553         1,
   7554         1,
   7555         1,
   7556         1,
   7557         1,
   7558         1,
   7559         1,
   7560         1,
   7561         1,
   7562         1,
   7563         1,
   7564         1,
   7565         1,
   7566         1,
   7567         1,
   7568         1,
   7569         1,
   7570         1,
   7571         1,
   7572         1,
   7573         1,
   7574         1,
   7575         1,
   7576         1,
   7577         1,
   7578         1,
   7579         1,
   7580         1,
   7581         1,
   7582         1,
   7583         1,
   7584         1,
   7585         1,
   7586         1,
   7587         1,
   7588         1,
   7589         1,
   7590         1,
   7591         1,
   7592         1,
   7593         1,
   7594         1,
   7595         1,
   7596         1,
   7597         1,
   7598         1,
   7599         1,
   7600         1,
   7601         1,
   7602         1,
   7603         1,
   7604         1,
   7605         1,
   7606         1,
   7607         1,
   7608         1,
   7609         1,
   7610         1,
   7611         1,
   7612         1,
   7613         1,
   7614         1,
   7615         1,
   7616         1,
   7617         1,
   7618         1,
   7619         1,
   7620         1,
   7621         1,
   7622         1,
   7623         1,
   7624         1,
   7625         1,
   7626         1,
   7627         1,
   7628         1,
   7629         1,
   7630         1,
   7631         1,
   7632         1,
   7633         1,
   7634         1,
   7635         1,
   7636         1,
   7637         1,
   7638         1,
   7639         1,
   7640         1,
   7641         1,
   7642         1,
   7643         1,
   7644         1,
   7645         1,
   7646         1,
   7647     ];
   7648     let pub_key = MlDsaVerKey::<MlDsa65>::decode(&[1u8; 1952].into())
   7649         .to_public_key_der()
   7650         .unwrap();
   7651     let att_obj_len = att_obj.len();
   7652     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
   7653     let b64_adata = base64url_nopad::encode(&att_obj[att_obj_len - 2033..]);
   7654     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
   7655     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
   7656     // Base case is valid.
   7657     assert!(
   7658         serde_json::from_str::<Registration>(
   7659             serde_json::json!({
   7660                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7661                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7662                 "response": {
   7663                     "clientDataJSON": b64_cdata_json,
   7664                     "authenticatorData": b64_adata,
   7665                     "transports": [],
   7666                     "publicKey": b64_key,
   7667                     "publicKeyAlgorithm": -49i8,
   7668                     "attestationObject": b64_aobj,
   7669                 },
   7670                 "clientExtensionResults": {},
   7671                 "type": "public-key"
   7672             })
   7673             .to_string()
   7674             .as_str()
   7675         )
   7676         .is_ok_and(
   7677             |reg| reg.response.client_data_json == c_data_json.as_bytes()
   7678                 && reg.response.attestation_object_and_c_data_hash[..att_obj_len] == att_obj
   7679                 && reg.response.attestation_object_and_c_data_hash[att_obj_len..]
   7680                     == *Sha256::digest(c_data_json.as_bytes())
   7681                 && reg.response.transports.is_empty()
   7682                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
   7683                 && reg.client_extension_results.cred_props.is_none()
   7684                 && reg.client_extension_results.prf.is_none()
   7685         )
   7686     );
   7687     // `publicKeyAlgorithm` mismatch.
   7688     let mut err = Error::invalid_value(
   7689         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Eddsa).as_str()),
   7690         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa65).as_str()
   7691     )
   7692     .to_string().into_bytes();
   7693     assert_eq!(
   7694         serde_json::from_str::<Registration>(
   7695             serde_json::json!({
   7696                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7697                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7698                 "response": {
   7699                     "clientDataJSON": b64_cdata_json,
   7700                     "authenticatorData": b64_adata,
   7701                     "transports": [],
   7702                     "publicKey": b64_key,
   7703                     "publicKeyAlgorithm": -8i8,
   7704                     "attestationObject": b64_aobj,
   7705                 },
   7706                 "clientExtensionResults": {},
   7707                 "type": "public-key"
   7708             })
   7709             .to_string()
   7710             .as_str()
   7711         )
   7712         .unwrap_err()
   7713         .to_string()
   7714         .into_bytes()
   7715         .get(..err.len()),
   7716         Some(err.as_slice())
   7717     );
   7718     // Missing `publicKeyAlgorithm`.
   7719     err = Error::missing_field("publicKeyAlgorithm")
   7720         .to_string()
   7721         .into_bytes();
   7722     assert_eq!(
   7723         serde_json::from_str::<Registration>(
   7724             serde_json::json!({
   7725                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7726                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7727                 "response": {
   7728                     "clientDataJSON": b64_cdata_json,
   7729                     "authenticatorData": b64_adata,
   7730                     "transports": [],
   7731                     "publicKey": b64_key,
   7732                     "attestationObject": b64_aobj,
   7733                 },
   7734                 "clientExtensionResults": {},
   7735                 "type": "public-key"
   7736             })
   7737             .to_string()
   7738             .as_str()
   7739         )
   7740         .unwrap_err()
   7741         .to_string()
   7742         .into_bytes()
   7743         .get(..err.len()),
   7744         Some(err.as_slice())
   7745     );
   7746     // `null` `publicKeyAlgorithm`.
   7747     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
   7748         .to_string()
   7749         .into_bytes();
   7750     assert_eq!(
   7751         serde_json::from_str::<Registration>(
   7752             serde_json::json!({
   7753                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7754                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7755                 "response": {
   7756                     "clientDataJSON": b64_cdata_json,
   7757                     "authenticatorData": b64_adata,
   7758                     "transports": [],
   7759                     "publicKey": b64_key,
   7760                     "publicKeyAlgorithm": null,
   7761                     "attestationObject": b64_aobj,
   7762                 },
   7763                 "clientExtensionResults": {},
   7764                 "type": "public-key"
   7765             })
   7766             .to_string()
   7767             .as_str()
   7768         )
   7769         .unwrap_err()
   7770         .to_string()
   7771         .into_bytes()
   7772         .get(..err.len()),
   7773         Some(err.as_slice())
   7774     );
   7775     // `publicKey` mismatch.
   7776     let bad_pub_key = MlDsaVerKey::<MlDsa65>::decode(&[2; 1952].into());
   7777     err = Error::invalid_value(
   7778         Unexpected::Bytes([0; 32].as_slice()),
   7779         &format!(
   7780             "DER-encoded public key to match the public key within the attestation object: MlDsa65(MlDsa65PubKey({:?}))",
   7781             &[1u8; 1952]
   7782         )
   7783         .as_str(),
   7784     )
   7785     .to_string().into_bytes();
   7786     assert_eq!(serde_json::from_str::<Registration>(
   7787         serde_json::json!({
   7788             "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7789             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7790             "response": {
   7791                 "clientDataJSON": b64_cdata_json,
   7792                 "authenticatorData": b64_adata,
   7793                 "transports": [],
   7794                 "publicKey": base64url_nopad::encode(bad_pub_key.to_public_key_der().unwrap().as_bytes()),
   7795                 "publicKeyAlgorithm": -49i8,
   7796                 "attestationObject": b64_aobj,
   7797             },
   7798             "clientExtensionResults": {},
   7799             "type": "public-key"
   7800         })
   7801         .to_string()
   7802         .as_str()
   7803         )
   7804         .unwrap_err().to_string().into_bytes().get(..err.len()),
   7805         Some(err.as_slice())
   7806     );
   7807     // Missing `publicKey` is allowed when not using EdDSA, ES256, or RS256.
   7808     assert!(
   7809         serde_json::from_str::<Registration>(
   7810             serde_json::json!({
   7811                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7812                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7813                 "response": {
   7814                     "clientDataJSON": b64_cdata_json,
   7815                     "authenticatorData": b64_adata,
   7816                     "transports": [],
   7817                     "publicKeyAlgorithm": -49i8,
   7818                     "attestationObject": b64_aobj,
   7819                 },
   7820                 "clientExtensionResults": {},
   7821                 "type": "public-key"
   7822             })
   7823             .to_string()
   7824             .as_str()
   7825         )
   7826         .is_ok()
   7827     );
   7828     // `publicKeyAlgorithm` mismatch when `publicKey` does not exist.
   7829     err = Error::invalid_value(
   7830         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
   7831         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa65).as_str()
   7832     )
   7833     .to_string().into_bytes();
   7834     assert_eq!(
   7835         serde_json::from_str::<Registration>(
   7836             serde_json::json!({
   7837                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7838                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7839                 "response": {
   7840                     "clientDataJSON": b64_cdata_json,
   7841                     "authenticatorData": b64_adata,
   7842                     "transports": [],
   7843                     "publicKeyAlgorithm": -7i8,
   7844                     "attestationObject": b64_aobj,
   7845                 },
   7846                 "clientExtensionResults": {},
   7847                 "type": "public-key"
   7848             })
   7849             .to_string()
   7850             .as_str()
   7851         )
   7852         .unwrap_err()
   7853         .to_string()
   7854         .into_bytes()
   7855         .get(..err.len()),
   7856         Some(err.as_slice())
   7857     );
   7858     // `null` `publicKey` is allowed when not using EdDSA, ES256, or RS256.
   7859     assert!(
   7860         serde_json::from_str::<Registration>(
   7861             serde_json::json!({
   7862                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7863                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7864                 "response": {
   7865                     "clientDataJSON": b64_cdata_json,
   7866                     "authenticatorData": b64_adata,
   7867                     "transports": [],
   7868                     "publicKey": null,
   7869                     "publicKeyAlgorithm": -49i8,
   7870                     "attestationObject": b64_aobj,
   7871                 },
   7872                 "clientExtensionResults": {},
   7873                 "type": "public-key"
   7874             })
   7875             .to_string()
   7876             .as_str()
   7877         )
   7878         .is_ok()
   7879     );
   7880     // `publicKeyAlgorithm` mismatch when `publicKey` is null.
   7881     err = Error::invalid_value(
   7882         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
   7883         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa65).as_str()
   7884     )
   7885     .to_string().into_bytes();
   7886     assert_eq!(
   7887         serde_json::from_str::<Registration>(
   7888             serde_json::json!({
   7889                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   7890                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   7891                 "response": {
   7892                     "clientDataJSON": b64_cdata_json,
   7893                     "authenticatorData": b64_adata,
   7894                     "transports": [],
   7895                     "publicKey": null,
   7896                     "publicKeyAlgorithm": -7i8,
   7897                     "attestationObject": b64_aobj,
   7898                 },
   7899                 "clientExtensionResults": {},
   7900                 "type": "public-key"
   7901             })
   7902             .to_string()
   7903             .as_str()
   7904         )
   7905         .unwrap_err()
   7906         .to_string()
   7907         .into_bytes()
   7908         .get(..err.len()),
   7909         Some(err.as_slice())
   7910     );
   7911 }
   7912 #[expect(
   7913     clippy::assertions_on_result_states,
   7914     clippy::unwrap_used,
   7915     reason = "OK in tests"
   7916 )]
   7917 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
   7918 #[expect(clippy::too_many_lines, reason = "a lot to test")]
   7919 #[test]
   7920 fn mldsa44_registration_deserialize_data_mismatch() {
   7921     let c_data_json = serde_json::json!({}).to_string();
   7922     let att_obj: [u8; 1424] = [
   7923         cbor::MAP_3,
   7924         cbor::TEXT_3,
   7925         b'f',
   7926         b'm',
   7927         b't',
   7928         cbor::TEXT_4,
   7929         b'n',
   7930         b'o',
   7931         b'n',
   7932         b'e',
   7933         cbor::TEXT_7,
   7934         b'a',
   7935         b't',
   7936         b't',
   7937         b'S',
   7938         b't',
   7939         b'm',
   7940         b't',
   7941         cbor::MAP_0,
   7942         cbor::TEXT_8,
   7943         b'a',
   7944         b'u',
   7945         b't',
   7946         b'h',
   7947         b'D',
   7948         b'a',
   7949         b't',
   7950         b'a',
   7951         cbor::BYTES_INFO_25,
   7952         5,
   7953         113,
   7954         // `rpIdHash`.
   7955         0,
   7956         0,
   7957         0,
   7958         0,
   7959         0,
   7960         0,
   7961         0,
   7962         0,
   7963         0,
   7964         0,
   7965         0,
   7966         0,
   7967         0,
   7968         0,
   7969         0,
   7970         0,
   7971         0,
   7972         0,
   7973         0,
   7974         0,
   7975         0,
   7976         0,
   7977         0,
   7978         0,
   7979         0,
   7980         0,
   7981         0,
   7982         0,
   7983         0,
   7984         0,
   7985         0,
   7986         0,
   7987         // `flags`.
   7988         0b0100_0101,
   7989         // `signCount`.
   7990         0,
   7991         0,
   7992         0,
   7993         0,
   7994         // `aaguid`.
   7995         0,
   7996         0,
   7997         0,
   7998         0,
   7999         0,
   8000         0,
   8001         0,
   8002         0,
   8003         0,
   8004         0,
   8005         0,
   8006         0,
   8007         0,
   8008         0,
   8009         0,
   8010         0,
   8011         // `credentialIdLength`.
   8012         0,
   8013         16,
   8014         // `credentialId`.
   8015         0,
   8016         0,
   8017         0,
   8018         0,
   8019         0,
   8020         0,
   8021         0,
   8022         0,
   8023         0,
   8024         0,
   8025         0,
   8026         0,
   8027         0,
   8028         0,
   8029         0,
   8030         0,
   8031         // ML-DSA-44 COSE key.
   8032         cbor::MAP_3,
   8033         KTY,
   8034         AKP,
   8035         ALG,
   8036         cbor::NEG_INFO_24,
   8037         MLDSA44,
   8038         // `pub`.
   8039         cbor::NEG_ONE,
   8040         cbor::BYTES_INFO_25,
   8041         5,
   8042         32,
   8043         // Encoded key.
   8044         1,
   8045         1,
   8046         1,
   8047         1,
   8048         1,
   8049         1,
   8050         1,
   8051         1,
   8052         1,
   8053         1,
   8054         1,
   8055         1,
   8056         1,
   8057         1,
   8058         1,
   8059         1,
   8060         1,
   8061         1,
   8062         1,
   8063         1,
   8064         1,
   8065         1,
   8066         1,
   8067         1,
   8068         1,
   8069         1,
   8070         1,
   8071         1,
   8072         1,
   8073         1,
   8074         1,
   8075         1,
   8076         1,
   8077         1,
   8078         1,
   8079         1,
   8080         1,
   8081         1,
   8082         1,
   8083         1,
   8084         1,
   8085         1,
   8086         1,
   8087         1,
   8088         1,
   8089         1,
   8090         1,
   8091         1,
   8092         1,
   8093         1,
   8094         1,
   8095         1,
   8096         1,
   8097         1,
   8098         1,
   8099         1,
   8100         1,
   8101         1,
   8102         1,
   8103         1,
   8104         1,
   8105         1,
   8106         1,
   8107         1,
   8108         1,
   8109         1,
   8110         1,
   8111         1,
   8112         1,
   8113         1,
   8114         1,
   8115         1,
   8116         1,
   8117         1,
   8118         1,
   8119         1,
   8120         1,
   8121         1,
   8122         1,
   8123         1,
   8124         1,
   8125         1,
   8126         1,
   8127         1,
   8128         1,
   8129         1,
   8130         1,
   8131         1,
   8132         1,
   8133         1,
   8134         1,
   8135         1,
   8136         1,
   8137         1,
   8138         1,
   8139         1,
   8140         1,
   8141         1,
   8142         1,
   8143         1,
   8144         1,
   8145         1,
   8146         1,
   8147         1,
   8148         1,
   8149         1,
   8150         1,
   8151         1,
   8152         1,
   8153         1,
   8154         1,
   8155         1,
   8156         1,
   8157         1,
   8158         1,
   8159         1,
   8160         1,
   8161         1,
   8162         1,
   8163         1,
   8164         1,
   8165         1,
   8166         1,
   8167         1,
   8168         1,
   8169         1,
   8170         1,
   8171         1,
   8172         1,
   8173         1,
   8174         1,
   8175         1,
   8176         1,
   8177         1,
   8178         1,
   8179         1,
   8180         1,
   8181         1,
   8182         1,
   8183         1,
   8184         1,
   8185         1,
   8186         1,
   8187         1,
   8188         1,
   8189         1,
   8190         1,
   8191         1,
   8192         1,
   8193         1,
   8194         1,
   8195         1,
   8196         1,
   8197         1,
   8198         1,
   8199         1,
   8200         1,
   8201         1,
   8202         1,
   8203         1,
   8204         1,
   8205         1,
   8206         1,
   8207         1,
   8208         1,
   8209         1,
   8210         1,
   8211         1,
   8212         1,
   8213         1,
   8214         1,
   8215         1,
   8216         1,
   8217         1,
   8218         1,
   8219         1,
   8220         1,
   8221         1,
   8222         1,
   8223         1,
   8224         1,
   8225         1,
   8226         1,
   8227         1,
   8228         1,
   8229         1,
   8230         1,
   8231         1,
   8232         1,
   8233         1,
   8234         1,
   8235         1,
   8236         1,
   8237         1,
   8238         1,
   8239         1,
   8240         1,
   8241         1,
   8242         1,
   8243         1,
   8244         1,
   8245         1,
   8246         1,
   8247         1,
   8248         1,
   8249         1,
   8250         1,
   8251         1,
   8252         1,
   8253         1,
   8254         1,
   8255         1,
   8256         1,
   8257         1,
   8258         1,
   8259         1,
   8260         1,
   8261         1,
   8262         1,
   8263         1,
   8264         1,
   8265         1,
   8266         1,
   8267         1,
   8268         1,
   8269         1,
   8270         1,
   8271         1,
   8272         1,
   8273         1,
   8274         1,
   8275         1,
   8276         1,
   8277         1,
   8278         1,
   8279         1,
   8280         1,
   8281         1,
   8282         1,
   8283         1,
   8284         1,
   8285         1,
   8286         1,
   8287         1,
   8288         1,
   8289         1,
   8290         1,
   8291         1,
   8292         1,
   8293         1,
   8294         1,
   8295         1,
   8296         1,
   8297         1,
   8298         1,
   8299         1,
   8300         1,
   8301         1,
   8302         1,
   8303         1,
   8304         1,
   8305         1,
   8306         1,
   8307         1,
   8308         1,
   8309         1,
   8310         1,
   8311         1,
   8312         1,
   8313         1,
   8314         1,
   8315         1,
   8316         1,
   8317         1,
   8318         1,
   8319         1,
   8320         1,
   8321         1,
   8322         1,
   8323         1,
   8324         1,
   8325         1,
   8326         1,
   8327         1,
   8328         1,
   8329         1,
   8330         1,
   8331         1,
   8332         1,
   8333         1,
   8334         1,
   8335         1,
   8336         1,
   8337         1,
   8338         1,
   8339         1,
   8340         1,
   8341         1,
   8342         1,
   8343         1,
   8344         1,
   8345         1,
   8346         1,
   8347         1,
   8348         1,
   8349         1,
   8350         1,
   8351         1,
   8352         1,
   8353         1,
   8354         1,
   8355         1,
   8356         1,
   8357         1,
   8358         1,
   8359         1,
   8360         1,
   8361         1,
   8362         1,
   8363         1,
   8364         1,
   8365         1,
   8366         1,
   8367         1,
   8368         1,
   8369         1,
   8370         1,
   8371         1,
   8372         1,
   8373         1,
   8374         1,
   8375         1,
   8376         1,
   8377         1,
   8378         1,
   8379         1,
   8380         1,
   8381         1,
   8382         1,
   8383         1,
   8384         1,
   8385         1,
   8386         1,
   8387         1,
   8388         1,
   8389         1,
   8390         1,
   8391         1,
   8392         1,
   8393         1,
   8394         1,
   8395         1,
   8396         1,
   8397         1,
   8398         1,
   8399         1,
   8400         1,
   8401         1,
   8402         1,
   8403         1,
   8404         1,
   8405         1,
   8406         1,
   8407         1,
   8408         1,
   8409         1,
   8410         1,
   8411         1,
   8412         1,
   8413         1,
   8414         1,
   8415         1,
   8416         1,
   8417         1,
   8418         1,
   8419         1,
   8420         1,
   8421         1,
   8422         1,
   8423         1,
   8424         1,
   8425         1,
   8426         1,
   8427         1,
   8428         1,
   8429         1,
   8430         1,
   8431         1,
   8432         1,
   8433         1,
   8434         1,
   8435         1,
   8436         1,
   8437         1,
   8438         1,
   8439         1,
   8440         1,
   8441         1,
   8442         1,
   8443         1,
   8444         1,
   8445         1,
   8446         1,
   8447         1,
   8448         1,
   8449         1,
   8450         1,
   8451         1,
   8452         1,
   8453         1,
   8454         1,
   8455         1,
   8456         1,
   8457         1,
   8458         1,
   8459         1,
   8460         1,
   8461         1,
   8462         1,
   8463         1,
   8464         1,
   8465         1,
   8466         1,
   8467         1,
   8468         1,
   8469         1,
   8470         1,
   8471         1,
   8472         1,
   8473         1,
   8474         1,
   8475         1,
   8476         1,
   8477         1,
   8478         1,
   8479         1,
   8480         1,
   8481         1,
   8482         1,
   8483         1,
   8484         1,
   8485         1,
   8486         1,
   8487         1,
   8488         1,
   8489         1,
   8490         1,
   8491         1,
   8492         1,
   8493         1,
   8494         1,
   8495         1,
   8496         1,
   8497         1,
   8498         1,
   8499         1,
   8500         1,
   8501         1,
   8502         1,
   8503         1,
   8504         1,
   8505         1,
   8506         1,
   8507         1,
   8508         1,
   8509         1,
   8510         1,
   8511         1,
   8512         1,
   8513         1,
   8514         1,
   8515         1,
   8516         1,
   8517         1,
   8518         1,
   8519         1,
   8520         1,
   8521         1,
   8522         1,
   8523         1,
   8524         1,
   8525         1,
   8526         1,
   8527         1,
   8528         1,
   8529         1,
   8530         1,
   8531         1,
   8532         1,
   8533         1,
   8534         1,
   8535         1,
   8536         1,
   8537         1,
   8538         1,
   8539         1,
   8540         1,
   8541         1,
   8542         1,
   8543         1,
   8544         1,
   8545         1,
   8546         1,
   8547         1,
   8548         1,
   8549         1,
   8550         1,
   8551         1,
   8552         1,
   8553         1,
   8554         1,
   8555         1,
   8556         1,
   8557         1,
   8558         1,
   8559         1,
   8560         1,
   8561         1,
   8562         1,
   8563         1,
   8564         1,
   8565         1,
   8566         1,
   8567         1,
   8568         1,
   8569         1,
   8570         1,
   8571         1,
   8572         1,
   8573         1,
   8574         1,
   8575         1,
   8576         1,
   8577         1,
   8578         1,
   8579         1,
   8580         1,
   8581         1,
   8582         1,
   8583         1,
   8584         1,
   8585         1,
   8586         1,
   8587         1,
   8588         1,
   8589         1,
   8590         1,
   8591         1,
   8592         1,
   8593         1,
   8594         1,
   8595         1,
   8596         1,
   8597         1,
   8598         1,
   8599         1,
   8600         1,
   8601         1,
   8602         1,
   8603         1,
   8604         1,
   8605         1,
   8606         1,
   8607         1,
   8608         1,
   8609         1,
   8610         1,
   8611         1,
   8612         1,
   8613         1,
   8614         1,
   8615         1,
   8616         1,
   8617         1,
   8618         1,
   8619         1,
   8620         1,
   8621         1,
   8622         1,
   8623         1,
   8624         1,
   8625         1,
   8626         1,
   8627         1,
   8628         1,
   8629         1,
   8630         1,
   8631         1,
   8632         1,
   8633         1,
   8634         1,
   8635         1,
   8636         1,
   8637         1,
   8638         1,
   8639         1,
   8640         1,
   8641         1,
   8642         1,
   8643         1,
   8644         1,
   8645         1,
   8646         1,
   8647         1,
   8648         1,
   8649         1,
   8650         1,
   8651         1,
   8652         1,
   8653         1,
   8654         1,
   8655         1,
   8656         1,
   8657         1,
   8658         1,
   8659         1,
   8660         1,
   8661         1,
   8662         1,
   8663         1,
   8664         1,
   8665         1,
   8666         1,
   8667         1,
   8668         1,
   8669         1,
   8670         1,
   8671         1,
   8672         1,
   8673         1,
   8674         1,
   8675         1,
   8676         1,
   8677         1,
   8678         1,
   8679         1,
   8680         1,
   8681         1,
   8682         1,
   8683         1,
   8684         1,
   8685         1,
   8686         1,
   8687         1,
   8688         1,
   8689         1,
   8690         1,
   8691         1,
   8692         1,
   8693         1,
   8694         1,
   8695         1,
   8696         1,
   8697         1,
   8698         1,
   8699         1,
   8700         1,
   8701         1,
   8702         1,
   8703         1,
   8704         1,
   8705         1,
   8706         1,
   8707         1,
   8708         1,
   8709         1,
   8710         1,
   8711         1,
   8712         1,
   8713         1,
   8714         1,
   8715         1,
   8716         1,
   8717         1,
   8718         1,
   8719         1,
   8720         1,
   8721         1,
   8722         1,
   8723         1,
   8724         1,
   8725         1,
   8726         1,
   8727         1,
   8728         1,
   8729         1,
   8730         1,
   8731         1,
   8732         1,
   8733         1,
   8734         1,
   8735         1,
   8736         1,
   8737         1,
   8738         1,
   8739         1,
   8740         1,
   8741         1,
   8742         1,
   8743         1,
   8744         1,
   8745         1,
   8746         1,
   8747         1,
   8748         1,
   8749         1,
   8750         1,
   8751         1,
   8752         1,
   8753         1,
   8754         1,
   8755         1,
   8756         1,
   8757         1,
   8758         1,
   8759         1,
   8760         1,
   8761         1,
   8762         1,
   8763         1,
   8764         1,
   8765         1,
   8766         1,
   8767         1,
   8768         1,
   8769         1,
   8770         1,
   8771         1,
   8772         1,
   8773         1,
   8774         1,
   8775         1,
   8776         1,
   8777         1,
   8778         1,
   8779         1,
   8780         1,
   8781         1,
   8782         1,
   8783         1,
   8784         1,
   8785         1,
   8786         1,
   8787         1,
   8788         1,
   8789         1,
   8790         1,
   8791         1,
   8792         1,
   8793         1,
   8794         1,
   8795         1,
   8796         1,
   8797         1,
   8798         1,
   8799         1,
   8800         1,
   8801         1,
   8802         1,
   8803         1,
   8804         1,
   8805         1,
   8806         1,
   8807         1,
   8808         1,
   8809         1,
   8810         1,
   8811         1,
   8812         1,
   8813         1,
   8814         1,
   8815         1,
   8816         1,
   8817         1,
   8818         1,
   8819         1,
   8820         1,
   8821         1,
   8822         1,
   8823         1,
   8824         1,
   8825         1,
   8826         1,
   8827         1,
   8828         1,
   8829         1,
   8830         1,
   8831         1,
   8832         1,
   8833         1,
   8834         1,
   8835         1,
   8836         1,
   8837         1,
   8838         1,
   8839         1,
   8840         1,
   8841         1,
   8842         1,
   8843         1,
   8844         1,
   8845         1,
   8846         1,
   8847         1,
   8848         1,
   8849         1,
   8850         1,
   8851         1,
   8852         1,
   8853         1,
   8854         1,
   8855         1,
   8856         1,
   8857         1,
   8858         1,
   8859         1,
   8860         1,
   8861         1,
   8862         1,
   8863         1,
   8864         1,
   8865         1,
   8866         1,
   8867         1,
   8868         1,
   8869         1,
   8870         1,
   8871         1,
   8872         1,
   8873         1,
   8874         1,
   8875         1,
   8876         1,
   8877         1,
   8878         1,
   8879         1,
   8880         1,
   8881         1,
   8882         1,
   8883         1,
   8884         1,
   8885         1,
   8886         1,
   8887         1,
   8888         1,
   8889         1,
   8890         1,
   8891         1,
   8892         1,
   8893         1,
   8894         1,
   8895         1,
   8896         1,
   8897         1,
   8898         1,
   8899         1,
   8900         1,
   8901         1,
   8902         1,
   8903         1,
   8904         1,
   8905         1,
   8906         1,
   8907         1,
   8908         1,
   8909         1,
   8910         1,
   8911         1,
   8912         1,
   8913         1,
   8914         1,
   8915         1,
   8916         1,
   8917         1,
   8918         1,
   8919         1,
   8920         1,
   8921         1,
   8922         1,
   8923         1,
   8924         1,
   8925         1,
   8926         1,
   8927         1,
   8928         1,
   8929         1,
   8930         1,
   8931         1,
   8932         1,
   8933         1,
   8934         1,
   8935         1,
   8936         1,
   8937         1,
   8938         1,
   8939         1,
   8940         1,
   8941         1,
   8942         1,
   8943         1,
   8944         1,
   8945         1,
   8946         1,
   8947         1,
   8948         1,
   8949         1,
   8950         1,
   8951         1,
   8952         1,
   8953         1,
   8954         1,
   8955         1,
   8956         1,
   8957         1,
   8958         1,
   8959         1,
   8960         1,
   8961         1,
   8962         1,
   8963         1,
   8964         1,
   8965         1,
   8966         1,
   8967         1,
   8968         1,
   8969         1,
   8970         1,
   8971         1,
   8972         1,
   8973         1,
   8974         1,
   8975         1,
   8976         1,
   8977         1,
   8978         1,
   8979         1,
   8980         1,
   8981         1,
   8982         1,
   8983         1,
   8984         1,
   8985         1,
   8986         1,
   8987         1,
   8988         1,
   8989         1,
   8990         1,
   8991         1,
   8992         1,
   8993         1,
   8994         1,
   8995         1,
   8996         1,
   8997         1,
   8998         1,
   8999         1,
   9000         1,
   9001         1,
   9002         1,
   9003         1,
   9004         1,
   9005         1,
   9006         1,
   9007         1,
   9008         1,
   9009         1,
   9010         1,
   9011         1,
   9012         1,
   9013         1,
   9014         1,
   9015         1,
   9016         1,
   9017         1,
   9018         1,
   9019         1,
   9020         1,
   9021         1,
   9022         1,
   9023         1,
   9024         1,
   9025         1,
   9026         1,
   9027         1,
   9028         1,
   9029         1,
   9030         1,
   9031         1,
   9032         1,
   9033         1,
   9034         1,
   9035         1,
   9036         1,
   9037         1,
   9038         1,
   9039         1,
   9040         1,
   9041         1,
   9042         1,
   9043         1,
   9044         1,
   9045         1,
   9046         1,
   9047         1,
   9048         1,
   9049         1,
   9050         1,
   9051         1,
   9052         1,
   9053         1,
   9054         1,
   9055         1,
   9056         1,
   9057         1,
   9058         1,
   9059         1,
   9060         1,
   9061         1,
   9062         1,
   9063         1,
   9064         1,
   9065         1,
   9066         1,
   9067         1,
   9068         1,
   9069         1,
   9070         1,
   9071         1,
   9072         1,
   9073         1,
   9074         1,
   9075         1,
   9076         1,
   9077         1,
   9078         1,
   9079         1,
   9080         1,
   9081         1,
   9082         1,
   9083         1,
   9084         1,
   9085         1,
   9086         1,
   9087         1,
   9088         1,
   9089         1,
   9090         1,
   9091         1,
   9092         1,
   9093         1,
   9094         1,
   9095         1,
   9096         1,
   9097         1,
   9098         1,
   9099         1,
   9100         1,
   9101         1,
   9102         1,
   9103         1,
   9104         1,
   9105         1,
   9106         1,
   9107         1,
   9108         1,
   9109         1,
   9110         1,
   9111         1,
   9112         1,
   9113         1,
   9114         1,
   9115         1,
   9116         1,
   9117         1,
   9118         1,
   9119         1,
   9120         1,
   9121         1,
   9122         1,
   9123         1,
   9124         1,
   9125         1,
   9126         1,
   9127         1,
   9128         1,
   9129         1,
   9130         1,
   9131         1,
   9132         1,
   9133         1,
   9134         1,
   9135         1,
   9136         1,
   9137         1,
   9138         1,
   9139         1,
   9140         1,
   9141         1,
   9142         1,
   9143         1,
   9144         1,
   9145         1,
   9146         1,
   9147         1,
   9148         1,
   9149         1,
   9150         1,
   9151         1,
   9152         1,
   9153         1,
   9154         1,
   9155         1,
   9156         1,
   9157         1,
   9158         1,
   9159         1,
   9160         1,
   9161         1,
   9162         1,
   9163         1,
   9164         1,
   9165         1,
   9166         1,
   9167         1,
   9168         1,
   9169         1,
   9170         1,
   9171         1,
   9172         1,
   9173         1,
   9174         1,
   9175         1,
   9176         1,
   9177         1,
   9178         1,
   9179         1,
   9180         1,
   9181         1,
   9182         1,
   9183         1,
   9184         1,
   9185         1,
   9186         1,
   9187         1,
   9188         1,
   9189         1,
   9190         1,
   9191         1,
   9192         1,
   9193         1,
   9194         1,
   9195         1,
   9196         1,
   9197         1,
   9198         1,
   9199         1,
   9200         1,
   9201         1,
   9202         1,
   9203         1,
   9204         1,
   9205         1,
   9206         1,
   9207         1,
   9208         1,
   9209         1,
   9210         1,
   9211         1,
   9212         1,
   9213         1,
   9214         1,
   9215         1,
   9216         1,
   9217         1,
   9218         1,
   9219         1,
   9220         1,
   9221         1,
   9222         1,
   9223         1,
   9224         1,
   9225         1,
   9226         1,
   9227         1,
   9228         1,
   9229         1,
   9230         1,
   9231         1,
   9232         1,
   9233         1,
   9234         1,
   9235         1,
   9236         1,
   9237         1,
   9238         1,
   9239         1,
   9240         1,
   9241         1,
   9242         1,
   9243         1,
   9244         1,
   9245         1,
   9246         1,
   9247         1,
   9248         1,
   9249         1,
   9250         1,
   9251         1,
   9252         1,
   9253         1,
   9254         1,
   9255         1,
   9256         1,
   9257         1,
   9258         1,
   9259         1,
   9260         1,
   9261         1,
   9262         1,
   9263         1,
   9264         1,
   9265         1,
   9266         1,
   9267         1,
   9268         1,
   9269         1,
   9270         1,
   9271         1,
   9272         1,
   9273         1,
   9274         1,
   9275         1,
   9276         1,
   9277         1,
   9278         1,
   9279         1,
   9280         1,
   9281         1,
   9282         1,
   9283         1,
   9284         1,
   9285         1,
   9286         1,
   9287         1,
   9288         1,
   9289         1,
   9290         1,
   9291         1,
   9292         1,
   9293         1,
   9294         1,
   9295         1,
   9296         1,
   9297         1,
   9298         1,
   9299         1,
   9300         1,
   9301         1,
   9302         1,
   9303         1,
   9304         1,
   9305         1,
   9306         1,
   9307         1,
   9308         1,
   9309         1,
   9310         1,
   9311         1,
   9312         1,
   9313         1,
   9314         1,
   9315         1,
   9316         1,
   9317         1,
   9318         1,
   9319         1,
   9320         1,
   9321         1,
   9322         1,
   9323         1,
   9324         1,
   9325         1,
   9326         1,
   9327         1,
   9328         1,
   9329         1,
   9330         1,
   9331         1,
   9332         1,
   9333         1,
   9334         1,
   9335         1,
   9336         1,
   9337         1,
   9338         1,
   9339         1,
   9340         1,
   9341         1,
   9342         1,
   9343         1,
   9344         1,
   9345         1,
   9346         1,
   9347         1,
   9348         1,
   9349         1,
   9350         1,
   9351         1,
   9352         1,
   9353         1,
   9354         1,
   9355         1,
   9356     ];
   9357     let pub_key = MlDsaVerKey::<MlDsa44>::decode(&[1u8; 1312].into())
   9358         .to_public_key_der()
   9359         .unwrap();
   9360     let att_obj_len = att_obj.len();
   9361     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
   9362     let b64_adata = base64url_nopad::encode(&att_obj[att_obj_len - 1393..]);
   9363     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
   9364     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
   9365     // Base case is valid.
   9366     assert!(
   9367         serde_json::from_str::<Registration>(
   9368             serde_json::json!({
   9369                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9370                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9371                 "response": {
   9372                     "clientDataJSON": b64_cdata_json,
   9373                     "authenticatorData": b64_adata,
   9374                     "transports": [],
   9375                     "publicKey": b64_key,
   9376                     "publicKeyAlgorithm": -48i8,
   9377                     "attestationObject": b64_aobj,
   9378                 },
   9379                 "clientExtensionResults": {},
   9380                 "type": "public-key"
   9381             })
   9382             .to_string()
   9383             .as_str()
   9384         )
   9385         .is_ok_and(
   9386             |reg| reg.response.client_data_json == c_data_json.as_bytes()
   9387                 && reg.response.attestation_object_and_c_data_hash[..att_obj_len] == att_obj
   9388                 && reg.response.attestation_object_and_c_data_hash[att_obj_len..]
   9389                     == *Sha256::digest(c_data_json.as_bytes())
   9390                 && reg.response.transports.is_empty()
   9391                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
   9392                 && reg.client_extension_results.cred_props.is_none()
   9393                 && reg.client_extension_results.prf.is_none()
   9394         )
   9395     );
   9396     // `publicKeyAlgorithm` mismatch.
   9397     let mut err = Error::invalid_value(
   9398         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Eddsa).as_str()),
   9399         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa44).as_str()
   9400     )
   9401     .to_string().into_bytes();
   9402     assert_eq!(
   9403         serde_json::from_str::<Registration>(
   9404             serde_json::json!({
   9405                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9406                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9407                 "response": {
   9408                     "clientDataJSON": b64_cdata_json,
   9409                     "authenticatorData": b64_adata,
   9410                     "transports": [],
   9411                     "publicKey": b64_key,
   9412                     "publicKeyAlgorithm": -8i8,
   9413                     "attestationObject": b64_aobj,
   9414                 },
   9415                 "clientExtensionResults": {},
   9416                 "type": "public-key"
   9417             })
   9418             .to_string()
   9419             .as_str()
   9420         )
   9421         .unwrap_err()
   9422         .to_string()
   9423         .into_bytes()
   9424         .get(..err.len()),
   9425         Some(err.as_slice())
   9426     );
   9427     // Missing `publicKeyAlgorithm`.
   9428     err = Error::missing_field("publicKeyAlgorithm")
   9429         .to_string()
   9430         .into_bytes();
   9431     assert_eq!(
   9432         serde_json::from_str::<Registration>(
   9433             serde_json::json!({
   9434                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9435                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9436                 "response": {
   9437                     "clientDataJSON": b64_cdata_json,
   9438                     "authenticatorData": b64_adata,
   9439                     "transports": [],
   9440                     "publicKey": b64_key,
   9441                     "attestationObject": b64_aobj,
   9442                 },
   9443                 "clientExtensionResults": {},
   9444                 "type": "public-key"
   9445             })
   9446             .to_string()
   9447             .as_str()
   9448         )
   9449         .unwrap_err()
   9450         .to_string()
   9451         .into_bytes()
   9452         .get(..err.len()),
   9453         Some(err.as_slice())
   9454     );
   9455     // `null` `publicKeyAlgorithm`.
   9456     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
   9457         .to_string()
   9458         .into_bytes();
   9459     assert_eq!(
   9460         serde_json::from_str::<Registration>(
   9461             serde_json::json!({
   9462                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9463                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9464                 "response": {
   9465                     "clientDataJSON": b64_cdata_json,
   9466                     "authenticatorData": b64_adata,
   9467                     "transports": [],
   9468                     "publicKey": b64_key,
   9469                     "publicKeyAlgorithm": null,
   9470                     "attestationObject": b64_aobj,
   9471                 },
   9472                 "clientExtensionResults": {},
   9473                 "type": "public-key"
   9474             })
   9475             .to_string()
   9476             .as_str()
   9477         )
   9478         .unwrap_err()
   9479         .to_string()
   9480         .into_bytes()
   9481         .get(..err.len()),
   9482         Some(err.as_slice())
   9483     );
   9484     // `publicKey` mismatch.
   9485     let bad_pub_key = MlDsaVerKey::<MlDsa44>::decode(&[2; 1312].into());
   9486     err = Error::invalid_value(
   9487         Unexpected::Bytes([0; 32].as_slice()),
   9488         &format!(
   9489             "DER-encoded public key to match the public key within the attestation object: MlDsa44(MlDsa44PubKey({:?}))",
   9490             &[1u8; 1312]
   9491         )
   9492         .as_str(),
   9493     )
   9494     .to_string().into_bytes();
   9495     assert_eq!(serde_json::from_str::<Registration>(
   9496         serde_json::json!({
   9497             "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9498             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9499             "response": {
   9500                 "clientDataJSON": b64_cdata_json,
   9501                 "authenticatorData": b64_adata,
   9502                 "transports": [],
   9503                 "publicKey": base64url_nopad::encode(bad_pub_key.to_public_key_der().unwrap().as_bytes()),
   9504                 "publicKeyAlgorithm": -48i8,
   9505                 "attestationObject": b64_aobj,
   9506             },
   9507             "clientExtensionResults": {},
   9508             "type": "public-key"
   9509         })
   9510         .to_string()
   9511         .as_str()
   9512         )
   9513         .unwrap_err().to_string().into_bytes().get(..err.len()),
   9514         Some(err.as_slice())
   9515     );
   9516     // Missing `publicKey` is allowed when not using EdDSA, ES256, or RS256.
   9517     assert!(
   9518         serde_json::from_str::<Registration>(
   9519             serde_json::json!({
   9520                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9521                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9522                 "response": {
   9523                     "clientDataJSON": b64_cdata_json,
   9524                     "authenticatorData": b64_adata,
   9525                     "transports": [],
   9526                     "publicKeyAlgorithm": -48i8,
   9527                     "attestationObject": b64_aobj,
   9528                 },
   9529                 "clientExtensionResults": {},
   9530                 "type": "public-key"
   9531             })
   9532             .to_string()
   9533             .as_str()
   9534         )
   9535         .is_ok()
   9536     );
   9537     // `publicKeyAlgorithm` mismatch when `publicKey` does not exist.
   9538     err = Error::invalid_value(
   9539         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
   9540         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa44).as_str()
   9541     )
   9542     .to_string().into_bytes();
   9543     assert_eq!(
   9544         serde_json::from_str::<Registration>(
   9545             serde_json::json!({
   9546                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9547                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9548                 "response": {
   9549                     "clientDataJSON": b64_cdata_json,
   9550                     "authenticatorData": b64_adata,
   9551                     "transports": [],
   9552                     "publicKeyAlgorithm": -7i8,
   9553                     "attestationObject": b64_aobj,
   9554                 },
   9555                 "clientExtensionResults": {},
   9556                 "type": "public-key"
   9557             })
   9558             .to_string()
   9559             .as_str()
   9560         )
   9561         .unwrap_err()
   9562         .to_string()
   9563         .into_bytes()
   9564         .get(..err.len()),
   9565         Some(err.as_slice())
   9566     );
   9567     // `null` `publicKey` is allowed when not using EdDSA, ES256, or RS256.
   9568     assert!(
   9569         serde_json::from_str::<Registration>(
   9570             serde_json::json!({
   9571                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9572                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9573                 "response": {
   9574                     "clientDataJSON": b64_cdata_json,
   9575                     "authenticatorData": b64_adata,
   9576                     "transports": [],
   9577                     "publicKey": null,
   9578                     "publicKeyAlgorithm": -48i8,
   9579                     "attestationObject": b64_aobj,
   9580                 },
   9581                 "clientExtensionResults": {},
   9582                 "type": "public-key"
   9583             })
   9584             .to_string()
   9585             .as_str()
   9586         )
   9587         .is_ok()
   9588     );
   9589     // `publicKeyAlgorithm` mismatch when `publicKey` is null.
   9590     err = Error::invalid_value(
   9591         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
   9592         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Mldsa44).as_str()
   9593     )
   9594     .to_string().into_bytes();
   9595     assert_eq!(
   9596         serde_json::from_str::<Registration>(
   9597             serde_json::json!({
   9598                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9599                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9600                 "response": {
   9601                     "clientDataJSON": b64_cdata_json,
   9602                     "authenticatorData": b64_adata,
   9603                     "transports": [],
   9604                     "publicKey": null,
   9605                     "publicKeyAlgorithm": -7i8,
   9606                     "attestationObject": b64_aobj,
   9607                 },
   9608                 "clientExtensionResults": {},
   9609                 "type": "public-key"
   9610             })
   9611             .to_string()
   9612             .as_str()
   9613         )
   9614         .unwrap_err()
   9615         .to_string()
   9616         .into_bytes()
   9617         .get(..err.len()),
   9618         Some(err.as_slice())
   9619     );
   9620 }
   9621 #[expect(clippy::unwrap_used, reason = "OK in tests")]
   9622 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
   9623 #[expect(clippy::too_many_lines, reason = "a lot to test")]
   9624 #[test]
   9625 fn es256_registration_deserialize_data_mismatch() {
   9626     let c_data_json = serde_json::json!({}).to_string();
   9627     let mut att_obj: [u8; 178] = [
   9628         cbor::MAP_3,
   9629         cbor::TEXT_3,
   9630         b'f',
   9631         b'm',
   9632         b't',
   9633         cbor::TEXT_4,
   9634         b'n',
   9635         b'o',
   9636         b'n',
   9637         b'e',
   9638         cbor::TEXT_7,
   9639         b'a',
   9640         b't',
   9641         b't',
   9642         b'S',
   9643         b't',
   9644         b'm',
   9645         b't',
   9646         cbor::MAP_0,
   9647         cbor::TEXT_8,
   9648         b'a',
   9649         b'u',
   9650         b't',
   9651         b'h',
   9652         b'D',
   9653         b'a',
   9654         b't',
   9655         b'a',
   9656         cbor::BYTES_INFO_24,
   9657         148,
   9658         // `rpIdHash`.
   9659         0,
   9660         0,
   9661         0,
   9662         0,
   9663         0,
   9664         0,
   9665         0,
   9666         0,
   9667         0,
   9668         0,
   9669         0,
   9670         0,
   9671         0,
   9672         0,
   9673         0,
   9674         0,
   9675         0,
   9676         0,
   9677         0,
   9678         0,
   9679         0,
   9680         0,
   9681         0,
   9682         0,
   9683         0,
   9684         0,
   9685         0,
   9686         0,
   9687         0,
   9688         0,
   9689         0,
   9690         0,
   9691         // `flags`.
   9692         0b0100_0101,
   9693         // `signCount`.
   9694         0,
   9695         0,
   9696         0,
   9697         0,
   9698         // `aaguid`.
   9699         0,
   9700         0,
   9701         0,
   9702         0,
   9703         0,
   9704         0,
   9705         0,
   9706         0,
   9707         0,
   9708         0,
   9709         0,
   9710         0,
   9711         0,
   9712         0,
   9713         0,
   9714         0,
   9715         // `credentialIdLength`.
   9716         0,
   9717         16,
   9718         // `credentialId`.
   9719         0,
   9720         0,
   9721         0,
   9722         0,
   9723         0,
   9724         0,
   9725         0,
   9726         0,
   9727         0,
   9728         0,
   9729         0,
   9730         0,
   9731         0,
   9732         0,
   9733         0,
   9734         0,
   9735         // P-256 COSE key.
   9736         cbor::MAP_5,
   9737         KTY,
   9738         EC2,
   9739         ALG,
   9740         ES256,
   9741         // `crv`.
   9742         cbor::NEG_ONE,
   9743         // `P-256`.
   9744         cbor::ONE,
   9745         // `x`.
   9746         cbor::NEG_TWO,
   9747         cbor::BYTES_INFO_24,
   9748         32,
   9749         // x-coordinate. This will be overwritten later.
   9750         0,
   9751         0,
   9752         0,
   9753         0,
   9754         0,
   9755         0,
   9756         0,
   9757         0,
   9758         0,
   9759         0,
   9760         0,
   9761         0,
   9762         0,
   9763         0,
   9764         0,
   9765         0,
   9766         0,
   9767         0,
   9768         0,
   9769         0,
   9770         0,
   9771         0,
   9772         0,
   9773         0,
   9774         0,
   9775         0,
   9776         0,
   9777         0,
   9778         0,
   9779         0,
   9780         0,
   9781         0,
   9782         // `y`.
   9783         cbor::NEG_THREE,
   9784         cbor::BYTES_INFO_24,
   9785         32,
   9786         // y-coordinate. This will be overwritten later.
   9787         0,
   9788         0,
   9789         0,
   9790         0,
   9791         0,
   9792         0,
   9793         0,
   9794         0,
   9795         0,
   9796         0,
   9797         0,
   9798         0,
   9799         0,
   9800         0,
   9801         0,
   9802         0,
   9803         0,
   9804         0,
   9805         0,
   9806         0,
   9807         0,
   9808         0,
   9809         0,
   9810         0,
   9811         0,
   9812         0,
   9813         0,
   9814         0,
   9815         0,
   9816         0,
   9817         0,
   9818         0,
   9819     ];
   9820     let key = P256Key::from_bytes(
   9821         &[
   9822             137, 133, 36, 206, 163, 47, 255, 5, 76, 144, 163, 141, 40, 109, 108, 240, 246, 115,
   9823             178, 237, 169, 68, 6, 129, 92, 21, 238, 127, 55, 158, 207, 95,
   9824         ]
   9825         .into(),
   9826     )
   9827     .unwrap()
   9828     .public_key();
   9829     let enc_key = key.to_sec1_point(false);
   9830     let pub_key = key.to_public_key_der().unwrap();
   9831     let att_obj_len = att_obj.len();
   9832     let x_start = att_obj_len - 67;
   9833     let y_meta_start = x_start + 32;
   9834     let y_start = y_meta_start + 3;
   9835     att_obj[x_start..y_meta_start].copy_from_slice(enc_key.x().unwrap());
   9836     att_obj[y_start..].copy_from_slice(enc_key.y().unwrap());
   9837     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
   9838     let b64_adata = base64url_nopad::encode(&att_obj[att_obj.len() - 148..]);
   9839     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
   9840     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
   9841     // Base case is valid.
   9842     assert!(
   9843         serde_json::from_str::<Registration>(
   9844             serde_json::json!({
   9845                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9846                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9847                 "response": {
   9848                     "clientDataJSON": b64_cdata_json,
   9849                     "authenticatorData": b64_adata,
   9850                     "transports": [],
   9851                     "publicKey": b64_key,
   9852                     "publicKeyAlgorithm": -7i8,
   9853                     "attestationObject": b64_aobj,
   9854                 },
   9855                 "clientExtensionResults": {},
   9856                 "type": "public-key"
   9857             })
   9858             .to_string()
   9859             .as_str()
   9860         )
   9861         .is_ok_and(
   9862             |reg| reg.response.client_data_json == c_data_json.as_bytes()
   9863                 && reg.response.attestation_object_and_c_data_hash[..att_obj.len()] == att_obj
   9864                 && reg.response.attestation_object_and_c_data_hash[att_obj.len()..]
   9865                     == *Sha256::digest(c_data_json.as_bytes())
   9866                 && reg.response.transports.is_empty()
   9867                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
   9868                 && reg.client_extension_results.cred_props.is_none()
   9869                 && reg.client_extension_results.prf.is_none()
   9870         )
   9871     );
   9872     // `publicKeyAlgorithm` mismatch.
   9873     let mut err = Error::invalid_value(
   9874         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Eddsa).as_str()),
   9875         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Es256).as_str()
   9876     )
   9877     .to_string().into_bytes();
   9878     assert_eq!(
   9879         serde_json::from_str::<Registration>(
   9880             serde_json::json!({
   9881                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9882                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9883                 "response": {
   9884                     "clientDataJSON": b64_cdata_json,
   9885                     "authenticatorData": b64_adata,
   9886                     "transports": [],
   9887                     "publicKey": b64_key,
   9888                     "publicKeyAlgorithm": -8i8,
   9889                     "attestationObject": b64_aobj,
   9890                 },
   9891                 "clientExtensionResults": {},
   9892                 "type": "public-key"
   9893             })
   9894             .to_string()
   9895             .as_str()
   9896         )
   9897         .unwrap_err()
   9898         .to_string()
   9899         .into_bytes()
   9900         .get(..err.len()),
   9901         Some(err.as_slice())
   9902     );
   9903     // Missing `publicKeyAlgorithm`.
   9904     err = Error::missing_field("publicKeyAlgorithm")
   9905         .to_string()
   9906         .into_bytes();
   9907     assert_eq!(
   9908         serde_json::from_str::<Registration>(
   9909             serde_json::json!({
   9910                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9911                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9912                 "response": {
   9913                     "clientDataJSON": b64_cdata_json,
   9914                     "authenticatorData": b64_adata,
   9915                     "transports": [],
   9916                     "publicKey": b64_key,
   9917                     "attestationObject": b64_aobj,
   9918                 },
   9919                 "clientExtensionResults": {},
   9920                 "type": "public-key"
   9921             })
   9922             .to_string()
   9923             .as_str()
   9924         )
   9925         .unwrap_err()
   9926         .to_string()
   9927         .into_bytes()
   9928         .get(..err.len()),
   9929         Some(err.as_slice())
   9930     );
   9931     // `null` `publicKeyAlgorithm`.
   9932     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
   9933         .to_string()
   9934         .into_bytes();
   9935     assert_eq!(
   9936         serde_json::from_str::<Registration>(
   9937             serde_json::json!({
   9938                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9939                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9940                 "response": {
   9941                     "clientDataJSON": b64_cdata_json,
   9942                     "authenticatorData": b64_adata,
   9943                     "transports": [],
   9944                     "publicKey": b64_key,
   9945                     "publicKeyAlgorithm": null,
   9946                     "attestationObject": b64_aobj,
   9947                 },
   9948                 "clientExtensionResults": {},
   9949                 "type": "public-key"
   9950             })
   9951             .to_string()
   9952             .as_str()
   9953         )
   9954         .unwrap_err()
   9955         .to_string()
   9956         .into_bytes()
   9957         .get(..err.len()),
   9958         Some(err.as_slice())
   9959     );
   9960     // `publicKey` mismatch.
   9961     let bad_pub_key = P256PubKey::from_sec1_point(&P256Pt::from_affine_coordinates(
   9962         &[
   9963             66, 71, 188, 41, 125, 2, 226, 44, 148, 62, 63, 190, 172, 64, 33, 214, 6, 37, 148, 23,
   9964             240, 235, 203, 84, 112, 219, 232, 197, 54, 182, 17, 235,
   9965         ]
   9966         .into(),
   9967         &[
   9968             22, 172, 123, 13, 170, 242, 217, 248, 193, 209, 206, 163, 92, 4, 162, 168, 113, 63, 2,
   9969             117, 16, 223, 239, 196, 109, 179, 10, 130, 43, 213, 205, 92,
   9970         ]
   9971         .into(),
   9972         false,
   9973     ))
   9974     .unwrap();
   9975     err = Error::invalid_value(
   9976         Unexpected::Bytes([0; 32].as_slice()),
   9977         &format!(
   9978             "DER-encoded public key to match the public key within the attestation object: P256(UncompressedP256PubKey({:?}, {:?}))",
   9979             &att_obj[x_start..y_meta_start],
   9980             &att_obj[y_start..],
   9981         )
   9982         .as_str(),
   9983     )
   9984     .to_string().into_bytes();
   9985     assert_eq!(serde_json::from_str::<Registration>(
   9986         serde_json::json!({
   9987             "id": "AAAAAAAAAAAAAAAAAAAAAA",
   9988             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
   9989             "response": {
   9990                 "clientDataJSON": b64_cdata_json,
   9991                 "authenticatorData": b64_adata,
   9992                 "transports": [],
   9993                 "publicKey": base64url_nopad::encode(bad_pub_key.to_public_key_der().unwrap().as_bytes()),
   9994                 "publicKeyAlgorithm": -7i8,
   9995                 "attestationObject": b64_aobj,
   9996             },
   9997             "clientExtensionResults": {},
   9998             "type": "public-key"
   9999         })
  10000         .to_string()
  10001         .as_str()
  10002         )
  10003         .unwrap_err().to_string().into_bytes().get(..err.len()),
  10004         Some(err.as_slice())
  10005     );
  10006     // Missing `publicKey` when using EdDSA, ES256, or RS256.
  10007     err = Error::missing_field("publicKey").to_string().into_bytes();
  10008     assert_eq!(
  10009         serde_json::from_str::<Registration>(
  10010             serde_json::json!({
  10011                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10012                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10013                 "response": {
  10014                     "clientDataJSON": b64_cdata_json,
  10015                     "authenticatorData": b64_adata,
  10016                     "transports": [],
  10017                     "publicKeyAlgorithm": -7i8,
  10018                     "attestationObject": b64_aobj,
  10019                 },
  10020                 "clientExtensionResults": {},
  10021                 "type": "public-key"
  10022             })
  10023             .to_string()
  10024             .as_str()
  10025         )
  10026         .unwrap_err()
  10027         .to_string()
  10028         .into_bytes()
  10029         .get(..err.len()),
  10030         Some(err.as_slice())
  10031     );
  10032     // `null` `publicKey` when using EdDSA, ES256, or RS256.
  10033     err = Error::invalid_type(Unexpected::Other("null"), &"publicKey")
  10034         .to_string()
  10035         .into_bytes();
  10036     assert_eq!(
  10037         serde_json::from_str::<Registration>(
  10038             serde_json::json!({
  10039                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10040                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10041                 "response": {
  10042                     "clientDataJSON": b64_cdata_json,
  10043                     "authenticatorData": b64_adata,
  10044                     "transports": [],
  10045                     "publicKey": null,
  10046                     "publicKeyAlgorithm": -7i8,
  10047                     "attestationObject": b64_aobj,
  10048                 },
  10049                 "clientExtensionResults": {},
  10050                 "type": "public-key"
  10051             })
  10052             .to_string()
  10053             .as_str()
  10054         )
  10055         .unwrap_err()
  10056         .to_string()
  10057         .into_bytes()
  10058         .get(..err.len()),
  10059         Some(err.as_slice())
  10060     );
  10061 }
  10062 #[expect(
  10063     clippy::assertions_on_result_states,
  10064     clippy::unwrap_used,
  10065     reason = "OK in tests"
  10066 )]
  10067 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
  10068 #[expect(clippy::too_many_lines, reason = "a lot to test")]
  10069 #[test]
  10070 fn es384_registration_deserialize_data_mismatch() {
  10071     let c_data_json = serde_json::json!({}).to_string();
  10072     let mut att_obj: [u8; 211] = [
  10073         cbor::MAP_3,
  10074         cbor::TEXT_3,
  10075         b'f',
  10076         b'm',
  10077         b't',
  10078         cbor::TEXT_4,
  10079         b'n',
  10080         b'o',
  10081         b'n',
  10082         b'e',
  10083         cbor::TEXT_7,
  10084         b'a',
  10085         b't',
  10086         b't',
  10087         b'S',
  10088         b't',
  10089         b'm',
  10090         b't',
  10091         cbor::MAP_0,
  10092         cbor::TEXT_8,
  10093         b'a',
  10094         b'u',
  10095         b't',
  10096         b'h',
  10097         b'D',
  10098         b'a',
  10099         b't',
  10100         b'a',
  10101         cbor::BYTES_INFO_24,
  10102         181,
  10103         // `rpIdHash`.
  10104         0,
  10105         0,
  10106         0,
  10107         0,
  10108         0,
  10109         0,
  10110         0,
  10111         0,
  10112         0,
  10113         0,
  10114         0,
  10115         0,
  10116         0,
  10117         0,
  10118         0,
  10119         0,
  10120         0,
  10121         0,
  10122         0,
  10123         0,
  10124         0,
  10125         0,
  10126         0,
  10127         0,
  10128         0,
  10129         0,
  10130         0,
  10131         0,
  10132         0,
  10133         0,
  10134         0,
  10135         0,
  10136         // `flags`.
  10137         0b0100_0101,
  10138         // `signCount`.
  10139         0,
  10140         0,
  10141         0,
  10142         0,
  10143         // `aaguid`.
  10144         0,
  10145         0,
  10146         0,
  10147         0,
  10148         0,
  10149         0,
  10150         0,
  10151         0,
  10152         0,
  10153         0,
  10154         0,
  10155         0,
  10156         0,
  10157         0,
  10158         0,
  10159         0,
  10160         // `credentialIdLength`.
  10161         0,
  10162         16,
  10163         // `credentialId`.
  10164         0,
  10165         0,
  10166         0,
  10167         0,
  10168         0,
  10169         0,
  10170         0,
  10171         0,
  10172         0,
  10173         0,
  10174         0,
  10175         0,
  10176         0,
  10177         0,
  10178         0,
  10179         0,
  10180         // P-384 COSE key.
  10181         cbor::MAP_5,
  10182         KTY,
  10183         EC2,
  10184         ALG,
  10185         cbor::NEG_INFO_24,
  10186         ES384,
  10187         // `crv`.
  10188         cbor::NEG_ONE,
  10189         // `P-384`.
  10190         cbor::TWO,
  10191         // `x`.
  10192         cbor::NEG_TWO,
  10193         cbor::BYTES_INFO_24,
  10194         48,
  10195         // x-coordinate. This will be overwritten later.
  10196         0,
  10197         0,
  10198         0,
  10199         0,
  10200         0,
  10201         0,
  10202         0,
  10203         0,
  10204         0,
  10205         0,
  10206         0,
  10207         0,
  10208         0,
  10209         0,
  10210         0,
  10211         0,
  10212         0,
  10213         0,
  10214         0,
  10215         0,
  10216         0,
  10217         0,
  10218         0,
  10219         0,
  10220         0,
  10221         0,
  10222         0,
  10223         0,
  10224         0,
  10225         0,
  10226         0,
  10227         0,
  10228         0,
  10229         0,
  10230         0,
  10231         0,
  10232         0,
  10233         0,
  10234         0,
  10235         0,
  10236         0,
  10237         0,
  10238         0,
  10239         0,
  10240         0,
  10241         0,
  10242         0,
  10243         0,
  10244         // `y`.
  10245         cbor::NEG_THREE,
  10246         cbor::BYTES_INFO_24,
  10247         48,
  10248         // y-coordinate. This will be overwritten later.
  10249         0,
  10250         0,
  10251         0,
  10252         0,
  10253         0,
  10254         0,
  10255         0,
  10256         0,
  10257         0,
  10258         0,
  10259         0,
  10260         0,
  10261         0,
  10262         0,
  10263         0,
  10264         0,
  10265         0,
  10266         0,
  10267         0,
  10268         0,
  10269         0,
  10270         0,
  10271         0,
  10272         0,
  10273         0,
  10274         0,
  10275         0,
  10276         0,
  10277         0,
  10278         0,
  10279         0,
  10280         0,
  10281         0,
  10282         0,
  10283         0,
  10284         0,
  10285         0,
  10286         0,
  10287         0,
  10288         0,
  10289         0,
  10290         0,
  10291         0,
  10292         0,
  10293         0,
  10294         0,
  10295         0,
  10296         0,
  10297     ];
  10298     let key = P384Key::from_bytes(
  10299         &[
  10300             158, 99, 156, 49, 190, 211, 85, 167, 28, 2, 80, 57, 31, 22, 17, 38, 85, 78, 232, 42,
  10301             45, 199, 154, 243, 136, 251, 84, 34, 5, 120, 208, 91, 61, 248, 64, 144, 87, 1, 32, 86,
  10302             220, 68, 182, 11, 105, 223, 75, 70,
  10303         ]
  10304         .into(),
  10305     )
  10306     .unwrap()
  10307     .public_key();
  10308     let enc_key = key.to_sec1_point(false);
  10309     let pub_key = key.to_public_key_der().unwrap();
  10310     let att_obj_len = att_obj.len();
  10311     let x_start = att_obj_len - 99;
  10312     let y_meta_start = x_start + 48;
  10313     let y_start = y_meta_start + 3;
  10314     att_obj[x_start..y_meta_start].copy_from_slice(enc_key.x().unwrap());
  10315     att_obj[y_start..].copy_from_slice(enc_key.y().unwrap());
  10316     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
  10317     let b64_adata = base64url_nopad::encode(&att_obj[att_obj_len - 181..]);
  10318     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
  10319     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
  10320     // Base case is valid.
  10321     assert!(
  10322         serde_json::from_str::<Registration>(
  10323             serde_json::json!({
  10324                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10325                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10326                 "response": {
  10327                     "clientDataJSON": b64_cdata_json,
  10328                     "authenticatorData": b64_adata,
  10329                     "transports": [],
  10330                     "publicKey": b64_key,
  10331                     "publicKeyAlgorithm": -35i8,
  10332                     "attestationObject": b64_aobj,
  10333                 },
  10334                 "clientExtensionResults": {},
  10335                 "type": "public-key"
  10336             })
  10337             .to_string()
  10338             .as_str()
  10339         )
  10340         .is_ok_and(
  10341             |reg| reg.response.client_data_json == c_data_json.as_bytes()
  10342                 && reg.response.attestation_object_and_c_data_hash[..att_obj.len()] == att_obj
  10343                 && reg.response.attestation_object_and_c_data_hash[att_obj.len()..]
  10344                     == *Sha256::digest(c_data_json.as_bytes())
  10345                 && reg.response.transports.is_empty()
  10346                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
  10347                 && reg.client_extension_results.cred_props.is_none()
  10348                 && reg.client_extension_results.prf.is_none()
  10349         )
  10350     );
  10351     // `publicKeyAlgorithm` mismatch.
  10352     let mut err = Error::invalid_value(
  10353         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
  10354         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Es384).as_str()
  10355     )
  10356     .to_string().into_bytes();
  10357     assert_eq!(
  10358         serde_json::from_str::<Registration>(
  10359             serde_json::json!({
  10360                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10361                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10362                 "response": {
  10363                     "clientDataJSON": b64_cdata_json,
  10364                     "authenticatorData": b64_adata,
  10365                     "transports": [],
  10366                     "publicKey": b64_key,
  10367                     "publicKeyAlgorithm": -7i8,
  10368                     "attestationObject": b64_aobj,
  10369                 },
  10370                 "clientExtensionResults": {},
  10371                 "type": "public-key"
  10372             })
  10373             .to_string()
  10374             .as_str()
  10375         )
  10376         .unwrap_err()
  10377         .to_string()
  10378         .into_bytes()
  10379         .get(..err.len()),
  10380         Some(err.as_slice())
  10381     );
  10382     // Missing `publicKeyAlgorithm`.
  10383     err = Error::missing_field("publicKeyAlgorithm")
  10384         .to_string()
  10385         .into_bytes();
  10386     assert_eq!(
  10387         serde_json::from_str::<Registration>(
  10388             serde_json::json!({
  10389                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10390                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10391                 "response": {
  10392                     "clientDataJSON": b64_cdata_json,
  10393                     "authenticatorData": b64_adata,
  10394                     "transports": [],
  10395                     "publicKey": b64_key,
  10396                     "attestationObject": b64_aobj,
  10397                 },
  10398                 "clientExtensionResults": {},
  10399                 "type": "public-key"
  10400             })
  10401             .to_string()
  10402             .as_str()
  10403         )
  10404         .unwrap_err()
  10405         .to_string()
  10406         .into_bytes()
  10407         .get(..err.len()),
  10408         Some(err.as_slice())
  10409     );
  10410     // `null` `publicKeyAlgorithm`.
  10411     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
  10412         .to_string()
  10413         .into_bytes();
  10414     assert_eq!(
  10415         serde_json::from_str::<Registration>(
  10416             serde_json::json!({
  10417                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10418                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10419                 "response": {
  10420                     "clientDataJSON": b64_cdata_json,
  10421                     "authenticatorData": b64_adata,
  10422                     "transports": [],
  10423                     "publicKey": b64_key,
  10424                     "publicKeyAlgorithm": null,
  10425                     "attestationObject": b64_aobj,
  10426                 },
  10427                 "clientExtensionResults": {},
  10428                 "type": "public-key"
  10429             })
  10430             .to_string()
  10431             .as_str()
  10432         )
  10433         .unwrap_err()
  10434         .to_string()
  10435         .into_bytes()
  10436         .get(..err.len()),
  10437         Some(err.as_slice())
  10438     );
  10439     // `publicKey` mismatch.
  10440     let bad_pub_key = P384PubKey::from_sec1_point(&P384Pt::from_affine_coordinates(
  10441         &[
  10442             192, 10, 27, 46, 66, 67, 80, 98, 33, 230, 156, 95, 1, 135, 150, 110, 64, 243, 22, 118,
  10443             5, 255, 107, 44, 234, 111, 217, 105, 125, 114, 39, 7, 126, 2, 191, 111, 48, 93, 234,
  10444             175, 18, 172, 59, 28, 97, 106, 178, 152,
  10445         ]
  10446         .into(),
  10447         &[
  10448             57, 36, 196, 12, 109, 129, 253, 115, 88, 154, 6, 43, 195, 85, 169, 5, 230, 51, 28, 205,
  10449             142, 28, 150, 35, 24, 222, 170, 253, 14, 248, 84, 151, 109, 191, 152, 111, 222, 70,
  10450             134, 247, 109, 171, 211, 33, 214, 217, 200, 111,
  10451         ]
  10452         .into(),
  10453         false,
  10454     ))
  10455     .unwrap();
  10456     err = Error::invalid_value(
  10457         Unexpected::Bytes([0; 32].as_slice()),
  10458         &format!(
  10459             "DER-encoded public key to match the public key within the attestation object: P384(UncompressedP384PubKey({:?}, {:?}))",
  10460             &att_obj[x_start..y_meta_start],
  10461             &att_obj[y_start..],
  10462         )
  10463         .as_str(),
  10464     )
  10465     .to_string().into_bytes();
  10466     assert_eq!(serde_json::from_str::<Registration>(
  10467         serde_json::json!({
  10468             "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10469             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10470             "response": {
  10471                 "clientDataJSON": b64_cdata_json,
  10472                 "authenticatorData": b64_adata,
  10473                 "transports": [],
  10474                 "publicKey": base64url_nopad::encode(bad_pub_key.to_public_key_der().unwrap().as_bytes()),
  10475                 "publicKeyAlgorithm": -35i8,
  10476                 "attestationObject": b64_aobj,
  10477             },
  10478             "clientExtensionResults": {},
  10479             "type": "public-key"
  10480         })
  10481         .to_string()
  10482         .as_str()
  10483         )
  10484         .unwrap_err().to_string().into_bytes().get(..err.len()),
  10485         Some(err.as_slice())
  10486     );
  10487     // Missing `publicKey` is allowed when not using EdDSA, ES256, or RS256.
  10488     assert!(
  10489         serde_json::from_str::<Registration>(
  10490             serde_json::json!({
  10491                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10492                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10493                 "response": {
  10494                     "clientDataJSON": b64_cdata_json,
  10495                     "authenticatorData": b64_adata,
  10496                     "transports": [],
  10497                     "publicKeyAlgorithm": -35i8,
  10498                     "attestationObject": b64_aobj,
  10499                 },
  10500                 "clientExtensionResults": {},
  10501                 "type": "public-key"
  10502             })
  10503             .to_string()
  10504             .as_str()
  10505         )
  10506         .is_ok()
  10507     );
  10508     // `publicKeyAlgorithm` mismatch when `publicKey` does not exist.
  10509     err = Error::invalid_value(
  10510         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
  10511         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Es384).as_str()
  10512     )
  10513     .to_string().into_bytes();
  10514     assert_eq!(
  10515         serde_json::from_str::<Registration>(
  10516             serde_json::json!({
  10517                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10518                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10519                 "response": {
  10520                     "clientDataJSON": b64_cdata_json,
  10521                     "authenticatorData": b64_adata,
  10522                     "transports": [],
  10523                     "publicKeyAlgorithm": -7i8,
  10524                     "attestationObject": b64_aobj,
  10525                 },
  10526                 "clientExtensionResults": {},
  10527                 "type": "public-key"
  10528             })
  10529             .to_string()
  10530             .as_str()
  10531         )
  10532         .unwrap_err()
  10533         .to_string()
  10534         .into_bytes()
  10535         .get(..err.len()),
  10536         Some(err.as_slice())
  10537     );
  10538     // `null` `publicKey` is allowed when not using EdDSA, ES256, or RS256.
  10539     assert!(
  10540         serde_json::from_str::<Registration>(
  10541             serde_json::json!({
  10542                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10543                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10544                 "response": {
  10545                     "clientDataJSON": b64_cdata_json,
  10546                     "authenticatorData": b64_adata,
  10547                     "transports": [],
  10548                     "publicKey": null,
  10549                     "publicKeyAlgorithm": -35i8,
  10550                     "attestationObject": b64_aobj,
  10551                 },
  10552                 "clientExtensionResults": {},
  10553                 "type": "public-key"
  10554             })
  10555             .to_string()
  10556             .as_str()
  10557         )
  10558         .is_ok()
  10559     );
  10560     // `publicKeyAlgorithm` mismatch when `publicKey` is null.
  10561     err = Error::invalid_value(
  10562         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Es256).as_str()),
  10563         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Es384).as_str()
  10564     )
  10565     .to_string().into_bytes();
  10566     assert_eq!(
  10567         serde_json::from_str::<Registration>(
  10568             serde_json::json!({
  10569                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  10570                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  10571                 "response": {
  10572                     "clientDataJSON": b64_cdata_json,
  10573                     "authenticatorData": b64_adata,
  10574                     "transports": [],
  10575                     "publicKey": null,
  10576                     "publicKeyAlgorithm": -7i8,
  10577                     "attestationObject": b64_aobj,
  10578                 },
  10579                 "clientExtensionResults": {},
  10580                 "type": "public-key"
  10581             })
  10582             .to_string()
  10583             .as_str()
  10584         )
  10585         .unwrap_err()
  10586         .to_string()
  10587         .into_bytes()
  10588         .get(..err.len()),
  10589         Some(err.as_slice())
  10590     );
  10591 }
  10592 #[expect(clippy::unwrap_used, reason = "OK in tests")]
  10593 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")]
  10594 #[expect(clippy::too_many_lines, reason = "a lot to test")]
  10595 #[test]
  10596 fn rs256_registration_deserialize_data_mismatch() {
  10597     let c_data_json = serde_json::json!({}).to_string();
  10598     let mut att_obj: [u8; 374] = [
  10599         cbor::MAP_3,
  10600         cbor::TEXT_3,
  10601         b'f',
  10602         b'm',
  10603         b't',
  10604         cbor::TEXT_4,
  10605         b'n',
  10606         b'o',
  10607         b'n',
  10608         b'e',
  10609         cbor::TEXT_7,
  10610         b'a',
  10611         b't',
  10612         b't',
  10613         b'S',
  10614         b't',
  10615         b'm',
  10616         b't',
  10617         cbor::MAP_0,
  10618         cbor::TEXT_8,
  10619         b'a',
  10620         b'u',
  10621         b't',
  10622         b'h',
  10623         b'D',
  10624         b'a',
  10625         b't',
  10626         b'a',
  10627         cbor::BYTES_INFO_25,
  10628         1,
  10629         87,
  10630         // `rpIdHash`.
  10631         0,
  10632         0,
  10633         0,
  10634         0,
  10635         0,
  10636         0,
  10637         0,
  10638         0,
  10639         0,
  10640         0,
  10641         0,
  10642         0,
  10643         0,
  10644         0,
  10645         0,
  10646         0,
  10647         0,
  10648         0,
  10649         0,
  10650         0,
  10651         0,
  10652         0,
  10653         0,
  10654         0,
  10655         0,
  10656         0,
  10657         0,
  10658         0,
  10659         0,
  10660         0,
  10661         0,
  10662         0,
  10663         // `flags`.
  10664         0b0100_0101,
  10665         // `signCount`.
  10666         0,
  10667         0,
  10668         0,
  10669         0,
  10670         // `aaguid`.
  10671         0,
  10672         0,
  10673         0,
  10674         0,
  10675         0,
  10676         0,
  10677         0,
  10678         0,
  10679         0,
  10680         0,
  10681         0,
  10682         0,
  10683         0,
  10684         0,
  10685         0,
  10686         0,
  10687         // `credentialIdLength`.
  10688         0,
  10689         16,
  10690         // `credentialId`.
  10691         0,
  10692         0,
  10693         0,
  10694         0,
  10695         0,
  10696         0,
  10697         0,
  10698         0,
  10699         0,
  10700         0,
  10701         0,
  10702         0,
  10703         0,
  10704         0,
  10705         0,
  10706         0,
  10707         // RSA COSE key.
  10708         cbor::MAP_4,
  10709         KTY,
  10710         RSA,
  10711         ALG,
  10712         cbor::NEG_INFO_25,
  10713         // RS256.
  10714         1,
  10715         0,
  10716         // `n`.
  10717         cbor::NEG_ONE,
  10718         cbor::BYTES_INFO_25,
  10719         1,
  10720         0,
  10721         // n. This will be overwritten later.
  10722         0,
  10723         0,
  10724         0,
  10725         0,
  10726         0,
  10727         0,
  10728         0,
  10729         0,
  10730         0,
  10731         0,
  10732         0,
  10733         0,
  10734         0,
  10735         0,
  10736         0,
  10737         0,
  10738         0,
  10739         0,
  10740         0,
  10741         0,
  10742         0,
  10743         0,
  10744         0,
  10745         0,
  10746         0,
  10747         0,
  10748         0,
  10749         0,
  10750         0,
  10751         0,
  10752         0,
  10753         0,
  10754         0,
  10755         0,
  10756         0,
  10757         0,
  10758         0,
  10759         0,
  10760         0,
  10761         0,
  10762         0,
  10763         0,
  10764         0,
  10765         0,
  10766         0,
  10767         0,
  10768         0,
  10769         0,
  10770         0,
  10771         0,
  10772         0,
  10773         0,
  10774         0,
  10775         0,
  10776         0,
  10777         0,
  10778         0,
  10779         0,
  10780         0,
  10781         0,
  10782         0,
  10783         0,
  10784         0,
  10785         0,
  10786         0,
  10787         0,
  10788         0,
  10789         0,
  10790         0,
  10791         0,
  10792         0,
  10793         0,
  10794         0,
  10795         0,
  10796         0,
  10797         0,
  10798         0,
  10799         0,
  10800         0,
  10801         0,
  10802         0,
  10803         0,
  10804         0,
  10805         0,
  10806         0,
  10807         0,
  10808         0,
  10809         0,
  10810         0,
  10811         0,
  10812         0,
  10813         0,
  10814         0,
  10815         0,
  10816         0,
  10817         0,
  10818         0,
  10819         0,
  10820         0,
  10821         0,
  10822         0,
  10823         0,
  10824         0,
  10825         0,
  10826         0,
  10827         0,
  10828         0,
  10829         0,
  10830         0,
  10831         0,
  10832         0,
  10833         0,
  10834         0,
  10835         0,
  10836         0,
  10837         0,
  10838         0,
  10839         0,
  10840         0,
  10841         0,
  10842         0,
  10843         0,
  10844         0,
  10845         0,
  10846         0,
  10847         0,
  10848         0,
  10849         0,
  10850         0,
  10851         0,
  10852         0,
  10853         0,
  10854         0,
  10855         0,
  10856         0,
  10857         0,
  10858         0,
  10859         0,
  10860         0,
  10861         0,
  10862         0,
  10863         0,
  10864         0,
  10865         0,
  10866         0,
  10867         0,
  10868         0,
  10869         0,
  10870         0,
  10871         0,
  10872         0,
  10873         0,
  10874         0,
  10875         0,
  10876         0,
  10877         0,
  10878         0,
  10879         0,
  10880         0,
  10881         0,
  10882         0,
  10883         0,
  10884         0,
  10885         0,
  10886         0,
  10887         0,
  10888         0,
  10889         0,
  10890         0,
  10891         0,
  10892         0,
  10893         0,
  10894         0,
  10895         0,
  10896         0,
  10897         0,
  10898         0,
  10899         0,
  10900         0,
  10901         0,
  10902         0,
  10903         0,
  10904         0,
  10905         0,
  10906         0,
  10907         0,
  10908         0,
  10909         0,
  10910         0,
  10911         0,
  10912         0,
  10913         0,
  10914         0,
  10915         0,
  10916         0,
  10917         0,
  10918         0,
  10919         0,
  10920         0,
  10921         0,
  10922         0,
  10923         0,
  10924         0,
  10925         0,
  10926         0,
  10927         0,
  10928         0,
  10929         0,
  10930         0,
  10931         0,
  10932         0,
  10933         0,
  10934         0,
  10935         0,
  10936         0,
  10937         0,
  10938         0,
  10939         0,
  10940         0,
  10941         0,
  10942         0,
  10943         0,
  10944         0,
  10945         0,
  10946         0,
  10947         0,
  10948         0,
  10949         0,
  10950         0,
  10951         0,
  10952         0,
  10953         0,
  10954         0,
  10955         0,
  10956         0,
  10957         0,
  10958         0,
  10959         0,
  10960         0,
  10961         0,
  10962         0,
  10963         0,
  10964         0,
  10965         0,
  10966         0,
  10967         0,
  10968         0,
  10969         0,
  10970         0,
  10971         0,
  10972         0,
  10973         0,
  10974         0,
  10975         0,
  10976         0,
  10977         0,
  10978         // `e`.
  10979         cbor::NEG_TWO,
  10980         cbor::BYTES | 3,
  10981         // e.
  10982         1,
  10983         0,
  10984         1,
  10985     ];
  10986     let n = [
  10987         111, 183, 124, 133, 38, 167, 70, 148, 44, 50, 30, 60, 121, 14, 38, 37, 96, 114, 107, 195,
  10988         248, 64, 79, 36, 237, 140, 43, 27, 94, 74, 102, 152, 135, 102, 184, 150, 186, 206, 185, 19,
  10989         165, 209, 48, 98, 98, 9, 3, 205, 208, 82, 250, 105, 132, 201, 73, 62, 60, 165, 100, 128,
  10990         153, 9, 41, 118, 66, 95, 236, 214, 73, 135, 197, 68, 184, 10, 27, 116, 204, 145, 50, 174,
  10991         58, 42, 183, 181, 119, 232, 126, 252, 217, 96, 162, 190, 103, 122, 64, 87, 145, 45, 32,
  10992         207, 17, 239, 223, 3, 35, 14, 112, 119, 124, 141, 123, 208, 239, 105, 81, 217, 151, 162,
  10993         190, 17, 88, 182, 176, 158, 81, 200, 42, 166, 133, 48, 23, 236, 55, 117, 248, 233, 151,
  10994         203, 122, 155, 231, 46, 177, 20, 20, 151, 64, 222, 239, 226, 7, 21, 254, 81, 202, 64, 232,
  10995         161, 235, 22, 51, 246, 207, 213, 0, 229, 138, 46, 222, 205, 157, 108, 139, 253, 230, 80,
  10996         50, 2, 122, 212, 163, 100, 180, 114, 12, 113, 52, 56, 99, 188, 42, 198, 212, 23, 182, 222,
  10997         56, 221, 200, 79, 96, 239, 221, 135, 10, 17, 106, 183, 56, 104, 68, 94, 198, 196, 35, 200,
  10998         83, 204, 26, 185, 204, 212, 31, 183, 19, 111, 233, 13, 72, 93, 53, 65, 111, 59, 242, 122,
  10999         160, 244, 162, 126, 38, 235, 156, 47, 88, 39, 132, 153, 79, 0, 133, 78, 7, 218, 165, 241,
  11000     ];
  11001     let e = 0x0001_0001u32;
  11002     let d = [
  11003         145, 79, 21, 97, 233, 3, 192, 194, 177, 68, 181, 80, 120, 197, 23, 44, 185, 74, 144, 0,
  11004         132, 149, 139, 11, 16, 224, 4, 112, 236, 94, 238, 97, 121, 124, 213, 145, 24, 253, 168, 35,
  11005         190, 205, 132, 115, 33, 201, 38, 253, 246, 180, 66, 155, 165, 46, 3, 254, 68, 108, 154,
  11006         247, 246, 45, 187, 0, 204, 96, 185, 157, 249, 174, 158, 38, 62, 244, 183, 76, 102, 6, 219,
  11007         92, 212, 138, 59, 147, 163, 219, 111, 39, 105, 21, 236, 196, 38, 255, 114, 247, 82, 104,
  11008         113, 204, 29, 152, 209, 219, 48, 239, 74, 129, 19, 247, 33, 239, 119, 166, 216, 152, 94,
  11009         138, 238, 164, 242, 129, 50, 150, 57, 20, 53, 224, 56, 241, 138, 97, 111, 215, 107, 212,
  11010         195, 146, 108, 143, 0, 229, 181, 171, 73, 152, 105, 146, 25, 243, 242, 140, 252, 248, 162,
  11011         247, 63, 168, 180, 20, 153, 120, 10, 248, 211, 1, 71, 127, 212, 249, 237, 203, 202, 48, 26,
  11012         216, 226, 228, 186, 13, 204, 70, 255, 240, 89, 255, 59, 83, 31, 253, 55, 43, 158, 90, 248,
  11013         83, 32, 159, 105, 57, 134, 34, 96, 18, 255, 245, 153, 162, 60, 91, 99, 220, 51, 44, 85,
  11014         114, 67, 125, 202, 65, 217, 245, 40, 8, 81, 165, 142, 24, 245, 127, 122, 247, 152, 212, 75,
  11015         45, 59, 90, 184, 234, 31, 147, 36, 8, 212, 45, 50, 23, 3, 25, 253, 87, 227, 79, 119, 161,
  11016     ];
  11017     let p = BoxedUint::from_le_slice_vartime(
  11018         [
  11019             215, 166, 5, 21, 11, 179, 41, 77, 198, 92, 165, 48, 77, 162, 42, 41, 206, 141, 60, 69,
  11020             47, 164, 19, 92, 46, 72, 100, 238, 100, 53, 214, 197, 163, 185, 6, 140, 229, 250, 195,
  11021             77, 8, 12, 5, 236, 178, 173, 86, 201, 43, 213, 165, 51, 108, 101, 161, 99, 76, 240, 14,
  11022             234, 76, 197, 137, 53, 198, 168, 135, 205, 212, 198, 120, 29, 16, 82, 98, 233, 236,
  11023             177, 12, 171, 141, 100, 107, 146, 33, 176, 125, 202, 172, 79, 147, 179, 30, 62, 247,
  11024             206, 169, 19, 168, 114, 26, 73, 108, 178, 105, 84, 89, 191, 168, 253, 228, 214, 54, 16,
  11025             212, 199, 111, 72, 3, 41, 247, 227, 165, 244, 32, 188, 24, 247,
  11026         ]
  11027         .as_slice(),
  11028     );
  11029     let p_2 = BoxedUint::from_le_slice_vartime(
  11030         [
  11031             41, 25, 198, 240, 134, 206, 121, 57, 11, 5, 134, 192, 212, 77, 229, 197, 14, 78, 85,
  11032             212, 190, 114, 179, 188, 21, 171, 174, 12, 104, 74, 15, 164, 136, 173, 62, 177, 141,
  11033             213, 93, 102, 147, 83, 59, 124, 146, 59, 175, 213, 55, 27, 25, 248, 154, 29, 39, 85,
  11034             50, 235, 134, 60, 203, 106, 186, 195, 190, 185, 71, 169, 142, 236, 92, 11, 250, 187,
  11035             198, 8, 201, 184, 120, 178, 227, 87, 63, 243, 89, 227, 234, 184, 28, 252, 112, 211,
  11036             193, 69, 23, 92, 5, 72, 93, 53, 69, 159, 73, 160, 105, 244, 249, 94, 214, 173, 9, 236,
  11037             4, 255, 129, 11, 224, 140, 252, 168, 57, 143, 176, 241, 60, 219, 90, 250,
  11038         ]
  11039         .as_slice(),
  11040     );
  11041     let key = RsaPrivateKey::from_components(
  11042         BoxedUint::from_le_slice_vartime(n.as_slice()),
  11043         e.into(),
  11044         BoxedUint::from_le_slice_vartime(d.as_slice()),
  11045         vec![p, p_2],
  11046     )
  11047     .unwrap()
  11048     .to_public_key();
  11049     let pub_key = key.to_public_key_der().unwrap();
  11050     let att_obj_len = att_obj.len();
  11051     let n_start_idx = att_obj_len - 261;
  11052     let e_meta_start_idx = n_start_idx + 256;
  11053     // Correct and won't `panic`.
  11054     att_obj[n_start_idx..e_meta_start_idx]
  11055         .copy_from_slice(key.n().to_be_bytes_trimmed_vartime().as_ref());
  11056     let b64_cdata_json = base64url_nopad::encode(c_data_json.as_bytes());
  11057     // Won't `panic`.
  11058     let b64_adata = base64url_nopad::encode(&att_obj[31..]);
  11059     let b64_key = base64url_nopad::encode(pub_key.as_bytes());
  11060     let b64_aobj = base64url_nopad::encode(att_obj.as_slice());
  11061     // Base case is valid.
  11062     assert!(
  11063         serde_json::from_str::<Registration>(
  11064             serde_json::json!({
  11065                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11066                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11067                 "response": {
  11068                     "clientDataJSON": b64_cdata_json,
  11069                     "authenticatorData": b64_adata,
  11070                     "transports": [],
  11071                     "publicKey": b64_key,
  11072                     "publicKeyAlgorithm": -257i16,
  11073                     "attestationObject": b64_aobj,
  11074                 },
  11075                 "clientExtensionResults": {},
  11076                 "type": "public-key"
  11077             })
  11078             .to_string()
  11079             .as_str()
  11080         )
  11081         .is_ok_and(
  11082             |reg| reg.response.client_data_json == c_data_json.as_bytes()
  11083                 && reg.response.attestation_object_and_c_data_hash[..att_obj_len] == att_obj
  11084                 && reg.response.attestation_object_and_c_data_hash[att_obj_len..]
  11085                     == *Sha256::digest(c_data_json.as_bytes())
  11086                 && reg.response.transports.is_empty()
  11087                 && matches!(reg.authenticator_attachment, AuthenticatorAttachment::None)
  11088                 && reg.client_extension_results.cred_props.is_none()
  11089                 && reg.client_extension_results.prf.is_none()
  11090         )
  11091     );
  11092     // `publicKeyAlgorithm` mismatch.
  11093     let mut err = Error::invalid_value(
  11094         Unexpected::Other(format!("{:?}", CoseAlgorithmIdentifier::Eddsa).as_str()),
  11095         &format!("public key algorithm to match the algorithm associated with the public key within the attestation object: {:?}", CoseAlgorithmIdentifier::Rs256).as_str()
  11096     )
  11097     .to_string().into_bytes();
  11098     assert_eq!(
  11099         serde_json::from_str::<Registration>(
  11100             serde_json::json!({
  11101                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11102                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11103                 "response": {
  11104                     "clientDataJSON": b64_cdata_json,
  11105                     "authenticatorData": b64_adata,
  11106                     "transports": [],
  11107                     "publicKey": b64_key,
  11108                     "publicKeyAlgorithm": -8i8,
  11109                     "attestationObject": b64_aobj,
  11110                 },
  11111                 "clientExtensionResults": {},
  11112                 "type": "public-key"
  11113             })
  11114             .to_string()
  11115             .as_str()
  11116         )
  11117         .unwrap_err()
  11118         .to_string()
  11119         .into_bytes()
  11120         .get(..err.len()),
  11121         Some(err.as_slice())
  11122     );
  11123     // Missing `publicKeyAlgorithm`.
  11124     err = Error::missing_field("publicKeyAlgorithm")
  11125         .to_string()
  11126         .into_bytes();
  11127     assert_eq!(
  11128         serde_json::from_str::<Registration>(
  11129             serde_json::json!({
  11130                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11131                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11132                 "response": {
  11133                     "clientDataJSON": b64_cdata_json,
  11134                     "authenticatorData": b64_adata,
  11135                     "transports": [],
  11136                     "publicKey": b64_key,
  11137                     "attestationObject": b64_aobj,
  11138                 },
  11139                 "clientExtensionResults": {},
  11140                 "type": "public-key"
  11141             })
  11142             .to_string()
  11143             .as_str()
  11144         )
  11145         .unwrap_err()
  11146         .to_string()
  11147         .into_bytes()
  11148         .get(..err.len()),
  11149         Some(err.as_slice())
  11150     );
  11151     // `null` `publicKeyAlgorithm`.
  11152     err = Error::invalid_type(Unexpected::Other("null"), &"publicKeyAlgorithm")
  11153         .to_string()
  11154         .into_bytes();
  11155     assert_eq!(
  11156         serde_json::from_str::<Registration>(
  11157             serde_json::json!({
  11158                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11159                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11160                 "response": {
  11161                     "clientDataJSON": b64_cdata_json,
  11162                     "authenticatorData": b64_adata,
  11163                     "transports": [],
  11164                     "publicKey": b64_key,
  11165                     "publicKeyAlgorithm": null,
  11166                     "attestationObject": b64_aobj,
  11167                 },
  11168                 "clientExtensionResults": {},
  11169                 "type": "public-key"
  11170             })
  11171             .to_string()
  11172             .as_str()
  11173         )
  11174         .unwrap_err()
  11175         .to_string()
  11176         .into_bytes()
  11177         .get(..err.len()),
  11178         Some(err.as_slice())
  11179     );
  11180     // `publicKey` mismatch.
  11181     let bad_pub_key = RsaPrivateKey::from_components(
  11182         BoxedUint::from_le_slice_vartime(
  11183             [
  11184                 175, 161, 161, 75, 52, 244, 72, 168, 29, 119, 33, 120, 3, 222, 231, 152, 222, 119,
  11185                 112, 83, 221, 237, 74, 174, 79, 216, 147, 251, 245, 94, 234, 114, 254, 21, 17, 254,
  11186                 8, 115, 75, 127, 150, 87, 59, 109, 230, 116, 85, 90, 11, 160, 63, 217, 9, 38, 187,
  11187                 250, 226, 183, 38, 164, 182, 218, 22, 19, 58, 189, 83, 219, 11, 144, 15, 99, 151,
  11188                 166, 46, 57, 17, 111, 189, 131, 142, 113, 85, 122, 188, 238, 52, 21, 116, 125, 102,
  11189                 195, 182, 165, 29, 156, 213, 182, 125, 156, 88, 56, 221, 2, 98, 43, 210, 115, 32,
  11190                 4, 105, 88, 181, 158, 207, 236, 162, 250, 253, 240, 72, 8, 253, 50, 220, 247, 76,
  11191                 170, 143, 68, 225, 231, 113, 64, 244, 17, 138, 162, 233, 33, 2, 67, 11, 223, 188,
  11192                 232, 152, 193, 20, 32, 243, 52, 64, 43, 2, 243, 8, 77, 150, 232, 109, 148, 95, 127,
  11193                 55, 71, 162, 34, 54, 83, 135, 52, 172, 191, 32, 42, 106, 43, 211, 206, 100, 104,
  11194                 110, 232, 5, 43, 120, 180, 166, 40, 144, 233, 239, 103, 134, 103, 255, 224, 138,
  11195                 184, 208, 137, 127, 36, 189, 143, 248, 201, 2, 218, 51, 232, 96, 30, 83, 124, 109,
  11196                 241, 23, 179, 247, 151, 238, 212, 204, 44, 43, 223, 148, 241, 172, 10, 235, 155,
  11197                 94, 68, 116, 24, 116, 191, 86, 53, 127, 35, 133, 198, 204, 59, 76, 110, 16, 1, 15,
  11198                 148, 135, 157,
  11199             ]
  11200             .as_slice(),
  11201         ),
  11202         0x0001_0001u32.into(),
  11203         BoxedUint::from_le_slice_vartime(
  11204             [
  11205                 129, 93, 123, 251, 104, 29, 84, 203, 116, 100, 75, 237, 111, 160, 12, 100, 172, 76,
  11206                 57, 178, 144, 235, 81, 61, 115, 243, 28, 40, 183, 22, 56, 150, 68, 38, 220, 62,
  11207                 233, 110, 48, 174, 35, 197, 244, 109, 148, 109, 36, 69, 69, 82, 225, 113, 175, 6,
  11208                 239, 27, 193, 101, 50, 239, 122, 102, 7, 46, 98, 79, 195, 116, 155, 158, 138, 147,
  11209                 51, 93, 24, 237, 246, 82, 14, 109, 144, 250, 239, 93, 63, 214, 96, 130, 226, 134,
  11210                 198, 145, 161, 11, 231, 97, 214, 180, 255, 95, 158, 88, 108, 254, 243, 177, 133,
  11211                 184, 92, 95, 148, 88, 55, 124, 245, 244, 84, 86, 4, 121, 44, 231, 97, 176, 190, 29,
  11212                 155, 40, 57, 69, 165, 80, 168, 9, 56, 43, 233, 6, 14, 157, 112, 223, 64, 88, 141,
  11213                 7, 65, 23, 64, 208, 6, 83, 61, 8, 182, 248, 126, 84, 179, 163, 80, 238, 90, 133, 4,
  11214                 14, 71, 177, 175, 27, 29, 151, 211, 108, 162, 195, 7, 157, 167, 86, 169, 3, 87,
  11215                 235, 89, 158, 237, 216, 31, 243, 197, 62, 5, 84, 131, 230, 186, 248, 49, 12, 93,
  11216                 244, 61, 135, 180, 17, 162, 241, 13, 115, 241, 138, 219, 98, 155, 166, 191, 63, 12,
  11217                 37, 1, 165, 178, 84, 200, 72, 80, 41, 77, 136, 217, 141, 246, 209, 31, 243, 159,
  11218                 71, 43, 246, 159, 182, 171, 116, 12, 3, 142, 235, 218, 164, 70, 90, 147, 238, 42,
  11219                 75,
  11220             ]
  11221             .as_slice(),
  11222         ),
  11223         vec![
  11224             BoxedUint::from_le_slice_vartime(
  11225                 [
  11226                     215, 199, 110, 28, 64, 16, 16, 109, 106, 152, 150, 124, 52, 166, 121, 92, 242,
  11227                     13, 0, 69, 7, 152, 72, 172, 118, 63, 156, 180, 140, 39, 53, 29, 197, 224, 177,
  11228                     48, 41, 221, 102, 65, 17, 185, 55, 62, 219, 152, 227, 7, 78, 219, 14, 139, 71,
  11229                     204, 144, 152, 14, 39, 247, 244, 165, 224, 234, 60, 213, 74, 237, 30, 102, 177,
  11230                     242, 138, 168, 31, 122, 47, 206, 155, 225, 113, 103, 175, 152, 244, 27, 233,
  11231                     112, 223, 248, 38, 215, 178, 20, 244, 8, 121, 26, 11, 70, 122, 16, 85, 167, 87,
  11232                     64, 216, 228, 227, 173, 57, 250, 8, 221, 38, 12, 203, 212, 1, 112, 43, 72, 91,
  11233                     225, 97, 228, 57, 154, 193,
  11234                 ]
  11235                 .as_slice(),
  11236             ),
  11237             BoxedUint::from_le_slice_vartime(
  11238                 [
  11239                     233, 89, 204, 152, 31, 242, 8, 110, 38, 190, 111, 159, 105, 105, 45, 85, 15,
  11240                     244, 30, 250, 174, 226, 219, 111, 107, 191, 196, 135, 17, 123, 186, 167, 85,
  11241                     13, 120, 197, 159, 129, 78, 237, 152, 31, 230, 26, 229, 253, 197, 211, 105,
  11242                     204, 126, 142, 250, 55, 26, 172, 65, 160, 45, 6, 99, 86, 66, 238, 107, 6, 98,
  11243                     171, 93, 224, 201, 160, 31, 204, 82, 120, 228, 158, 238, 6, 190, 12, 150, 153,
  11244                     239, 95, 57, 71, 100, 239, 235, 155, 73, 200, 5, 225, 127, 185, 46, 48, 243,
  11245                     84, 33, 142, 17, 19, 20, 23, 215, 16, 114, 58, 211, 14, 73, 148, 168, 252, 159,
  11246                     252, 125, 57, 101, 211, 188, 12, 77, 208,
  11247                 ]
  11248                 .as_slice(),
  11249             ),
  11250         ],
  11251     )
  11252     .unwrap()
  11253     .to_public_key();
  11254     err = Error::invalid_value(
  11255         Unexpected::Bytes([0; 32].as_slice()),
  11256         &format!(
  11257             "DER-encoded public key to match the public key within the attestation object: Rsa(RsaPubKey({:?}, 65537))",
  11258             // Correct and won't `panic`.
  11259             &att_obj[n_start_idx..e_meta_start_idx],
  11260         )
  11261         .as_str(),
  11262     )
  11263     .to_string().into_bytes();
  11264     assert_eq!(serde_json::from_str::<Registration>(
  11265         serde_json::json!({
  11266             "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11267             "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11268             "response": {
  11269                 "clientDataJSON": b64_cdata_json,
  11270                 "authenticatorData": b64_adata,
  11271                 "transports": [],
  11272                 "publicKey": base64url_nopad::encode(bad_pub_key.to_public_key_der().unwrap().as_bytes()),
  11273                 "publicKeyAlgorithm": -257i16,
  11274                 "attestationObject": b64_aobj,
  11275             },
  11276             "clientExtensionResults": {},
  11277             "type": "public-key"
  11278         })
  11279         .to_string()
  11280         .as_str()
  11281         )
  11282         .unwrap_err().to_string().into_bytes().get(..err.len()),
  11283         Some(err.as_slice())
  11284     );
  11285     // Missing `publicKey` when using EdDSA, ES256, or RS256.
  11286     err = Error::missing_field("publicKey").to_string().into_bytes();
  11287     assert_eq!(
  11288         serde_json::from_str::<Registration>(
  11289             serde_json::json!({
  11290                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11291                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11292                 "response": {
  11293                     "clientDataJSON": b64_cdata_json,
  11294                     "authenticatorData": b64_adata,
  11295                     "transports": [],
  11296                     "publicKeyAlgorithm": -257i16,
  11297                     "attestationObject": b64_aobj,
  11298                 },
  11299                 "clientExtensionResults": {},
  11300                 "type": "public-key"
  11301             })
  11302             .to_string()
  11303             .as_str()
  11304         )
  11305         .unwrap_err()
  11306         .to_string()
  11307         .into_bytes()
  11308         .get(..err.len()),
  11309         Some(err.as_slice())
  11310     );
  11311     // `null` `publicKey` when using EdDSA, ES256, or RS256.
  11312     err = Error::invalid_type(Unexpected::Other("null"), &"publicKey")
  11313         .to_string()
  11314         .into_bytes();
  11315     assert_eq!(
  11316         serde_json::from_str::<Registration>(
  11317             serde_json::json!({
  11318                 "id": "AAAAAAAAAAAAAAAAAAAAAA",
  11319                 "rawId": "AAAAAAAAAAAAAAAAAAAAAA",
  11320                 "response": {
  11321                     "clientDataJSON": b64_cdata_json,
  11322                     "authenticatorData": b64_adata,
  11323                     "transports": [],
  11324                     "publicKey": null,
  11325                     "publicKeyAlgorithm": -257i16,
  11326                     "attestationObject": b64_aobj,
  11327                 },
  11328                 "clientExtensionResults": {},
  11329                 "type": "public-key"
  11330             })
  11331             .to_string()
  11332             .as_str()
  11333         )
  11334         .unwrap_err()
  11335         .to_string()
  11336         .into_bytes()
  11337         .get(..err.len()),
  11338         Some(err.as_slice())
  11339     );
  11340 }