open method
Verifies and decrypts box. Throws AuthenticationException on any
mismatch of key, nonce, AAD, ciphertext or tag.
Implementation
Uint8List open(List<int> nonce, SealedBox box, {List<int> aad = const []}) {
initNoConfig();
if (box.tag.length != tagLength) {
throw const AuthenticationException();
}
return using((arena) {
final ctx = _newCtx(arena, nonce, encrypt: false);
try {
final outl = arena<Int>();
if (aad.isNotEmpty) {
checkOne(
ssl.EVP_DecryptUpdate(
ctx,
nullptr,
outl,
toNative(arena, aad),
aad.length,
),
'EVP_DecryptUpdate(aad)',
);
}
// Holds unauthenticated plaintext until the tag verifies; wiped on
// release whether or not it did.
final out = secretBuffer(arena, box.ciphertext.length + 16);
var produced = 0;
if (box.ciphertext.isNotEmpty) {
checkOne(
ssl.EVP_DecryptUpdate(
ctx,
out,
outl,
toNative(arena, box.ciphertext),
box.ciphertext.length,
),
'EVP_DecryptUpdate',
);
produced = outl.value;
}
checkOne(
ssl.EVP_CIPHER_CTX_ctrl(
ctx,
ssl.EVP_CTRL_AEAD_SET_TAG,
tagLength,
toNative(arena, box.tag).cast(),
),
'EVP_CIPHER_CTX_ctrl(SET_TAG)',
);
final ok = ssl.EVP_DecryptFinal_ex(ctx, out + produced, outl);
if (ok != 1) {
ssl.ERR_clear_error();
throw const AuthenticationException();
}
produced += outl.value;
return fromNative(out, produced);
} finally {
ssl.EVP_CIPHER_CTX_free(ctx);
}
});
}