/** * Allow the Listener a chance to customise the request. before the server does its stuff. <br> * This allows the required attributes to be set for SSL requests. <br> * The requirements of the Servlet specs are: * * <ul> * <li>an attribute named "javax.servlet.request.cipher_suite" of type String. * <li>an attribute named "javax.servlet.request.key_size" of type Integer. * <li>an attribute named "javax.servlet.request.X509Certificate" of type * java.security.cert.X509Certificate[]. This is an array of objects of type * X509Certificate, the order of this array is defined as being in ascending order of trust. * The first certificate in the chain is the one set by the client, the next is the one used * to authenticate the first, and so on. * </ul> * * @param socket The Socket the request arrived on. This should be a javax.net.ssl.SSLSocket. * @param request HttpRequest to be customised. */ protected void customizeRequest(Socket socket, HttpRequest request) { super.customizeRequest(socket, request); if (!(socket instanceof javax.net.ssl.SSLSocket)) return; // I'm tempted to let it throw an exception... try { SSLSocket sslSocket = (SSLSocket) socket; SSLSession sslSession = sslSocket.getSession(); String cipherSuite = sslSession.getCipherSuite(); Integer keySize; X509Certificate[] certs; CachedInfo cachedInfo = (CachedInfo) sslSession.getValue(CACHED_INFO_ATTR); if (cachedInfo != null) { keySize = cachedInfo.getKeySize(); certs = cachedInfo.getCerts(); } else { keySize = new Integer(ServletSSL.deduceKeyLength(cipherSuite)); certs = getCertChain(sslSession); cachedInfo = new CachedInfo(keySize, certs); sslSession.putValue(CACHED_INFO_ATTR, cachedInfo); } if (certs != null) request.setAttribute("javax.servlet.request.X509Certificate", certs); else if (_needClientAuth) // Sanity check throw new HttpException(HttpResponse.__403_Forbidden); request.setAttribute("javax.servlet.request.cipher_suite", cipherSuite); request.setAttribute("javax.servlet.request.key_size", keySize); } catch (Exception e) { log.warn(LogSupport.EXCEPTION, e); } }
/** * javax.net.ssl.SSLSession#putValue(String name, Object value) * javax.net.ssl.SSLSession#removeValue(String name) javax.net.ssl.SSLSession#getValueNames() */ public void test_putValue() { SSLSession s = clientSession; mySSLSessionBindingListener sbl = new mySSLSessionBindingListener(); assertNotNull(s.getValueNames()); assertEquals(0, s.getValueNames().length); s.putValue("Name_01", sbl); s.putValue("Name_02", sbl); s.putValue("Name_03", sbl); assertEquals(3, s.getValueNames().length); s.removeValue("Name_01"); assertEquals(2, s.getValueNames().length); try { s.putValue(null, null); fail("IllegalArgumentException wasn't thrown"); } catch (IllegalArgumentException expected) { // expected } try { s.putValue("ABC", null); fail("IllegalArgumentException wasn't thrown"); } catch (IllegalArgumentException expected) { // expected } try { s.putValue(null, sbl); fail("IllegalArgumentException wasn't thrown"); } catch (IllegalArgumentException expected) { // expected } try { s.removeValue(null); fail("IllegalArgumentException wasn't thrown"); } catch (IllegalArgumentException expected) { // expected } }
/** javax.net.ssl.SSLSession#getValue(String name) */ public void test_getValue() { SSLSession s = clientSession; mySSLSessionBindingListener sbl = new mySSLSessionBindingListener(); try { s.getValue(null); fail("IllegalArgumentException wasn't thrown"); } catch (IllegalArgumentException expected) { // expected } s.putValue("Name", sbl); Object obj = s.getValue("Name"); assertTrue(obj instanceof SSLSessionBindingListener); }
/** * Customizes the request attributes to be set for SSL requests. * * <p>The requirements of the Servlet specs are: * * <ul> * <li>an attribute named "javax.servlet.request.ssl_session_id" of type String (since Servlet * Spec 3.0). * <li>an attribute named "javax.servlet.request.cipher_suite" of type String. * <li>an attribute named "javax.servlet.request.key_size" of type Integer. * <li>an attribute named "javax.servlet.request.X509Certificate" of type * java.security.cert.X509Certificate[]. This is an array of objects of type * X509Certificate, the order of this array is defined as being in ascending order of trust. * The first certificate in the chain is the one set by the client, the next is the one used * to authenticate the first, and so on. * </ul> * * @param sslEngine the sslEngine to be customized. * @param request HttpRequest to be customized. */ protected void customize(SSLEngine sslEngine, Request request) { SSLSession sslSession = sslEngine.getSession(); if (_sniHostCheck) { String name = request.getServerName(); X509 x509 = (X509) sslSession.getValue(SniX509ExtendedKeyManager.SNI_X509); if (x509 != null && !x509.matches(name)) { LOG.warn("Host {} does not match SNI {}", name, x509); throw new BadMessageException(400, "Host does not match SNI"); } if (LOG.isDebugEnabled()) LOG.debug("Host {} matched SNI {}", name, x509); } try { String cipherSuite = sslSession.getCipherSuite(); Integer keySize; X509Certificate[] certs; String idStr; CachedInfo cachedInfo = (CachedInfo) sslSession.getValue(CACHED_INFO_ATTR); if (cachedInfo != null) { keySize = cachedInfo.getKeySize(); certs = cachedInfo.getCerts(); idStr = cachedInfo.getIdStr(); } else { keySize = SslContextFactory.deduceKeyLength(cipherSuite); certs = SslContextFactory.getCertChain(sslSession); byte[] bytes = sslSession.getId(); idStr = TypeUtil.toHexString(bytes); cachedInfo = new CachedInfo(keySize, certs, idStr); sslSession.putValue(CACHED_INFO_ATTR, cachedInfo); } if (certs != null) request.setAttribute("javax.servlet.request.X509Certificate", certs); request.setAttribute("javax.servlet.request.cipher_suite", cipherSuite); request.setAttribute("javax.servlet.request.key_size", keySize); request.setAttribute("javax.servlet.request.ssl_session_id", idStr); } catch (Exception e) { LOG.warn(Log.EXCEPTION, e); } }