Vulnerability in BC (D)TLS server, fix in new beta release 1.51b12

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
Report Content as Inappropriate

Vulnerability in BC (D)TLS server, fix in new beta release 1.51b12

David Hook

Hi All,

With thanks to Andreas Ritter, we have been made aware of a serious
vulnerability for anyone using our TLS server implementation with
client-authentication enabled. The verification checks are broken in
releases up to and including 1.51b11, and _fail silently_.

By default, we have not enabled client-auth, but it is possible that
users are already overriding TlsServer.getCertificateRequest in a
similar way to our unit tests, thinking it works, and therefore may be

- Affects any DTLS or TLS implementation (at any protocol version) that
is overriding TlsServer.getCertificateRequest() to prompt the client to
- Fails silently, allowing any client to "authenticate" by mere
possession of a valid certificate.
- DTLS or TLS client code is not affected.
- The C# TLS API does not yet support server-side operation and so is

We have now fixed the silent failure problem, and completed the client-auth
server-side implementation for (D)TLS 1.2 (thanks Andreas Ritter again
for patch), and added test coverage for various client-auth scenarios,
including expected failure cases. These changes are all available now in
BC beta release 1.51b12 (http://www.downloads.bouncycastle.org/betas).

If you are affected by this, as in you are relying on client-auth, we
recommend you to upgrade to this beta release. A full release will
follow in May.

If you are unable to upgrade _do not_ use client-auth unless you are
using a work around. As mentioned earlier client-auth is disabled by
(TlsServer.getCertificateRequest returns null, and that is the default).

There is a workaround that can be used with 1.50 if you are using a TLS
(not DTLS) server at version 1.1 or earlier (i.e. not TLS 1.2), by
overriding the receiveCertificateVerifyMessage as follows:

         TlsServerProtocol serverProtocol = new TlsServerProtocol(...)
             protected void
receiveCertificateVerifyMessage(ByteArrayInputStream buf)
                 throws IOException
                 DigitallySigned clientCertificateVerify =
DigitallySigned.parse(getContext(), buf);


                 if (TlsUtils.isTLSv12(getContext()))
                     throw new

                 // Verify the CertificateVerify message contains a
correct signature.
                 boolean verified = false;
                     byte[] certificateVerifyHash =
                         prepareFinishHash, null);

                     org.bouncycastle.asn1.x509.Certificate x509Cert =
                     SubjectPublicKeyInfo keyInfo =
                     AsymmetricKeyParameter publicKey =

                     TlsSigner tlsSigner =
                     verified =
publicKey, certificateVerifyHash);
                 catch (Exception e)

                 if (!verified)
                     throw new

If you use this workaround or another of your own devising, please take
extra care to test client-auth failure scenarios.

We welcome questions to [hidden email] if you would
rather not ask on the public list.


Pete Dettman (via David Hook)