fromWire static method

SecureMessage fromWire({
  1. required Map<String, String> headers,
  2. required String body,
})

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);
  }
}