cratefield_testing/vectors.rs
1//! The Web Push test vectors the workspace shares.
2//!
3//! These are not decorative constants. [`RFC8291_UA_PUBLIC`] and
4//! [`RFC8291_AUTH_SECRET`] are RFC 8291 Appendix A's user agent: a real
5//! point on the P-256 curve and a real 16-byte auth secret, so a
6//! subscription built from them is one the adapter accepts and a body
7//! encrypted to them can be opened again with [`RFC8291_UA_PRIVATE`]. A
8//! made-up `p256dh` is refused — which is the point of the checks that use
9//! them, and the reason a test cannot simply invent a value.
10//!
11//! They used to be copied into `crates/adapter-webpush`,
12//! `crates/adapter-apns`, `crates/cli` and `crates/cli-acceptance`, each
13//! with a comment saying it was "the same one" another crate used and
14//! nothing making that true. `crates/cli-acceptance/tests/vector_guard.rs`
15//! now fails the build if any source outside this module writes one of
16//! them down again.
17
18/// RFC 8291 Appendix A: the user agent's public key — the `p256dh` a
19/// browser puts in `subscription.keys`, base64url of the 65-byte
20/// uncompressed P-256 point.
21pub const RFC8291_UA_PUBLIC: &str =
22 "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4";
23
24/// RFC 8291 Appendix A: the user agent's private key. Only a test has
25/// this — it is what lets the decrypt side of a round trip exist.
26pub const RFC8291_UA_PRIVATE: &str = "q1dXpw3UpT5VOmu_cf_v6ih07Aems3njxI-JWgLcM94";
27
28/// RFC 8291 Appendix A: the subscription's 16-byte `auth` secret.
29pub const RFC8291_AUTH_SECRET: &str = "BTBZMqHH6r4Tts7J_aSIgg";
30
31/// RFC 8291 §5: the plaintext the published example encrypts.
32pub const RFC8291_PLAINTEXT: &str = "When I grow up, I want to be a watermelon";
33
34/// The push service origin of [`WEB_PUSH_ENDPOINT`] — what a VAPID token
35/// claims as its `aud`, and the most a report may print of an endpoint.
36pub const WEB_PUSH_ORIGIN: &str = "https://updates.push.services.mozilla.com";
37
38/// The subscription-specific part of [`WEB_PUSH_ENDPOINT`]'s path: the
39/// bearer capability, and so the string a test asserts is **absent** from
40/// output. Distinctive on purpose — it cannot be matched by accident.
41pub const WEB_PUSH_ENDPOINT_CAPABILITY: &str = "gAAAAABsubscriptionCapability";
42
43/// A Web Push endpoint of the shape a browser hands over: an origin plus a
44/// long, subscription-specific path. Whoever holds the whole thing can
45/// push to that browser, which is what makes it credential material.
46pub const WEB_PUSH_ENDPOINT: &str =
47 "https://updates.push.services.mozilla.com/wpush/v2/gAAAAABsubscriptionCapability";
48
49/// A throwaway P-256 private key in PKCS#8 PEM, generated for these tests
50/// only — **not** an Apple, Google or Mozilla key.
51///
52/// Shared for the suites that already read from here. It is older than
53/// this module (`cratefield-push-auth` mints with it, and the APNs suite
54/// asserts bytes from it), so unlike the Web Push vectors above it is not
55/// guarded as the only copy — see
56/// `crates/cli-acceptance/tests/vector_guard.rs`.
57pub const TEST_P256_PEM: &str = "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcXMgRpW+eLn7ZvCx\nIuTdd8csWMZ69azlRzS0dy2FN6GhRANCAATJ6GazR2lhWcC3JYsazLR0uWOyDKrC\nmeP4HPWghRmfoa4z3Ux7mG3Ylz+auRaBukKGicSdSvVG+jGeQwr3fNag\n-----END PRIVATE KEY-----";
58
59/// A `mailto:` VAPID subject (RFC 8292 §2.1).
60pub const TEST_VAPID_SUBJECT: &str = "mailto:ops@example.test";
61
62/// The subscription exactly as `JSON.stringify(subscription)` gives it —
63/// the shape an operator pastes into `fz push send --recipient`.
64#[must_use]
65pub fn web_push_subscription_json() -> String {
66 format!(
67 "{{\"endpoint\":\"{WEB_PUSH_ENDPOINT}\",\"expirationTime\":null,\
68 \"keys\":{{\"p256dh\":\"{RFC8291_UA_PUBLIC}\",\"auth\":\"{RFC8291_AUTH_SECRET}\"}}}}"
69 )
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn the_endpoint_is_its_origin_and_its_capability() {
78 assert_eq!(
79 WEB_PUSH_ENDPOINT,
80 format!("{WEB_PUSH_ORIGIN}/wpush/v2/{WEB_PUSH_ENDPOINT_CAPABILITY}"),
81 "the three have to be one endpoint, or a test asserting the capability is absent \
82 asserts nothing"
83 );
84 }
85
86 #[test]
87 fn the_subscription_json_carries_the_vectors() {
88 let json = web_push_subscription_json();
89 for part in [WEB_PUSH_ENDPOINT, RFC8291_UA_PUBLIC, RFC8291_AUTH_SECRET] {
90 assert!(json.contains(part), "{part} is missing from {json}");
91 }
92 }
93}