Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Session-token authenticated requests to the FxA auth-server now use the typed-Bearer token scheme (`Authorization: Bearer fxs_<token_id>`) instead of Hawk. This is an internal change with no consumer-facing API impact; production routes accept both schemes. See the [authentication schemes reference](https://mozilla.github.io/ecosystem-platform/reference/authentication-schemes). ([#PRNUM](https://github.com/mozilla/application-services/pull/PRNUM))

### Remote Settings

- Skip verification of signatures with unknown signature types ([Bug 2055147](https://bugzilla.mozilla.org/show_bug.cgi?id=2055147))

[Full Changelog](In progress)

## ✨ What's New ✨
Expand Down
44 changes: 44 additions & 0 deletions components/remote_settings/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ impl<C: ApiClient> RemoteSettingsClient<C> {
"No valid signatures found".into(),
));
for signature in &metadata.signatures {
if signature.mode != "p384ecdsa" {
// We currently only support ECDSA P384.
// Change this once `rc_crypto` will support more types (eg. post-quantum algorithms).
continue;
}

let cert_chain_bytes = inner.api_client.fetch_cert(&signature.x5u)?;

// The signer name is hard-coded. This would have to be modified in the very (very)
Expand Down Expand Up @@ -799,6 +805,8 @@ pub struct CollectionSignature {
pub signature: String,
/// X.509 certificate chain Url (x5u)
pub x5u: String,
/// Signature type
pub mode: String,
}

/// A parsed Remote Settings record. Records can contain arbitrary fields, so clients
Expand Down Expand Up @@ -1375,6 +1383,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
VALID_CERT_EPOCH_SECONDS,
"main",
Expand All @@ -1394,10 +1403,39 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
CollectionSignature {
signature: "invalid signature".to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
},
CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
},
],
VALID_CERT_EPOCH_SECONDS,
"main",
)
.expect("Valid signature");
Ok(())
}

#[test]
fn test_first_signature_has_unknown_type() -> Result<()> {
ensure_initialized();
run_client_sync(
&[],
&[],
VALID_CERTIFICATE,
&[
CollectionSignature {
signature: "unkown signature".to_string(),
x5u: "http://mocked".into(),
// Unknown signature type.
mode: "mldsa".into(),
},
CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
},
],
VALID_CERT_EPOCH_SECONDS,
Expand All @@ -1423,6 +1461,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
VALID_CERT_EPOCH_SECONDS,
"main",
Expand All @@ -1441,6 +1480,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: "invalid signature".to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
VALID_CERT_EPOCH_SECONDS,
"main",
Expand All @@ -1462,6 +1502,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
VALID_CERT_EPOCH_SECONDS,
"main",
Expand Down Expand Up @@ -1489,6 +1530,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
december_20_2024,
"main",
Expand Down Expand Up @@ -1522,6 +1564,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
VALID_CERT_EPOCH_SECONDS,
"main",
Expand All @@ -1544,6 +1587,7 @@ IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
&[CollectionSignature {
signature: VALID_SIGNATURE.to_string(),
x5u: "http://mocked".into(),
mode: "p384ecdsa".into(),
}],
VALID_CERT_EPOCH_SECONDS,
"security-state",
Expand Down
16 changes: 13 additions & 3 deletions components/remote_settings/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ impl Storage {
SELECT
cm.bucket,
json_extract(sig.value, '$.x5u') AS x5u,
json_extract(sig.value, '$.signature') AS signature
json_extract(sig.value, '$.signature') AS signature,
json_extract(sig.value, '$.mode') AS mode
FROM collection_metadata AS cm
LEFT JOIN json_each(cm.signatures) AS sig ON true
WHERE cm.collection_url = ?
Expand All @@ -161,8 +162,13 @@ impl Storage {
}
let x5u: Option<String> = row.get(1)?;
let signature: Option<String> = row.get(2)?;
if let (Some(x5u), Some(signature)) = (x5u, signature) {
signatures.push(CollectionSignature { signature, x5u });
let mode: Option<String> = row.get(3)?;
if let (Some(x5u), Some(signature), Some(mode)) = (x5u, signature, mode) {
signatures.push(CollectionSignature {
signature,
x5u,
mode,
});
}
}
match bucket {
Expand Down Expand Up @@ -1123,10 +1129,12 @@ mod tests {
CollectionSignature {
signature: "b64encodedsig".into(),
x5u: "http://15u/".into(),
mode: "mldsa".into(),
},
CollectionSignature {
signature: "b64encodedsig2".into(),
x5u: "http://15u2/".into(),
mode: "p384ecdsa".into(),
},
],
},
Expand All @@ -1136,8 +1144,10 @@ mod tests {

assert_eq!(metadata.signatures[0].signature, "b64encodedsig");
assert_eq!(metadata.signatures[0].x5u, "http://15u/");
assert_eq!(metadata.signatures[0].mode, "mldsa");
assert_eq!(metadata.signatures[1].signature, "b64encodedsig2");
assert_eq!(metadata.signatures[1].x5u, "http://15u2/");
assert_eq!(metadata.signatures[1].mode, "p384ecdsa");

Ok(())
}
Expand Down
5 changes: 5 additions & 0 deletions components/search/src/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ mod tests {
"signatures": [{
"x5u": "fake",
"signature": "fake",
"mode": "fake",
}],
},
"timestamp": 1000,
Expand Down Expand Up @@ -982,6 +983,7 @@ mod tests {
"signatures": [{
"x5u": "fake",
"signature": "fake",
"mode": "fake",
}],
},
"timestamp": 1000,
Expand Down Expand Up @@ -1031,6 +1033,7 @@ mod tests {
"signatures": [{
"x5u": "fake",
"signature": "fake",
"mode": "fake",
}],
},
"timestamp": 1000,
Expand All @@ -1055,6 +1058,7 @@ mod tests {
"signatures": [{
"x5u": "fake",
"signature": "fake",
"mode": "fake",
}],
},
"timestamp": 1000,
Expand Down Expand Up @@ -1142,6 +1146,7 @@ mod tests {
"signatures": [{
"x5u": "fake",
"signature": "fake",
"mode": "fake",
}],
},
"timestamp": 1000,
Expand Down