diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-04-02 16:45:03 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-04-03 14:11:18 +0200 |
| commit | 6512b686bc7935be275c5e37a53bf6b20e45b459 (patch) | |
| tree | 36dd13a339080390c96bc9be0cebf6880bcc5604 | |
| parent | a17a5bcd74806a9a6521c0d0a27a501750f69d18 (diff) | |
| download | mullvadvpn-6512b686bc7935be275c5e37a53bf6b20e45b459.tar.xz mullvadvpn-6512b686bc7935be275c5e37a53bf6b20e45b459.zip | |
Do not specify verifying keys in HttpVersionInfoProvider by default
3 files changed, 117 insertions, 105 deletions
diff --git a/mullvad-update/meta/src/platform.rs b/mullvad-update/meta/src/platform.rs index 0455e5acee..06ad8a7185 100644 --- a/mullvad-update/meta/src/platform.rs +++ b/mullvad-update/meta/src/platform.rs @@ -103,10 +103,12 @@ impl Platform { println!("Pulling {self} metadata from {}...", platform.url()); - let response = HttpVersionInfoProvider::from(platform) - .get_versions(crate::MIN_VERIFY_METADATA_VERSION) - .await - .context("Failed to retrieve versions")?; + let response = HttpVersionInfoProvider::get_versions_for_platform( + platform, + crate::MIN_VERIFY_METADATA_VERSION, + ) + .await + .context("Failed to retrieve versions")?; let json = serde_json::to_string_pretty(&response) .context("Failed to serialize updated metadata")?; diff --git a/mullvad-update/src/client/api.rs b/mullvad-update/src/client/api.rs index 2ba215cdb4..c4953177b3 100644 --- a/mullvad-update/src/client/api.rs +++ b/mullvad-update/src/client/api.rs @@ -1,6 +1,7 @@ //! This module implements fetching of information about app versions use anyhow::Context; +#[cfg(test)] use vec1::Vec1; use crate::format; @@ -59,8 +60,6 @@ pub struct HttpVersionInfoProvider { url: String, /// Accepted root certificate. Defaults are used unless specified pinned_certificate: Option<reqwest::Certificate>, - /// Key to use for verifying the response - verifying_keys: Vec1<format::key::VerifyingKey>, } #[async_trait::async_trait] @@ -74,13 +73,11 @@ impl VersionInfoProvider for HttpVersionInfoProvider { impl From<MetaRepositoryPlatform> for HttpVersionInfoProvider { /// Construct an [HttpVersionInfoProvider] for the given platform using reasonable defaults. /// - /// By default, `pinned_certificate` will be set to the LE root certificate, and - /// `verifying_keys` will be set to the keys in `trusted-metadata-signing-keys`. + /// By default, `pinned_certificate` will be set to the LE root certificate. fn from(platform: MetaRepositoryPlatform) -> Self { HttpVersionInfoProvider { url: platform.url(), pinned_certificate: Some(crate::defaults::PINNED_CERTIFICATE.clone()), - verifying_keys: crate::defaults::TRUSTED_METADATA_SIGNING_PUBKEYS.clone(), } } } @@ -89,18 +86,56 @@ impl HttpVersionInfoProvider { /// Maximum size of the GET response, in bytes const SIZE_LIMIT: usize = 1024 * 1024; - /// Download and verify signed data - pub async fn get_versions( + /// Retrieve version metadata for the given platform using reasonable defaults. + /// + /// By default, `pinned_certificate` will be set to the LE root certificate, and + /// `verifying_keys` will be set to the keys in `trusted-metadata-signing-keys`. + pub async fn get_versions_for_platform( + platform: MetaRepositoryPlatform, + lowest_metadata_version: usize, + ) -> anyhow::Result<format::SignedResponse> { + HttpVersionInfoProvider::from(platform) + .get_versions(lowest_metadata_version) + .await + } + + /// Download and verify signed data with sane defaults + /// + /// By default, `pinned_certificate` will be set to the LE root certificate, and + /// and the keys in `trusted-metadata-signing-keys` will be used for verification. + async fn get_versions( + &self, + lowest_metadata_version: usize, + ) -> anyhow::Result<format::SignedResponse> { + self.get_versions_inner(|raw_json| { + format::SignedResponse::deserialize_and_verify(raw_json, lowest_metadata_version) + }) + .await + } + + /// Download and verify signed data with the given keys + #[cfg(test)] + async fn get_versions_with_keys( &self, lowest_metadata_version: usize, + verifying_keys: &Vec1<format::key::VerifyingKey>, + ) -> anyhow::Result<format::SignedResponse> { + self.get_versions_inner(|raw_json| { + format::SignedResponse::deserialize_and_verify_with_keys( + verifying_keys, + raw_json, + lowest_metadata_version, + ) + }) + .await + } + + async fn get_versions_inner( + &self, + deserialize_fn: impl FnOnce(&[u8]) -> anyhow::Result<format::SignedResponse>, ) -> anyhow::Result<format::SignedResponse> { let raw_json = Self::get(&self.url, self.pinned_certificate.clone()).await?; - let response = format::SignedResponse::deserialize_and_verify_with_keys( - &self.verifying_keys, - &raw_json, - lowest_metadata_version, - )?; - Ok(response) + deserialize_fn(&raw_json) } /// Perform a simple GET request, with a size limit, and return it as bytes @@ -158,8 +193,6 @@ mod test { use insta::assert_yaml_snapshot; use vec1::vec1; - use crate::version::VersionArchitecture; - use super::*; // These tests rely on `insta` for snapshot testing. If they fail due to snapshot assertions, @@ -187,19 +220,13 @@ mod test { let url = format!("{}/version", server.url()); // Construct query and provider - let params = VersionParameters { - architecture: VersionArchitecture::X86, - rollout: 1., - lowest_metadata_version: 0, - }; let info_provider = HttpVersionInfoProvider { url, pinned_certificate: None, - verifying_keys, }; let info = info_provider - .get_version_info(params) + .get_versions_with_keys(0, &verifying_keys) .await .context("Expected valid version info")?; diff --git a/mullvad-update/src/client/snapshots/mullvad_update__client__api__test__http_version_provider.snap b/mullvad-update/src/client/snapshots/mullvad_update__client__api__test__http_version_provider.snap index 1cb23ff5e5..a7266769fc 100644 --- a/mullvad-update/src/client/snapshots/mullvad_update__client__api__test__http_version_provider.snap +++ b/mullvad-update/src/client/snapshots/mullvad_update__client__api__test__http_version_provider.snap @@ -1,83 +1,66 @@ --- -source: mullvad-update/src/api.rs +source: mullvad-update/src/client/api.rs expression: info snapshot_kind: text --- -stable: - version: "2025.2" - urls: - - "https://releases.mullvad.net/desktop/releases/2025.2/MullvadVPN-2025.2.exe" - size: 101384672 - changelog: "[macos] Adding support for quicfuscator\n[windows] Less bugs" - sha256: - - 244 - - 178 - - 87 - - 19 - - 209 - - 63 - - 40 - - 25 - - 163 - - 0 - - 242 - - 255 - - 169 - - 77 - - 150 - - 116 - - 99 - - 170 - - 238 - - 160 - - 211 - - 87 - - 251 - - 215 - - 71 - - 154 - - 40 - - 17 - - 84 - - 186 - - 4 - - 96 -beta: - version: 2025.3-beta1 - urls: - - "https://releases.mullvad.net/desktop/releases/2025.3-beta1/MullvadVPN-2025.3-beta1_x64.exe" - size: 106297504 - changelog: "[macos] Adding support for quicfuscator\n[windows] Less bugs" - sha256: - - 12 - - 86 - - 154 - - 160 - - 145 - - 46 - - 185 - - 54 - - 5 - - 168 - - 80 - - 115 - - 68 - - 125 - - 66 - - 186 - - 12 - - 166 - - 18 - - 54 - - 27 - - 239 - - 120 - - 239 - - 4 - - 239 - - 3 - - 142 - - 128 - - 177 - - 84 - - 3 +signatures: + - keytype: ed25519 + keyid: bb4ef63ffdcc6bd5a19c30cd23b9de03099407a04463418f17ae338b98aa09d4 + sig: 253ec37846dcd909bfc5119c0e0d06535767e179eb8b4465015eaa95f4bed362c8c9186311192c987871722bf7d319d44e4f04eaf79c269820bc13ff1a901f0b +signed: + metadata_version: 0 + metadata_expiry: "2025-07-02T15:33:00Z" + releases: + - version: "2025.2" + changelog: "[macos] Adding support for quicfuscator\n[windows] Less bugs" + installers: + - architecture: x86 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.2/MullvadVPN-2025.2.exe" + size: 101384672 + sha256: F4B25713D13F2819A300F2FFA94D967463AAEEA0D357FBD7479A281154BA0460 + - architecture: arm64 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.2/MullvadVPN-2025.2_arm64.exe" + size: 104146312 + sha256: AFD8098A1FF89D69A243EC4E2E946CF5FBF8D1C10998230D6C8FC0A5C9C39541 + - version: "2025.3" + changelog: "[macos] Adding support for quicfuscator\n[windows] Less bugs" + installers: + - architecture: x86 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.2/MullvadVPN-2025.2.exe" + size: 101384672 + sha256: F4B25713D13F2819A300F2FFA94D967463AAEEA0D357FBD7479A281154BA0460 + - architecture: arm64 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.2/MullvadVPN-2025.2_arm64.exe" + size: 104146312 + sha256: AFD8098A1FF89D69A243EC4E2E946CF5FBF8D1C10998230D6C8FC0A5C9C39541 + rollout: 0.5 + - version: 2025.1-beta1 + changelog: "[macos] Adding support for quicfuscator\n[windows] Less bugs" + installers: + - architecture: x86 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.3-beta1/MullvadVPN-2025.3-beta1_x64.exe" + size: 106297504 + sha256: 0c569aa0912eb93605a85073447d42ba0ca612361bef78ef04ef038e80b15403 + - architecture: arm64 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.3-beta1/MullvadVPN-2025.3-beta1_arm64.exe" + size: 111488248 + sha256: 82948D3DB5B869EE5F0D246DB557A81B72B68DFDDD2267872B7B8A5B19A05444 + - version: 2025.3-beta1 + changelog: "[macos] Adding support for quicfuscator\n[windows] Less bugs" + installers: + - architecture: x86 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.3-beta1/MullvadVPN-2025.3-beta1_x64.exe" + size: 106297504 + sha256: 0c569aa0912eb93605a85073447d42ba0ca612361bef78ef04ef038e80b15403 + - architecture: arm64 + urls: + - "https://releases.mullvad.net/desktop/releases/2025.3-beta1/MullvadVPN-2025.3-beta1_arm64.exe" + size: 111488248 + sha256: 82948D3DB5B869EE5F0D246DB557A81B72B68DFDDD2267872B7B8A5B19A05444 |
