diff --git a/src/lib.rs b/src/lib.rs index d34c4b5..08fa556 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -423,12 +423,13 @@ fn check_key_constants( crv: Option, ) -> Result<(), E> { let kty = kty.ok_or_else(|| E::missing_field("kty"))?; - let alg = alg.ok_or_else(|| E::missing_field("alg"))?; if kty != K::KTY { return Err(E::invalid_value(Unexpected::Signed(kty as _), &K::KTY)); } - if alg != K::ALG { - return Err(E::invalid_value(Unexpected::Signed(alg as _), &K::ALG)); + if let Some(alg) = alg { + if alg != K::ALG { + return Err(E::invalid_value(Unexpected::Signed(alg as _), &K::ALG)); + } } if K::CRV != Crv::None { let crv = crv.ok_or_else(|| E::missing_field("crv"))?; diff --git a/tests/cose.rs b/tests/cose.rs index 6d8837c..1e96473 100644 --- a/tests/cose.rs +++ b/tests/cose.rs @@ -55,6 +55,50 @@ fn test_de(s: &str, data: T) { assert_eq!(data, deserialized); } +fn test_de_alg( + data: T, + alg: Option, +) -> bool { + let serialized_value = Value::serialized(&data).unwrap(); + let mut fields = serialized_value.into_map().unwrap(); + // this must be alg + assert_eq!(fields[1].0, Value::Integer(3.into())); + + let expect_success = if let Some(alg) = alg { + // alg values may only work if they are correct + let alg = Value::Integer(alg.into()); + if fields[1].1 == alg { + true + } else { + fields[1].1 = alg; + false + } + } else { + // deserialization without alg must work + fields.remove(1); + true + }; + + let (deserialized, serialized) = deserialize_map::(fields); + let is_success = deserialized.is_ok() == expect_success; + + if !is_success { + if alg.is_some() { + if expect_success { + println!("Expected correct deserialization for original algorithm"); + } else { + println!("Expected error for invalid algorithm"); + } + } else { + println!("Expected correct deserialization for missing algorithm"); + } + println!("alg: {:?}", alg); + print_input_output(&data, &serialized, &deserialized); + } + + is_success +} + fn test_de_order(data: T) -> bool { let serialized_value = Value::serialized(&data).unwrap(); let canonical_fields = serialized_value.into_map().unwrap(); @@ -167,4 +211,24 @@ quickcheck::quickcheck! { x: x.0, }) } + + fn de_alg_p256(x: Input, y: Input, alg: Option) -> bool { + test_de_alg(P256PublicKey { + x: x.0, + y: y.0, + }, alg) + } + + fn de_alg_ecdh(x: Input, y: Input, alg: Option) -> bool { + test_de_alg(EcdhEsHkdf256PublicKey { + x: x.0, + y: y.0, + }, alg) + } + + fn de_alg_ed25519(x: Input, alg: Option) -> bool { + test_de_alg(Ed25519PublicKey { + x: x.0, + }, alg) + } }