fromWire static method
Parses a SecureMessage from wire headers/body.
headers must contain keys: "v","w","n","c" (all strings).
body must be the Base64-encoded tag string.
Throws InvalidMessageException on missing fields, bad integers/base64, nonce length != 8, or empty ciphertext.
HINT: This is a format parser only; MAC verification is done elsewhere.
Implementation
static SecureMessage fromWire({
required Map<String, String> headers,
required String body,
}) {
try {
// -- Required header fields -------------------------------------------
final vStr = headers['v'];
final wStr = headers['w'];
final nStr = headers['n'];
final cStr = headers['c'];
if (vStr == null || wStr == null || nStr == null || cStr == null) {
throw ArgumentError('missing required headers v/w/n/c');
}
// Parse integers (v,w). Reject non-integers / negatives.
final v = int.parse(vStr);
final w = int.parse(wStr);
if (v < 1) {
throw ArgumentError.value(v, 'v', 'Protocol version must be >= 1.');
}
if (w < 0) {
throw ArgumentError.value(w, 'w', 'Window must be non-negative.');
}
// Decode Base64 fields.
final nonce = Bytes.fromBase64Strict(nStr);
final ciphertext = Bytes.fromBase64Strict(cStr);
final tag = Bytes.fromBase64Strict(body);
// Enforce lengths.
NonceGenerator.validate(nonce);
if (ciphertext.isEmpty) {
throw ArgumentError('ciphertext must not be empty.');
}
if (tag.length != 32) {
throw ArgumentError.value(tag.length, 'tag.length', 'HMAC-SHA256 tag must be 32 bytes.');
}
return SecureMessage._internal(
v: v,
w: w,
nonce: nonce,
ciphertext: ciphertext,
tag: tag,
);
} catch (e, st) {
throw InvalidMessageException(cause: e, stackTrace: st);
}
}