Skip to main content

Crate mako_as4

Crate mako_as4 

Source
Expand description

BDEW MaKo AS4 profile for German energy market communication.

This crate encodes the BDEW AS4-Profil v1.2 requirements on top of asx_rs v0.13, providing:

§BDEW AS4-Profil v1.2 crypto requirements

RequirementAlgorithmSource
SigningECDSA-SHA256 + BrainpoolP256r1§2.2.6.2.1 / BSI TR-03116-3 §9.1
Signing tokenX509PKIPathv1 (BinarySecurityToken)§2.2.6.2.1
EncryptionECDH-ES + ConcatKDF + AES-128-GCM§2.2.6.2.2 / BSI TR-03116-3 §9.2
Key referenceX509SKI§2.2.6.2.2
EC curveBrainpoolP256r1 (both signing and encryption)BSI TR-03116-3

Both algorithms are auto-detected from the key/cert type — supply EC (BrainpoolP256r1) material and the correct paths are selected automatically.

§Signature scope

The BDEW profile requires PMode[1].Security.X509.Sign to be set “nach Maßgabe der Abschnitte 5.1.4 und 5.1.5 von [AS4]” (§2.2.6.2.1), and those sections put the eb:Messaging SOAP header block inside the signature.

The whole eb:Messaging block is signed, referenced by wsu:Id="as4-messaging". That scope is what makes the signature meaningful: PartyInfo, CollaborationInfo and Action are the routing and authorization metadata, so a signature covering only eb:MessageId would leave all of it tamperable.

On receive, the block the parser consumes is bound to the block the signature verified, so a relocated-but-still-resolvable signed element cannot be paired with an injected unsigned replacement (XML Signature Wrapping).

§Interop

Verification is strict in one direction: a receiver requiring the full block rejects a sender that signs less, while a receiver checking only that some signature verified accepts a conformant sender either way. Conformant partner stacks sign the block, so strict verification rejects only non-conformant senders.

§ECDH-ES key derivation

ConcatKDF uses the SP 800-56A raw-concatenation form — no keydatalen field, no JOSE-style length prefixes — which is what BSI TR-03116-3 §9.2 requires. The derivation determines the KEK, so a peer deriving it differently cannot decrypt the payload.

§Quick start

use mako_as4::{BdewAs4Profile, BdewAction, bdew_pmode, constants};

// Build a profile and register bilateral P-Modes for each trading partner
let mut profile = BdewAs4Profile::new();
profile
    .register_pmode(bdew_pmode("pm-utilmd-a", "9900000000001", BdewAction::Utilmd))
    .register_pmode(bdew_pmode("pm-aperak-a", "9900000000001", BdewAction::Aperak));

// Fail-fast at startup
profile.validate().expect("BDEW MaKo profile must satisfy all security invariants");

// Resolve a P-Mode at send time
let pm = profile.resolve_pmode(
    "9900000000001",
    constants::SERVICE,
    &BdewAction::Utilmd.as_uri(),
);
assert!(pm.is_some());

Re-exports§

pub use partner_directory::PartnerDirectory;
pub use partner_directory::PartnerDirectoryParseError;
pub use pmode::BdewAction;
pub use pmode::ParseBdewActionError;
pub use pmode::bdew_action_from_str;
pub use pmode::bdew_pmode;
pub use pmode::bdew_pmode_sign_only;
pub use pmode::bdew_pmode_with_endpoint;
pub use profile::BdewAs4Profile;
pub use profile::bdew_mako_profile_stack;
pub use profile::bdew_push_policy;

Modules§

constants
BDEW MaKo AS4 protocol constants.
partner_directory
BDEW MaKo trading-partner AS4 endpoint directory.
pmode
BDEW MaKo AS4 P-Mode types and factory functions.
profile
BDEW MaKo AS4 profile stack and BdewAs4Profile entry point.

Structs§

As4PushPolicy
PModeRegistry
Registry of P-Modes keyed by partner ID and service/action.