in source/enc_ctx.c [131:188]
int aws_cryptosdk_enc_ctx_deserialize(
struct aws_allocator *alloc, struct aws_hash_table *enc_ctx, struct aws_byte_cursor *cursor) {
AWS_PRECONDITION(aws_allocator_is_valid(alloc));
AWS_PRECONDITION(aws_hash_table_is_valid(enc_ctx));
AWS_PRECONDITION(aws_byte_cursor_is_valid(cursor));
aws_cryptosdk_enc_ctx_clear(enc_ctx);
if (cursor->len == 0) {
AWS_POSTCONDITION(aws_allocator_is_valid(alloc));
AWS_POSTCONDITION(aws_hash_table_is_valid(enc_ctx));
AWS_POSTCONDITION(aws_byte_cursor_is_valid(cursor));
return AWS_OP_SUCCESS;
}
uint16_t elem_count;
if (!aws_byte_cursor_read_be16(cursor, &elem_count)) goto SHORT_BUF;
if (!elem_count) return aws_raise_error(AWS_CRYPTOSDK_ERR_BAD_CIPHERTEXT);
for (uint16_t i = 0; i < elem_count; i++) {
uint16_t len;
if (!aws_byte_cursor_read_be16(cursor, &len)) goto SHORT_BUF;
struct aws_byte_cursor k_cursor = aws_byte_cursor_advance_nospec(cursor, len);
if (!k_cursor.ptr) goto SHORT_BUF;
if (!aws_byte_cursor_read_be16(cursor, &len)) goto SHORT_BUF;
struct aws_byte_cursor v_cursor = aws_byte_cursor_advance_nospec(cursor, len);
if (!v_cursor.ptr) goto SHORT_BUF;
struct aws_string *k = aws_string_new_from_array(alloc, k_cursor.ptr, k_cursor.len);
struct aws_string *v = aws_string_new_from_array(alloc, v_cursor.ptr, v_cursor.len);
int was_created;
if (!k || !v || aws_hash_table_put(enc_ctx, k, (void *)v, &was_created)) {
// Errors here are only on memory allocation. aws-c-common will raise the error code
aws_string_destroy(k);
aws_string_destroy(v);
goto RETHROW;
}
if (!was_created) {
// !was_created means there was a duplicate key in serialized encryption context, so fail
aws_raise_error(AWS_CRYPTOSDK_ERR_BAD_CIPHERTEXT);
goto RETHROW;
}
}
return AWS_OP_SUCCESS;
SHORT_BUF:
aws_raise_error(AWS_ERROR_SHORT_BUFFER);
RETHROW:
aws_cryptosdk_enc_ctx_clear(enc_ctx);
AWS_POSTCONDITION(aws_allocator_is_valid(alloc));
AWS_POSTCONDITION(aws_hash_table_is_valid(enc_ctx));
AWS_POSTCONDITION(aws_byte_cursor_is_valid(cursor));
return AWS_OP_ERR;
}