If we were to add a feature to help the use-case, we'd need to decide on the scope.
The alternatives I see: (a) validate the expiration of self-signed certificates used for authentication purposes only (b) broaden the feature. Disallow all expired trust anchors.This which would include (a) but would also catch cases where, say a, a private CA is used carelessly: the root-CA certificate is allowed to expire before certificates issued from it. (c) do nothing more. QPID-7869 has already added altering for out of date certificates within the trust stores. perhaps this is enough. I think any new feature would be optional and turned off by default. This is for the sake of backward compatibility. Turning to implementation: For (a) we would simply change the X509TrustManagers#checkClientTrusted to call X509Certificate#checkValidity() on all certificates in the peer's chain. The CertificateExpiredException would halt the connection. For (b), I see two implementation options: 1) Exclude expired certificates from the truststore. Currently the TrustManagers are generated once and reused by the Ports.This would need to change: either TrustManagers could be generated on-the-fly for each connection (not sure about the cost), or the TrustManagers could be periodically refreshed (there would be a race, of course). 2) Have X509TrustManagers#checkClientTrusted check the TrustAnchor's validity. Unfortunately, the JCA doesn't expose the full certification path to the application until after the TLS handshake is completed. To have X509TrustManagers#checkClientTrusted check the TrustAnchor's validity, it is necessary to recompute the certification path. I have checked this approach is feasible (proof of concept patch attached to QPID-7868). I want to mention what the client would see,. With the CPP Broker/NSS a TLS alert "certificate_expired" goes over the wire. Unfortunately, Oracle's coding of the JCA means that if a X509TrustManager#checkClientTrusted throws an CertificateException or sub-class, the TLS alert that goes over the wire is always "certificate_unknown" regardless of underlying cause. The code in question is sun.security.ssl.ServerHandshaker#clientCertificate(). The class is final and the whole piece seems to be unpluggable. I don't see a reasonable way around this. I am in favour of feature (b) as this feels more generally useful. I prefer implementation option 2). Thoughts? Alternatives? Keith. On 2 August 2017 at 11:50, Keith W <keith.w...@gmail.com> wrote: > Hello > > Martin Krasa raised JIRA QPID-7867 [1] on 21st July. As the JIRA > possibly eluded to a potential security issue, the initial discussion > was held in private on the Qpid private / Apache security lists. We > have now reached a point where there is a agreement that there is no > security issue as such. We might however added a feature to the Java > Broker to benefit this use-case. > > I don't wish to cross-post the private conversation verbatim. Instead > I will try and summerise the issue and the background as I understand > it. > > use-case/issue: > > The use-case is a development one, It involves a mutually > authenticated TLS connection for messaging from the Qpid JMS Client to > the Java Broker. Both client and server were using self signed > certificates and those certificates had expired The complaint was > that connection succeeded even though the certificates had expired. > The user was comparing behaviour with the CPP Broker which disallowed > such connections. > > background: > > Both the Java Broker and Qpid JMS Client rely on the inbuilt features > of Java JCA for the purpose of establishing trust during a TLS > handshake. Java treats certificates in the truststore store as > trust anchors. During an TLS handshake, the Java builds a certificate > chain from the certificate(s) provided by the peer over the wire to a > trust anchor in the store. If the chain can be formed, the > certificates that comprise the chain are subject to checks (such as an > expiration), but these checks are *not* applied to the trust anchor > itself. This behaviour seems to me to consistent with RFC5280 [4]. > > In use-cases involving self-signed certificates, the certificate is > installed in the peer's truststore. and as such the self signed > certificate is itself the trust anchor. When the remote side > connects and presents the self signed cert, this matches the trust > anchor stored and connection forms without expiration exception. > > I hope this is reasonable summary. Please feel free to correct or clarify. > I plan to post again later today with my ideas for changes we could > make to the Java Broker to help this use-case. > > Keith,. > > [1] https://issues.apache.org/jira/browse/QPID-7867 > [2] > https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html > [3] > https://docs.oracle.com/javase/8/docs/api/java/security/cert/package-summary.html > [4] http://www.ietf.org/rfc/rfc5280.txt --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org For additional commands, e-mail: users-h...@qpid.apache.org