1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
//! BDEW MaKo AS4 protocol constants.
//!
//! All values are taken from the **BDEW AS4 Kommunikationshandbuch** (mandatory
//! for electricity since 1 April 2024, for gas since 1 April 2025).
// ── Service / action ─────────────────────────────────────────────────────────
/// BDEW MaKo AS4 service identifier used in `<eb:Service>`.
///
/// Identifies the BDEW market communication business service in the ebMS3
/// `<eb:CollaborationInfo>` element.
pub const SERVICE: &str = "urn:bdew:as4:service";
/// `type` attribute on `<eb:Service>` — empty string omits the attribute.
pub const SERVICE_TYPE: &str = "";
/// BDEW MaKo AS4 agreement reference (`<eb:AgreementRef>`).
///
/// Fixed value per BDEW AS4-Profil v1.2 §2.3.2, signalling that the profile's
/// dynamic sender/receiver model is in use. The `pmode` and `type` attributes
/// **must not** be emitted alongside it — pass `None` for the type.
pub const AGREEMENT_REF: &str = "https://www.bdew.de/as4/communication/agreement";
// ── Roles ─────────────────────────────────────────────────────────────────────
/// `<eb:From>/<eb:Role>` — fixed `PMode.Initiator.Role` per §2.3, Tabelle 1.
pub const ROLE_INITIATOR: &str =
"http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/initiator";
/// `<eb:To>/<eb:Role>` — fixed `PMode.Responder.Role` per §2.3, Tabelle 1.
pub const ROLE_RESPONDER: &str =
"http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/responder";
// ── Party identifier types ────────────────────────────────────────────────────
/// `<eb:PartyId>/@type` for a GLN, per §2.3.1.1 (ebCore ISO 6523, ICD 0088).
pub const PARTY_TYPE_GLN: &str = "urn:oasis:names:tc:ebcore:partyid-type:iso6523:0088";
/// `<eb:PartyId>/@type` for a BDEW-assigned MP-ID, per §2.3.1.1.
pub const PARTY_TYPE_BDEW: &str = "urn:oasis:names:tc:ebcore:partyid-type:unregistered:BDEW";
/// `<eb:PartyId>/@type` for a DVGW-assigned MP-ID, per §2.3.1.1.
pub const PARTY_TYPE_DVGW: &str = "urn:oasis:names:tc:ebcore:partyid-type:unregistered:DVGW";
/// `<eb:PartyId>/@type` for a DB (Bahnstromnetz) MP-ID, per §2.3.1.1.
pub const PARTY_TYPE_BAHN: &str = "urn:oasis:names:tc:ebcore:partyid-type:unregistered:BAHN";
/// Map a NAD DE3055 agency code to its ebCore `<eb:PartyId>/@type`.
///
/// §2.3.1.1 requires the attribute and derives it from the agency that issued
/// the MP-ID, so the two identifier vocabularies — EDIFACT's numeric agency
/// code and AS4's ebCore URI — must not drift apart. Unknown codes fall back
/// to the BDEW scheme, matching the registry's own default agency.
pub const
// ── MPC ───────────────────────────────────────────────────────────────────────
/// ebMS3 default Message Partition Channel.
///
/// BDEW uses the standard default MPC; no custom partitioning is required.
pub const DEFAULT_MPC: &str =
"http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/defaultMPC";
// ── WS-Security signing algorithms ───────────────────────────────────────────
/// ECDSA-SHA256 signature algorithm.
///
/// Mandatory per BDEW AS4-Profil v1.2 §2.2.6.2.1 and BSI TR-03116-3 §9.1.
/// Use with a BrainpoolP256r1 EC signing key; the algorithm is auto-detected
/// from the key type — no explicit configuration needed.
pub const SIG_ALGO_ECDSA_SHA256: &str = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
/// SHA-256 digest algorithm (mandatory for all signed content).
pub const DIGEST_SHA256: &str = "http://www.w3.org/2001/04/xmlenc#sha256";
/// Exclusive C14N canonicalization algorithm (without comments).
///
/// Required by BDEW for WS-Security XMLDSig (BDEW AS4 Kommunikationshandbuch §5.5).
pub const C14N_EXCLUSIVE: &str = "http://www.w3.org/2001/10/xml-exc-c14n#";
// ── XML Encryption algorithms ─────────────────────────────────────────────────
/// ECDH-ES key agreement algorithm.
///
/// Mandatory per BDEW AS4-Profil v1.2 §2.2.6.2.2 and BSI TR-03116-3 §9.2.
/// Automatically selected when the recipient certificate carries an EC public key.
pub const ENC_KEY_AGREEMENT_ECDH_ES: &str = "http://www.w3.org/2009/xmlenc11#ECDH-ES";
/// ConcatKDF key derivation algorithm (NIST SP 800-56A §5.8.1).
///
/// Used inside ECDH-ES key agreement to derive the key-encryption key (KEK).
pub const ENC_KEY_DERIVATION_CONCAT_KDF: &str = "http://www.w3.org/2009/xmlenc11#ConcatKDF";
/// AES-128 Key Wrap algorithm (RFC 3394).
///
/// Mandatory per BDEW AS4-Profil v1.2 §2.2.6.2.2: wraps the CEK with the
/// ECDH-ES-derived KEK.
pub const ENC_KEY_WRAP_AES128: &str = "http://www.w3.org/2001/04/xmlenc#kw-aes128";
/// AES-128-GCM content encryption algorithm.
///
/// Mandatory per BDEW AS4-Profil v1.2 §2.2.6.2.2.
pub const ENC_CONTENT_AES128_GCM: &str = "http://www.w3.org/2009/xmlenc11#aes128-gcm";
/// AES-256-GCM content encryption algorithm (alternative, not mandated by BDEW v1.2).
pub const ENC_CONTENT_AES256_GCM: &str = "http://www.w3.org/2009/xmlenc11#aes256-gcm";
// ── Reliability ───────────────────────────────────────────────────────────────
/// Maximum retry duration in seconds — 72 hours (BDEW AS4 Kommunikationshandbuch).
///
/// AS4 senders MUST retry unacknowledged messages for up to 72 hours before
/// permanently failing delivery. This window also defines the deduplication
/// TTL: an [`asx_rs`] `TtlDedupStorage` should be configured with at least
/// this TTL (96 hours recommended for safety margin).
pub const MAX_RETRY_DURATION_SECS: u64 = 72 * 3600;
/// Timestamp freshness window in seconds.
///
/// Per eDelivery AS4 v1.15 §5.1.3, inbound `<eb:Timestamp>` values outside
/// ±5 minutes of the current time MUST be rejected.
pub const TIMESTAMP_FRESHNESS_WINDOW_SECS: u64 = 300;
// ── Payload media type ────────────────────────────────────────────────────────
/// `<eb:PartInfo>/@MimeType` for the EDIFACT payload part.
///
/// BDEW AS4-Profil v1.2 §2.2.3.2: because compression is mandatory in this
/// profile the payload is carried as binary in its own MIME part with
/// Content-Type `application/octet-stream`, never in the SOAP Body — which
/// this profile requires to be empty.
///
/// This must be stated explicitly on every send. `asx-rs` defaults an unset
/// media type to `application/xml` **whenever encryption is on**, and BDEW
/// encrypts unconditionally (§2.2.6.2.2), so leaving it unset would label an
/// EDIFACT interchange as XML on the wire.
pub const PAYLOAD_MIME_TYPE: &str = "application/octet-stream";
// ── Tests ─────────────────────────────────────────────────────────────────────