summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-04-02 16:45:03 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-04-03 14:11:18 +0200
commit6512b686bc7935be275c5e37a53bf6b20e45b459 (patch)
tree36dd13a339080390c96bc9be0cebf6880bcc5604
parenta17a5bcd74806a9a6521c0d0a27a501750f69d18 (diff)
downloadmullvadvpn-6512b686bc7935be275c5e37a53bf6b20e45b459.tar.xz
mullvadvpn-6512b686bc7935be275c5e37a53bf6b20e45b459.zip
Do not specify verifying keys in HttpVersionInfoProvider by default
-rw-r--r--mullvad-update/meta/src/platform.rs10
-rw-r--r--mullvad-update/src/client/api.rs71
-rw-r--r--mullvad-update/src/client/snapshots/mullvad_update__client__api__test__http_version_provider.snap141
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