Skip to content

Commit

Permalink
test(token): separate tests for verification against self/examples
Browse files Browse the repository at this point in the history
  • Loading branch information
pulsastrix committed Jun 17, 2024
1 parent c3fd6ce commit 4cb4fe5
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ std = ["serde/std", "ciborium/std", "serde_bytes/std", "erased-serde/std", "deri
serde = { version = "1.0", default-features = false, features = ["derive"] }
ciborium = { version = "^0.2", default-features = false }
ciborium-io = { version = "^0.2", default-features = false }
coset = { version = "^0.3", default-features = false }
coset = { version = "^0.3", default-features = false }#, path = "../coset" }
serde_bytes = { version = "^0.11", default-features = false, features = ["alloc"] }
erased-serde = { version = "0.4.5", default-features = false, features = ["alloc"] }
derive_builder = { version = "0.20", default-features = false, features = ["alloc"] }
Expand Down
125 changes: 108 additions & 17 deletions src/token/crypto_impl/openssl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,12 @@ impl CoseSignCipher for Signer<'_> {
unprotected_signature_header: Option<&Header>,

Check warning on line 325 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `unprotected_signature_header`

warning: unused variable: `unprotected_signature_header` --> src/token/crypto_impl/openssl.rs:325:9 | 325 | unprotected_signature_header: Option<&Header>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unprotected_signature_header`

Check warning on line 325 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / Check

unused variable: `unprotected_signature_header`

Check warning on line 325 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused variable: `unprotected_signature_header`

Check warning on line 325 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / test_coverage

unused variable: `unprotected_signature_header`
protected_signature_header: Option<&ProtectedHeader>,

Check warning on line 326 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `protected_signature_header`

warning: unused variable: `protected_signature_header` --> src/token/crypto_impl/openssl.rs:326:9 | 326 | protected_signature_header: Option<&ProtectedHeader>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_protected_signature_header`

Check warning on line 326 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / Check

unused variable: `protected_signature_header`

Check warning on line 326 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused variable: `protected_signature_header`

Check warning on line 326 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / test_coverage

unused variable: `protected_signature_header`
) -> Result<(), CoseCipherError<Self::Error>> {
match &protected_header.header.alg {
let algorithm = if protected_header.header.alg.is_some() {
&protected_header.header.alg
} else {
&unprotected_header.alg
};
match algorithm {
Some(Algorithm::Assigned(iana::Algorithm::ES256)) => {
let p256group: EcGroup = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let public_key =
Expand Down Expand Up @@ -423,13 +428,14 @@ mod tests {
iana, AsCborValue, CborSerializable, CoseKeyBuilder, CoseSign1, CoseSign1Builder,
HeaderBuilder, TaggedCborSerializable,
};
use openssl::sign::Signer;
use openssl::sign::{Signer, Verifier};

Check warning on line 431 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `Verifier`
use serde::Serialize;

Check warning on line 432 in src/token/crypto_impl/openssl.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `serde::Serialize`

/// Test case from the cose-wg/Examples repository - sign1-tests/sign-pass-01.json
/// Sign and Verify using OpenSSL backend.
/// https://github.com/cose-wg/Examples/blob/master/sign1-tests/sign-pass-01.json
#[test]
fn example_test_sign_pass_01() {
fn example_test_sign_verify_pass_01() {
let key = CoseKeyBuilder::new_ec2_priv_key(
iana::EllipticCurve::P_256,
URL_SAFE_NO_PAD
Expand All @@ -452,6 +458,7 @@ mod tests {

let sign_struct = CoseSign1Builder::new()
.unprotected(unprotected.clone())
.protected(HeaderBuilder::new().build())
.payload(Vec::from(plaintext));

let sign_cbor = sign_struct
Expand All @@ -471,21 +478,105 @@ mod tests {
.unwrap()
.build();

let expected_cbor_raw = hex::decode("D28441A0A201260442313154546869732069732074686520636F6E74656E742E584087DB0D2E5571843B78AC33ECB2830DF7B6E0A4D5B7376DE336B23C591C90C425317E56127FBE04370097CE347087B233BF722B64072BEB4486BDA4031D27244F").unwrap();
let expected_cbor: ciborium::Value =
ciborium::from_reader(expected_cbor_raw.as_slice()).unwrap();
let output_cbor = sign_cbor.clone().to_tagged_vec().unwrap();
println!("Output CBOR of CoseSign1: {}", hex::encode(&output_cbor));

// TODO for some reason, the expected result has an additional byte in the protected header,
// which causes a signature mismatch.
println!(
"Expected CoseSign1 struct:\n{:?}",
CoseSign1::from_tagged_slice(expected_cbor_raw.as_slice()).unwrap()
);
println!("Output CoseSign1 struct:\n{:?}", sign_cbor);
println!(
"Output CBOR of CoseSign1: {}",
hex::encode_upper(sign_cbor.clone().to_tagged_vec().unwrap()).as_str()
let reimported_sign = CoseSign1::from_tagged_slice(output_cbor.as_slice()).unwrap();
assert_eq!(
sign_cbor.to_cbor_value().unwrap(),
reimported_sign.clone().to_cbor_value().unwrap()
);
assert_eq!(sign_cbor.to_cbor_value().unwrap(), expected_cbor)

reimported_sign
.verify_signature(&[], |signature, toverify| {
let intermediate_tobeverified = hex::decode(
"846A5369676E617475726531404054546869732069732074686520636F6E74656E742E",
)
.unwrap();
assert_eq!(toverify, intermediate_tobeverified.as_slice());
<Signer as CoseSignCipher>::verify(
&key,
signature,
toverify,
&reimported_sign.unprotected,
&reimported_sign.protected,
None,
None,
)
})
.unwrap();
}

/// Test case from the cose-wg/Examples repository - sign1-tests/sign-pass-01.json
/// Verify signature from given example using OpenSSL.
/// https://github.com/cose-wg/Examples/blob/master/sign1-tests/sign-pass-01.json
#[test]
fn example_test_verify_pass_01() {
let key = CoseKeyBuilder::new_ec2_priv_key(
iana::EllipticCurve::P_256,
URL_SAFE_NO_PAD
.decode("usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8")
.unwrap(),
URL_SAFE_NO_PAD
.decode("IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4")
.unwrap(),
URL_SAFE_NO_PAD
.decode("V8kgd2ZBRuh2dgyVINBUqpPDr7BOMGcF22CQMIUHtNM")
.unwrap(),
)
.build();
let plaintext = "This is the content.";

let unprotected = HeaderBuilder::new()
.key_id("11".as_bytes().to_vec())
.algorithm(Algorithm::ES256)
.build();

let sign_struct = CoseSign1Builder::new()
.unprotected(unprotected.clone())
.protected(HeaderBuilder::new().build())
.payload(Vec::from(plaintext));

let sign_cbor = sign_struct
.try_create_signature(&[], |tosign| {
let intermediate_tobesigned = hex::decode(
"846A5369676E617475726531404054546869732069732074686520636F6E74656E742E",
)
.unwrap();
assert_eq!(tosign, intermediate_tobesigned.as_slice());
<Signer as CoseSignCipher>::sign(
&key,
tosign,
&unprotected,
&HeaderBuilder::new().build(),
)
})
.unwrap()
.build();

let example_cbor_raw = hex::decode("D28441A0A201260442313154546869732069732074686520636F6E74656E742E584087DB0D2E5571843B78AC33ECB2830DF7B6E0A4D5B7376DE336B23C591C90C425317E56127FBE04370097CE347087B233BF722B64072BEB4486BDA4031D27244F").unwrap();
let example_cbor: ciborium::Value =
ciborium::from_reader(example_cbor_raw.as_slice()).unwrap();
let example_sign = CoseSign1::from_tagged_slice(example_cbor_raw.as_slice()).unwrap();

example_sign
.verify_signature(&[], |signature, toverify| {
let intermediate_tobeverified = hex::decode(
"846A5369676E617475726531404054546869732069732074686520636F6E74656E742E",
)
.unwrap();
// TODO Value for which to verify signature for seems to be mismatched - presumably because the example token has this zero length string encoding with the A0 byte for the protected header.
assert_eq!(toverify, intermediate_tobeverified.as_slice());
<Signer as CoseSignCipher>::verify(
&key,
signature,
toverify,
&example_sign.unprotected,
&example_sign.protected,
None,
None,
)
})
.unwrap();
}
}

0 comments on commit 4cb4fe5

Please sign in to comment.