2

Trying to implement TPU Client over MsQuic. Here is my code:

var quicClient = await QuicConnection.ConnectAsync(new QuicClientConnectionOptions
{
    DefaultStreamErrorCode = 0x0A,
    DefaultCloseErrorCode = 0x0B,

    RemoteEndPoint = IPEndPoint.Parse(firstLeader.Item2.TpuQuic!),
    ClientAuthenticationOptions = new SslClientAuthenticationOptions
    {
        ClientCertificates = [mockedCert],
        ApplicationProtocols = [new SslApplicationProtocol("solana-tpu")],
        EnabledSslProtocols = SslProtocols.Tls13,
        TargetHost = "server",
    }
});
await using var streamSend = await quicClient.OpenOutboundStreamAsync(QuicStreamType.Unidirectional);

This code is failing with exception System.Net.Quic.QuicException: An internal error has occurred. Status code: QUIC_STATUS_HANDSHAKE_FAILURE. When I look further in Wireshark, I see slightly more informational error:

CONNECTION_CLOSE (Transport) Error code: CRYPTO_ERROR (Handshake Failure)
    Frame Type: CONNECTION_CLOSE (Transport) (0x000000000000001c)
    Error code: CRYPTO_ERROR (296)
    TLS Alert Description: Handshake Failure (40)
    Frame Type: 0
    Reason phrase Length: 48
    Reason phrase: peer is incompatible: NoSignatureSchemesInCommon

So I suppose, MsQuic doesn't provide such TLS Signature Algorithms, that Solana TPU Server use. There is signature algorithms from and cipher suites from my ClientHello:

Signature Hash Algorithms (12 algorithms)
    Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
    Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
    Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
    Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
    Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
    Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
    Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
    Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
    Signature Algorithm: ecdsa_sha1 (0x0203)
    Signature Algorithm: SHA1 DSA (0x0202)
    Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
    Signature Algorithm: ecdsa_secp521r1_sha512 (0x0603)

Cipher Suites (2 suites)
    Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
    Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)

So, what can I do with it? As I can see, there is no other Quic implementations/binders (that are not outdated) in C#.

Or maybe something with my cert? I generated it once via nodejs':

import selfsigned from 'selfsigned';
const pems = selfsigned.generate([{name: 'commonName', value: 'Solana node'}, { name: "subjectAltName", value: [{ type: 7, value: "0.0.0.0" }]}], { days: 365, algorithm: 'ed25519', keySize: 2048 });

and combined it into one pfx like this:

openssl pkcs12 -export -in certificate.pem -inkey privatekey.pem -out cert-and-key.pfx

and impoting in C# like this:

var mockedCert = new X509Certificate2(@"C:\cert-and-key.pfx");

(.NET doesn't natively support Ed25519 yet)

1 Answer 1

1

This is a guess, since it's on the edge of my experience, but I think you're right about the cert being in an incorrect format. There's some very particular manipulating of the ed25519 keypair to convert it to DER.

You'll likely need to reimplement the logic at https://github.com/anza-xyz/agave/blob/990f938a718d4bcc791e26002a5475a233afa4c8/streamer/src/tls_certificates.rs#L6, or you can compile and run just that code against your ed25519 keypair.

I hope you get this to work!

1
  • Hello! Thanks for the answer. Unfortunately, I already tried this, it won't help. Same cert works for nodejs code but not for .NET
    – Temnij
    Commented Nov 1 at 13:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.