static int s_verify_signature()

in source/windows/bcrypt_ecc.c [180:253]


static int s_verify_signature(
    const struct aws_ecc_key_pair *key_pair,
    const struct aws_byte_cursor *message,
    const struct aws_byte_cursor *signature) {
    struct bcrypt_ecc_key_pair *key_impl = key_pair->impl;

    /* OKAY Windows doesn't do the whole standard internet formats thing. So we need to manually decode
       the DER encoded ASN.1 format first.*/
    uint8_t temp_signature[MAX_SIGNATURE_LENGTH] = {0};
    struct aws_byte_buf temp_signature_buf = aws_byte_buf_from_empty_array(temp_signature, sizeof(temp_signature));

    struct aws_byte_cursor der_encoded_signature = aws_byte_cursor_from_array(signature->ptr, signature->len);

    struct aws_der_decoder *decoder = aws_der_decoder_new(key_pair->allocator, der_encoded_signature);
    if (!decoder) {
        return AWS_OP_ERR;
    }

    if (!aws_der_decoder_next(decoder) || aws_der_decoder_tlv_type(decoder) != AWS_DER_SEQUENCE) {
        aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
        goto error;
    }

    if (!aws_der_decoder_next(decoder) || aws_der_decoder_tlv_type(decoder) != AWS_DER_INTEGER) {
        aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
        goto error;
    }

    /* there will be two coordinates. They need to be concatenated together. */
    struct aws_byte_cursor coordinate;
    AWS_ZERO_STRUCT(coordinate);
    if (aws_der_decoder_tlv_integer(decoder, &coordinate)) {
        aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
        goto error;
    }

    if (s_append_coordinate(&temp_signature_buf, &coordinate, key_pair->curve_name)) {
        goto error;
    }

    if (!aws_der_decoder_next(decoder) || aws_der_decoder_tlv_type(decoder) != AWS_DER_INTEGER) {
        aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
        goto error;
    }
    AWS_ZERO_STRUCT(coordinate);
    if (aws_der_decoder_tlv_integer(decoder, &coordinate)) {
        aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
        goto error;
    }

    if (s_append_coordinate(&temp_signature_buf, &coordinate, key_pair->curve_name)) {
        goto error;
    }

    aws_der_decoder_destroy(decoder);

    /* okay, now we've got a windows compatible signature, let's verify it. */
    NTSTATUS status = BCryptVerifySignature(
        key_impl->key_handle,
        NULL,
        message->ptr,
        (ULONG)message->len,
        temp_signature_buf.buffer,
        (ULONG)temp_signature_buf.len,
        0);

    return status == 0 ? AWS_OP_SUCCESS : aws_raise_error(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED);

error:
    if (decoder) {
        aws_der_decoder_destroy(decoder);
    }
    return AWS_OP_ERR;
}