diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-03-06 17:57:35 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-03-07 10:21:44 +0100 |
| commit | 264c3b15cbc68ec49899b0b1d0907f2581d9acd2 (patch) | |
| tree | 140c20d9004028fee7a65aadf7b361ca1fe4bf91 | |
| parent | 0183121e0ee85a8548f03195621938fbfe13e93d (diff) | |
| download | mullvadvpn-264c3b15cbc68ec49899b0b1d0907f2581d9acd2.tar.xz mullvadvpn-264c3b15cbc68ec49899b0b1d0907f2581d9acd2.zip | |
Add tests for signing and verifying with multiple keys
| -rw-r--r-- | mullvad-update/src/client/api.rs | 5 | ||||
| -rw-r--r-- | mullvad-update/src/format/serializer.rs | 53 |
2 files changed, 55 insertions, 3 deletions
diff --git a/mullvad-update/src/client/api.rs b/mullvad-update/src/client/api.rs index d3e4ea1790..b3428854ab 100644 --- a/mullvad-update/src/client/api.rs +++ b/mullvad-update/src/client/api.rs @@ -117,8 +117,9 @@ mod test { /// We're not testing the correctness of [version] here, only the HTTP client #[tokio::test] async fn test_http_version_provider() -> anyhow::Result<()> { - let valid_key = crate::format::key::VerifyingKey::from_hex(include_str!("../../test-pubkey")) - .expect("valid key"); + let valid_key = + crate::format::key::VerifyingKey::from_hex(include_str!("../../test-pubkey")) + .expect("valid key"); let verifying_keys = vec1![valid_key]; // Start HTTP server diff --git a/mullvad-update/src/format/serializer.rs b/mullvad-update/src/format/serializer.rs index ca98b7ba26..ce6ebf9559 100644 --- a/mullvad-update/src/format/serializer.rs +++ b/mullvad-update/src/format/serializer.rs @@ -96,7 +96,58 @@ mod test { let bytes = serde_json::to_vec(&partial)?; - deserialize_and_verify(&vec1![pubkey], &bytes)?; + deserialize_and_verify(&vec1![pubkey.clone()], &bytes)?; + + // Verify that an irrelevant key is ignored + let invalid_key = key::SecretKey::generate(); + let invalid_pubkey = invalid_key.pubkey(); + + deserialize_and_verify(&vec1![pubkey.clone(), invalid_pubkey.clone()], &bytes)?; + + // Wrong public key only fails + deserialize_and_verify(&vec1![invalid_pubkey], &bytes).unwrap_err(); + + Ok(()) + } + + #[test] + fn test_sign_multiple() -> anyhow::Result<()> { + // Generate keys and data + let key = key::SecretKey::generate(); + let pubkey = key.pubkey(); + + let key2 = key::SecretKey::generate(); + let pubkey2 = key2.pubkey(); + + let invalid_key = key::SecretKey::generate(); + let invalid_pubkey = invalid_key.pubkey(); + + let data = json!({ + "stuff": "I can prove that I wrote this" + }); + + // Sign with two keys + let mut partial = sign(&key, &data).context("Signing failed")?; + let partial2 = sign(&key2, &data).context("Signing failed")?; + partial.signatures.extend(partial2.signatures); + + let bytes = serde_json::to_vec(&partial)?; + + // Accept either (or both) keys + deserialize_and_verify(&vec1![pubkey.clone(), pubkey2.clone()], &bytes)?; + deserialize_and_verify(&vec1![pubkey2.clone()], &bytes)?; + deserialize_and_verify(&vec1![pubkey.clone()], &bytes)?; + + // Ignore irrelevant key + deserialize_and_verify( + &vec1![pubkey.clone(), pubkey2.clone(), invalid_pubkey.clone()], + &bytes, + )?; + deserialize_and_verify(&vec1![pubkey2, invalid_pubkey.clone()], &bytes)?; + deserialize_and_verify(&vec1![invalid_pubkey.clone(), pubkey], &bytes)?; + + // Using wrong public key fails + deserialize_and_verify(&vec1![invalid_pubkey], &bytes).unwrap_err(); Ok(()) } |
