Windows `ED25519` Unsupported Algorithm
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
ringandaws-lc-rsbackend. - This failure is specific for Windows operative system
Questions
- Is
ED25519actually supported on Windows? - If not, should it be removed from
supported_verify_schemes()?
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.
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:
-
Is this a fundamental limitation where
ED25519is simply not supported by the Windows certificate verification infrastructure, making removal from the supported schemes list the correct approach? -
Or is this potentially a configuration/setup issue where
ED25519could 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)
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.
@ctz I would appreciate some clarification on the ways
rustlsitself usessupported_verify_schemessince I'm not an expert on the TLS protocol side, if you don't mind.From what I remember, the reason why all the
ServerCertVerifierimplementations 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.)
It should be validated, but from a quick experiment it seems the same happens on MacOS