Explain exact encrypted container rejection reasons
This commit is contained in:
1 parent
8a46a53a21
commit
1896a19eba
1 file changed
+22
-7
@@ -114,22 +114,37 @@ int encrypted_file_read(const char* source, const char* destination, const uint8
|
||||
uint8_t actual[32], header[EF_HEADER], meta[EF_META], cipher[EF_META + 16], nonce[13];
|
||||
size_t length = 0;
|
||||
uint64_t size = 0;
|
||||
if (!source || !destination || !strcmp(source, destination) || !key || !author || !id || !hash || !info || !type ||
|
||||
ma_sha256_file(source, actual) || CRYPTO_memcmp(actual, hash, 32)) goto done;
|
||||
const char* reason = "invalid arguments";
|
||||
if (!source || !destination || !strcmp(source, destination) || !key || !author || !id || !hash || !info || !type) goto done;
|
||||
reason = "cannot hash ciphertext";
|
||||
if (ma_sha256_file(source, actual)) goto done;
|
||||
reason = "ciphertext does not match signed manifest hash";
|
||||
if (CRYPTO_memcmp(actual, hash, 32)) goto done;
|
||||
reason = "cannot open ciphertext or truncated header";
|
||||
in = fopen(source, "rb");
|
||||
if (!in || fread(header, 1, sizeof(header), in) != sizeof(header) || memcmp(header, "UTENC001", 8) ||
|
||||
memcmp(header + 8, id, 16)) goto done;
|
||||
if (!in || fread(header, 1, sizeof(header), in) != sizeof(header)) goto done;
|
||||
reason = "unsupported container format or mismatched UUID";
|
||||
if (memcmp(header, "UTENC001", 8) || memcmp(header + 8, id, 16)) goto done;
|
||||
size_t encrypted_size = ((size_t)header[32] << 8) | header[33];
|
||||
reason = "invalid metadata length or truncated metadata";
|
||||
if (encrypted_size < 32 + 11 + 16 || encrypted_size > sizeof(cipher) ||
|
||||
fread(cipher, 1, encrypted_size, in) != encrypted_size) goto done;
|
||||
media_cipher_nonce(author, id, UINT64_MAX, nonce);
|
||||
if (media_ccm_decrypt(key, nonce, cipher, encrypted_size, meta, &length) || length < 32 ||
|
||||
reason = "metadata authentication failed";
|
||||
if (media_ccm_decrypt(key, nonce, cipher, encrypted_size, meta, &length)) goto done;
|
||||
reason = "invalid attachment metadata";
|
||||
if (length < 32 ||
|
||||
!memchr(meta, 0, 32) || !meta[0] || attachment_decode(meta + 32, length - 32, info)) goto done;
|
||||
reason = "invalid content type";
|
||||
for (unsigned i = 0; i < 32 && meta[i]; i++) if (meta[i] < 33 || meta[i] > 126 || meta[i] == '"' || meta[i] == '\\') goto done;
|
||||
memcpy(type, meta, 32);
|
||||
for (unsigned i = 0; i < 8; i++) size = (size << 8) | header[24 + i];
|
||||
out = fopen(destination, "wb");
|
||||
if (!out || media_decrypt_stream(key, author, id, size, header + 34, in, out)) goto done;
|
||||
reason = "cannot open temporary plaintext";
|
||||
if (!out) goto done;
|
||||
reason = "file authentication, size or body hash failed";
|
||||
if (media_decrypt_stream(key, author, id, size, header + 34, in, out)) goto done;
|
||||
reason = "close or durable file sync failed";
|
||||
rc = 0;
|
||||
done:
|
||||
OPENSSL_cleanse(meta, sizeof(meta));
|
||||
@@ -137,7 +152,7 @@ done:
|
||||
if (out && fclose(out)) rc = -1;
|
||||
if (!rc) rc = encrypted_file_sync(destination);
|
||||
if (rc) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: verification/decryption failed source=%s", source ? source : "?");
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted file: rejected source=%s reason=%s", source ? source : "?", reason);
|
||||
if (out && remove(destination) && errno != ENOENT) DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "encrypted file: rejected output cleanup failed");
|
||||
} else DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "encrypted file: verified author=%llu bytes=%llu", (unsigned long long)author,
|
||||
(unsigned long long)size);
|
||||
|
||||
Reference in new issue
Block a user