rustls-platform-verifier icon indicating copy to clipboard operation
rustls-platform-verifier copied to clipboard

Windows `ED25519` Unsupported Algorithm

Open BiagioFesta opened this issue 2 months ago • 5 comments

Description

When attempting to verify an ED25519 certificate on Windows, the verification fails with an "Invalid algorithm specified" error, despite ED25519 being listed in the supported verification schemes.

Code to Reproduce

use rustls::client::danger::ServerCertVerifier;
use rustls_platform_verifier::Verifier;
use std::sync::Arc;

const SERVER_NAME: &str = "my-test";

fn main() {
    let certificate = generate_certificate();

    let crypto_provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
    let verifier = Verifier::new(crypto_provider).unwrap();

    println!(
        "Supported schemes: {:?}",
        verifier.supported_verify_schemes()
    );

    let result = verifier.verify_server_cert(
        &certificate,
        &[],
        &SERVER_NAME.try_into().unwrap(),
        &[],
        rustls::pki_types::UnixTime::now(),
    );

    println!("Verify result: {result:?}");
}

fn generate_certificate() -> rustls::pki_types::CertificateDer<'static> {
    let key_pair = rcgen::KeyPair::generate_for(&rcgen::PKCS_ED25519).unwrap();

    let cert = rcgen::CertificateParams::new(vec![SERVER_NAME.to_string()])
        .unwrap()
        .self_signed(&key_pair)
        .unwrap();

    cert.der().to_owned()
}

Output

$ cargo run --example mytest

Supported schemes: [ECDSA_NISTP384_SHA384, ECDSA_NISTP256_SHA256, ECDSA_NISTP521_SHA512, ED25519, RSA_PSS_SHA512, RSA_PSS_SHA384, RSA_PSS_SHA256, RSA_PKCS1_SHA512, RSA_PKCS1_SHA384, RSA_PKCS1_SHA256]
Verify result: Err(General("Invalid algorithm specified. (os error -2146893816)"))

Current Behavior

  • ED25519 is listed in supported_verify_schemes()
  • Verification fails with error: General("Invalid algorithm specified. (os error -2146893816)")
  • The error seems to occur during chain construction (CertGetCertificateChain)

Additional Notes

  • The result is the same with both ring and aws-lc-rs backend.
  • This failure is specific for Windows operative system

Questions

  • Is ED25519 actually supported on Windows?
  • If not, should it be removed from supported_verify_schemes()?

BiagioFesta avatar Sep 29 '25 20:09 BiagioFesta

I think the main thing to do here is (aside from removing ED25519 from the windows verifier's list) is to test a chain on each platform for each item in that platform's supported_verify_schemes(). Theoretically that could be one test with one big heterogeneous chain, but probably it would be clearer to a homogeneous chain per offered scheme.

ctz avatar Sep 30 '25 13:09 ctz

Thanks for the response. As I'm not too familiar with Windows internals (I am not a Windows guy), I'd like to clarify the underlying issue to help guide a potential PR:

  1. Is this a fundamental limitation where ED25519 is simply not supported by the Windows certificate verification infrastructure, making removal from the supported schemes list the correct approach?

  2. Or is this potentially a configuration/setup issue where ED25519 could work on Windows with additional steps (e.g., specific Windows API configurations or prerequisites)?

(Beside the correct suggestion of improve the code test for this part)

BiagioFesta avatar Sep 30 '25 21:09 BiagioFesta

Is this a fundamental limitation where ED25519 is simply not supported by the Windows certificate verification infrastructure, making removal from the supported schemes list the correct approach?

@BiagioFesta Yes, Windows doesn't support Ed25519 at all in the platform cryptography libraries. I'm trying to gather a bit more information before assuming removing it from the list is the correct path though.


@ctz I would appreciate some clarification on the ways rustls itself uses supported_verify_schemes since I'm not an expert on the TLS protocol side, if you don't mind.

From what I remember, the reason why all the ServerCertVerifier implementations claim support for all of the algorithms as the underlying cryptographic provider is because it was assumed this was for TLS handshake signature verification only, not for checking the signature lists during certificate chainbuilding.

So in this scenario, we would be correctly advertising that we can handle validating the session signature using the certificate's private Ed25519 key but once that certificate is passed into Windows the OS falls over because it doesn't know how to parse an X.509 certificate with an Ed25519 public key inside it.

complexspaces avatar Oct 22 '25 03:10 complexspaces

@ctz I would appreciate some clarification on the ways rustls itself uses supported_verify_schemes since I'm not an expert on the TLS protocol side, if you don't mind.

From what I remember, the reason why all the ServerCertVerifier implementations claim support for all of the algorithms as the underlying cryptographic provider is because it was assumed this was for TLS handshake signature verification only, not for checking the signature lists during certificate chainbuilding.

Unfortunately it's both, and there's no way in TLS1.2 to say "I support ED25519 for verifying the handshake signature, but not for chain building". There was a way to do that added in TLS1.3, but I don't think it will help in this case (sidebar: it allows a separate specification of which schemes can be used for chain building, but that special cut-out will be ignored if TLS1.2 is negotiated so we're back where we are now.)

ctz avatar Oct 24 '25 12:10 ctz

It should be validated, but from a quick experiment it seems the same happens on MacOS

BiagioFesta avatar Nov 07 '25 18:11 BiagioFesta