fromWire static method
Parses a SecureMessage
from wire headers/body.
headers
must contain keys: "version","window","nonce","ciphertext" (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 versionStr = headers['version'];
final windowStr = headers['window'];
final nonceStr = headers['nonce'];
final ciphertextStr = headers['ciphertext'];
if (versionStr == null || windowStr == null || nonceStr == null || ciphertextStr == null) {
throw ArgumentError('missing required headers v/w/n/c');
}
// Parse integers (version, window). Reject non-integers / negatives.
final version = int.parse(versionStr);
final window = int.parse(windowStr);
if (version < 1) {
throw ArgumentError.value(version, 'version', 'Protocol version must be >= 1.');
}
if (window < 0) {
throw ArgumentError.value(window, 'window', 'Window must be non-negative.');
}
// Decode Base64 fields.
final nonce = Bytes.fromBase64Strict(nonceStr);
final ciphertext = Bytes.fromBase64Strict(ciphertextStr);
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(
version: version,
window: window,
nonce: nonce,
ciphertext: ciphertext,
tag: tag,
);
} catch (e, st) {
throw InvalidMessageException(cause: e, stackTrace: st);
}
}