int aws_cryptosdk_enc_ctx_deserialize()

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