static int s_sign_message()

in source/windows/bcrypt_ecc.c [85:139]


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

    size_t output_buf_space = signature_output->capacity - signature_output->len;

    if (output_buf_space < s_signature_length(key_pair)) {
        return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
    }

    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));
    size_t signature_length = temp_signature_buf.capacity;

    NTSTATUS status = BCryptSignHash(
        key_impl->key_handle,
        NULL,
        message->ptr,
        (ULONG)message->len,
        temp_signature_buf.buffer,
        (ULONG)signature_length,
        (ULONG *)&signature_length,
        0);

    if (status != 0) {
        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
    }

    temp_signature_buf.len += signature_length;
    size_t coordinate_len = temp_signature_buf.len / 2;

    /* okay. Windows doesn't DER encode this to ASN.1, so we need to do it manually. */
    struct aws_der_encoder *encoder =
        aws_der_encoder_new(key_pair->allocator, signature_output->capacity - signature_output->len);
    if (!encoder) {
        return AWS_OP_ERR;
    }

    aws_der_encoder_begin_sequence(encoder);
    struct aws_byte_cursor integer_cur = aws_byte_cursor_from_array(temp_signature_buf.buffer, coordinate_len);
    aws_der_encoder_write_integer(encoder, integer_cur);
    integer_cur = aws_byte_cursor_from_array(temp_signature_buf.buffer + coordinate_len, coordinate_len);
    aws_der_encoder_write_integer(encoder, integer_cur);
    aws_der_encoder_end_sequence(encoder);

    struct aws_byte_cursor signature_out_cur;
    AWS_ZERO_STRUCT(signature_out_cur);
    aws_der_encoder_get_contents(encoder, &signature_out_cur);
    aws_byte_buf_append(signature_output, &signature_out_cur);
    aws_der_encoder_destroy(encoder);

    return AWS_OP_SUCCESS;
}