bc-csharp icon indicating copy to clipboard operation
bc-csharp copied to clipboard

TLS-PSK returns bad_record_mac while OpenSSL working

Open chrisandchris opened this issue 8 months ago • 1 comments

I create a new TLS-PSK client using the following code (credentials are changed). I Use BouncyCastle.Cryptography in v2.5.1

using Org.BouncyCastle.Tls;
using Org.BouncyCastle.Tls.Crypto.Impl.BC;
// ----
            var pskTlsClient = new PskTlsClient(
                new BcTlsCrypto(),
                new BasicTlsPskIdentity(
                    "foobar",
                    Encoding.UTF8.GetBytes("foobar")));
            var client = new TcpClient(configuration.Host, configuration.Port)
            {
                SendTimeout = timeout,
                ReceiveTimeout = timeout,
                SendBufferSize = bufferSize,
                ReceiveBufferSize = bufferSize,
            };

            var proto = new TlsClientProtocol(client.GetStream());
            proto.Connect(pskTlsClient);

            return client.GetStream();

It returns a bad_record_mac. The server (a Zabbix instance) logs

SSL routines::decryption failed or bad record mac: TLS write fatal alert "bad record mac

If i try to connect using OpenSSL 3.x, it works:

# openssl s_client -connect 127.0.0.1:10051 -psk_identity foobar -psk foobar -ciphersuites TLS_AES_128_GCM_SHA256 -debug
---
no peer certificate available
---
No client certificate CA names sent
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 351 bytes and written 895 bytes
Verification: OK
---
Reused, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)

What am I doing wrong and where could i make some adjustments? I triple-checked the credentials. If I use a regular TLS connection (without PSK) it works (I can send/receive data).

chrisandchris avatar Apr 02 '25 09:04 chrisandchris

A different mechanism is used for handling "external" PSKs in TLS 1.3 from the way they were handled in earlier TLS versions (as distinct key exchange types with corresponding cipher suites). The main thing is to implement/override GetExternalPsks in your TlsClient implementation (in theory also GetPskKeyExchangeModes but we only support psk_dhe_ke at the moment anyway). You don't particularly need to use/follow PskTlsClient unless you are trying to support pre-TLS 1.3 versions also.

The tests in Org.BouncyCastle.Tls.Tests include Tls13PskProtocolTest, which uses MockPskTls13Client and MockPskTls13Server, showing how PSKs are used in TLS 1.3.

peterdettman avatar Jun 10 '25 12:06 peterdettman