private ProxyLdapContext(Hashtable env) throws NamingException { final Map<String, Object> savedEnv = new HashMap<String, Object>(); for (final String key : Arrays.asList( Context.SECURITY_AUTHENTICATION, Context.SECURITY_CREDENTIALS, Context.SECURITY_PRINCIPAL, Context.SECURITY_PROTOCOL)) { final Object entry = env.remove(key); if (entry != null) { savedEnv.put(key, entry); } } delegate = new InitialLdapContext(env, null); tls = (StartTlsResponse) delegate.extendedOperation(new StartTlsRequest()); tls.setHostnameVerifier( new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); try { final SSLSession negotiate = tls.negotiate(); Logger.getLogger(this.getClass().getCanonicalName()) .fine("LDAP is now using " + negotiate.getProtocol()); } catch (final IOException e) { throw new NamingException(e.getMessage()); } for (final Map.Entry<String, Object> savedEntry : savedEnv.entrySet()) { delegate.addToEnvironment(savedEntry.getKey(), savedEntry.getValue()); } }
/** * 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); } }
public Certificate[] getLocalCertificates() { SSLSession sslSession = (SSLSession) ioSession.getAttribute(SslFilter.SSL_SESSION); if (sslSession != null) { return sslSession.getLocalCertificates(); } return new Certificate[0]; }
@Override public Object[] getPeerCertificateChain(boolean force) throws IOException, RemoteException { try { // Look up the current SSLSession if (session == null) return null; // Convert JSSE's certificate format to the ones we need X509Certificate[] jsseCerts = null; try { jsseCerts = session.getPeerCertificateChain(); } catch (Exception bex) { // ignore. } if (jsseCerts == null) jsseCerts = new X509Certificate[0]; if (jsseCerts.length <= 0 && force && ssl != null) { session.invalidate(); handShake(); session = ssl.getSession(); } return getX509Certificates(session); } catch (Exception excp) { excp.printStackTrace(); } return null; }
/* * Create and size the buffers appropriately. */ private void createBuffers() { /* * We'll assume the buffer sizes are the same * between client and server. */ SSLSession session = clientEngine.getSession(); int appBufferMax = session.getApplicationBufferSize(); int netBufferMax = session.getPacketBufferSize(); /* * We'll make the input buffers a bit bigger than the max needed * size, so that unwrap()s following a successful data transfer * won't generate BUFFER_OVERFLOWS. * * We'll use a mix of direct and indirect ByteBuffers for * tutorial purposes only. In reality, only use direct * ByteBuffers when they give a clear performance enhancement. */ clientIn = ByteBuffer.allocate(appBufferMax + 50); serverIn = ByteBuffer.allocate(appBufferMax + 50); cTOs = ByteBuffer.allocateDirect(netBufferMax); sTOc = ByteBuffer.allocateDirect(netBufferMax); clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes()); serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes()); }
private static void printConnectionInfo(SSLSocket s) { SSLSession currentSession = s.getSession(); System.out.println("Protocol: " + currentSession.getProtocol()); System.out.println("Cipher Suite: " + currentSession.getCipherSuite()); System.out.println("Host: " + currentSession.getPeerHost()); System.out.println("Host Port: " + currentSession.getPeerPort()); }
public static void main(String[] args) throws Exception { SSLContext sslContext = createSSLContext(); SSLServerSocketFactory fact = sslContext.getServerSocketFactory(); SSLServerSocket sSock = (SSLServerSocket) fact.createServerSocket(Utils.PORT_NO); // client authenticate where possible sSock.setWantClientAuth(true); for (; ; ) { SSLSocket sslSock = (SSLSocket) sSock.accept(); try { sslSock.startHandshake(); } catch (IOException e) { continue; } readRequest(sslSock.getInputStream()); SSLSession session = sslSock.getSession(); try { Principal clientID = session.getPeerPrincipal(); System.out.println("client identified as: " + clientID); } catch (SSLPeerUnverifiedException e) { System.out.println("client not authenticated"); } sendResponse(sslSock.getOutputStream()); sslSock.close(); } }
private void createBuffers() { SSLSession session = sslStateMachine.sslEngine.getSession(); appBufferMax = session.getApplicationBufferSize(); netBufferMax = session.getPacketBufferSize(); if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) { logger.logDebug("appBufferMax=" + appBufferMax + " netBufferMax=" + netBufferMax); } }
// Server identity checking is done according to RFC 2818: HTTP over TLS // Section 3.1 Server Identity private void checkURLSpoofing(HostnameVerifier hostnameVerifier) throws IOException { // // Get authenticated server name, if any // boolean done = false; String host = url.getHost(); // if IPv6 strip off the "[]" if (host != null && host.startsWith("[") && host.endsWith("]")) { host = host.substring(1, host.length() - 1); } Certificate[] peerCerts = null; try { // get the subject's certificate peerCerts = session.getPeerCertificates(); X509Certificate peerCert; if (peerCerts[0] instanceof java.security.cert.X509Certificate) { peerCert = (java.security.cert.X509Certificate) peerCerts[0]; } else { throw new SSLPeerUnverifiedException(""); } HostnameChecker checker = HostnameChecker.getInstance(HostnameChecker.TYPE_TLS); checker.match(host, peerCert); // if it doesn't throw an exception, we passed. Return. return; } catch (SSLPeerUnverifiedException e) { // // client explicitly changed default policy and enabled // anonymous ciphers; we can't check the standard policy // // ignore } catch (java.security.cert.CertificateException cpe) { // ignore } // Assume the peerCerts are already cloned. String cipher = session.getCipherSuite(); if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) { return; } else if ((hostnameVerifier != null) && (hostnameVerifier.verify(host, session))) { return; } serverSocket.close(); session.invalidate(); throw new IOException("HTTPS hostname wrong: should be <" + url.getHost() + ">"); }
public Certificate[] getPeerCertificates() { try { SSLSession sslSession = (SSLSession) ioSession.getAttribute(SslFilter.SSL_SESSION); if (sslSession != null) { return sslSession.getPeerCertificates(); } } catch (SSLPeerUnverifiedException e) { Log.warn("Error retrieving client certificates of: " + session, e); } return new Certificate[0]; }
private static void printSocketInfo(SSLSocket s) { LOGGER.info("Socket class: " + s.getClass()); LOGGER.info(" Remote address = " + s.getInetAddress().toString()); LOGGER.info(" Remote port = " + s.getPort()); LOGGER.info(" Local socket address = " + s.getLocalSocketAddress().toString()); LOGGER.info(" Local address = " + s.getLocalAddress().toString()); LOGGER.info(" Local port = " + s.getLocalPort()); LOGGER.info(" Need client authentication = " + s.getNeedClientAuth()); SSLSession ss = s.getSession(); LOGGER.info(" Cipher suite = " + ss.getCipherSuite()); LOGGER.info(" Protocol = " + ss.getProtocol()); }
@Override public void handshake(Socket sock) throws IOException { // We do getSession instead of startHandshake() so we can call this multiple times SSLSession session = ((SSLSocket) sock).getSession(); if (session.getCipherSuite().equals("SSL_NULL_WITH_NULL_NULL")) throw new IOException( "SSL handshake failed. Ciper suite in SSL Session is SSL_NULL_WITH_NULL_NULL"); if (!allowUnsafeLegacyRenegotiation && !rfc5746Supported) { // Prevent further handshakes by removing all cipher suites ((SSLSocket) sock).setEnabledCipherSuites(new String[0]); } }
public SSLSocketChannelWrapper(SSLContext sslContext, SocketChannel sc, boolean client) throws Exception { super(sc); sslEngine = sslContext.createSSLEngine(); sslEngine.setUseClientMode(client); sslEngine.setEnableSessionCreation(true); SSLSession session = sslEngine.getSession(); in = ByteBuffer.allocate(64 * 1024); emptyBuffer = ByteBuffer.allocate(0); int netBufferMax = session.getPacketBufferSize(); netOutBuffer = ByteBuffer.allocate(netBufferMax); netInBuffer = ByteBuffer.allocate(netBufferMax); }
@Override public Socket createSocket(Socket plainSocket, String host, int port, boolean autoClose) throws IOException { String peerHost = this.conn.getRequestProperty("Host"); if (peerHost == null) peerHost = host; Log.i(TAG, "customized createSocket. host: " + peerHost); InetAddress address = plainSocket.getInetAddress(); if (autoClose) { // we don't need the plainSocket plainSocket.close(); } // create and connect SSL socket, but don't do hostname/certificate verification yet SSLCertificateSocketFactory sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0); SSLSocket ssl = (SSLSocket) sslSocketFactory.createSocket(address, port); // enable TLSv1.1/1.2 if available ssl.setEnabledProtocols(ssl.getSupportedProtocols()); // set up SNI before the handshake if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { Log.i(TAG, "Setting SNI hostname"); sslSocketFactory.setHostname(ssl, peerHost); } else { Log.d(TAG, "No documented SNI support on Android <4.2, trying with reflection"); try { java.lang.reflect.Method setHostnameMethod = ssl.getClass().getMethod("setHostname", String.class); setHostnameMethod.invoke(ssl, peerHost); } catch (Exception e) { Log.w(TAG, "SNI not useable", e); } } // verify hostname and certificate SSLSession session = ssl.getSession(); if (!hostnameVerifier.verify(peerHost, session)) throw new SSLPeerUnverifiedException("Cannot verify hostname: " + peerHost); Log.i( TAG, "Established " + session.getProtocol() + " connection with " + session.getPeerHost() + " using " + session.getCipherSuite()); return ssl; }
public boolean verify(String hostName, SSLSession session) { System.out.println("Server: " + hostName + ":" + session.getPeerPort()); try { X509Certificate[] chain = session.getPeerCertificateChain(); for (X509Certificate cert : chain) { System.out.println("DN: " + cert.getSubjectDN()); } } catch (SSLPeerUnverifiedException e) { e.printStackTrace(); } System.out.println("-----"); return true; }
/** * Close the {@link SSLEngine} attached to this channel * * @throws Exception */ private void handleClose() throws Exception { if (sslEngine.isOutboundDone()) { return; } sslEngine.closeOutbound(); SSLSession session = getSSLSession(); int packetBufferSize = Math.max(session.getPacketBufferSize(), MIN_BUFFER_SIZE); this.netOutBuffer = (this.netOutBuffer == null) ? ByteBuffer.allocateDirect(packetBufferSize) : this.netOutBuffer.compact(); this.netInBuffer = (this.netInBuffer == null) ? ByteBuffer.allocateDirect(packetBufferSize) : this.netInBuffer.compact(); while (!sslEngine.isOutboundDone()) { // Get close message SSLEngineResult res = sslEngine.wrap(this.netInBuffer, this.netOutBuffer); switch (res.getStatus()) { case OK: // Execute tasks if we need to tryTasks(); while (this.netOutBuffer.hasRemaining()) { if (this.channel.write(this.netOutBuffer).get() < 0) { break; } this.netOutBuffer.compact(); } break; case BUFFER_OVERFLOW: ByteBuffer tmp = ByteBuffer.allocateDirect(packetBufferSize + this.netOutBuffer.capacity()); this.netOutBuffer.flip(); tmp.put(this.netOutBuffer); this.netOutBuffer = tmp; break; case BUFFER_UNDERFLOW: // Cannot happens in case of wrap case CLOSED: // Already closed, so return break; } } }
/** 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); }
/** Copied from <code>org.apache.catalina.valves.CertificateValve</code> */ @Override public Integer getKeySize() throws IOException, RemoteException { try { // Look up the current SSLSession org.apache.tomcat.util.net.SSLSupportCipherDataRemoteInterface c_aux[] = ciphers; if (session == null) return null; Integer keySize = null; synchronized (keySizeCache) { keySize = keySizeCache.get(session); } if (keySize == null) { int size = 0; String cipherSuite = session.getCipherSuite(); for (int i = 0; i < c_aux.length; i++) { if (cipherSuite.indexOf(c_aux[i].getPhrase()) >= 0) { size = c_aux[i].getKeySize(); break; } } keySize = Integer.valueOf(size); synchronized (keySizeCache) { keySizeCache.put(session, keySize); } } return keySize; } catch (Exception excp) { excp.printStackTrace(); } return null; }
protected boolean verify(String hostname, SSLSession session, boolean interactive) { LOGGER.log( Level.FINE, "hostname verifier for " + hostname + ", trying default verifier first"); // if the default verifier accepts the hostname, we are done if (defaultVerifier.verify(hostname, session)) { LOGGER.log(Level.FINE, "default verifier accepted " + hostname); return true; } // otherwise, we check if the hostname is an alias for this cert in our keystore try { X509Certificate cert = (X509Certificate) session.getPeerCertificates()[0]; // Log.d(TAG, "cert: " + cert); if (cert.equals(appKeyStore.getCertificate(hostname.toLowerCase(Locale.US)))) { LOGGER.log(Level.FINE, "certificate for " + hostname + " is in our keystore. accepting."); return true; } else { LOGGER.log( Level.FINE, "server " + hostname + " provided wrong certificate, asking user."); if (interactive) { return interactHostname(cert, hostname); } else { return false; } } } catch (Exception e) { e.printStackTrace(); return false; } }
/** Invalidate the session this support object is associated with. */ @Override public void invalidateSession() throws RemoteException { try { session.invalidate(); } catch (Exception excp) { excp.printStackTrace(); } }
@Override public void handshakeCompleted(HandshakeCompletedEvent event) { SSLSession session = event.getSession(); String protocol = session.getProtocol(); String cipherSuite = session.getCipherSuite(); String peerName = null; try { peerName = session.getPeerPrincipal().getName(); Log.d(TAG, "peerName: " + peerName); } catch (SSLPeerUnverifiedException e) { e.printStackTrace(); } Log.d(TAG, "session: " + session); Log.d(TAG, "protocol: " + protocol); Log.d(TAG, "cipherSuite: " + cipherSuite); }
public final void verify(String s, SSLSocket sslsocket) throws IOException { if (s == null) { throw new NullPointerException("host to verify is null"); } SSLSession sslsession1 = sslsocket.getSession(); SSLSession sslsession = sslsession1; if (sslsession1 == null) { sslsocket.getInputStream().available(); SSLSession sslsession2 = sslsocket.getSession(); sslsession = sslsession2; if (sslsession2 == null) { sslsocket.startHandshake(); sslsession = sslsocket.getSession(); } } verify(s, (X509Certificate) sslsession.getPeerCertificates()[0]); }
public final boolean verify(String s, SSLSession sslsession) { try { verify(s, (X509Certificate) sslsession.getPeerCertificates()[0]); } // Misplaced declaration of an exception variable catch (String s) { return false; } return true; }
/** Bypass host name verification */ public boolean verify(String hostname, SSLSession session) { System.out.println("Bypassing verification of hostname: " + hostname); try { System.out.println("Peer principal: " + session.getPeerPrincipal().toString()); } catch (SSLPeerUnverifiedException e) { System.err.println("Unable to get peer principal"); e.printStackTrace(); } return true; }
public boolean verify(String hostname, SSLSession session) { if (trustAllServerCerts) { return true; } boolean approve = true; X509Certificate peercert = null; String cn = null; try { X509Certificate[] peercerts = (X509Certificate[]) session.getPeerCertificates(); peercert = peercerts[0]; String subjectDN = peercert.getSubjectDN().getName(); cn = new X500Name(subjectDN).getCommonName(); } catch (Exception ex) { debug.error("AMHostnameVerifier:" + ex.toString()); } if (cn == null) return false; if (!sslTrustHosts.isEmpty()) { if (sslTrustHosts.contains(cn.toLowerCase())) { return true; } } if (resolveIPAddress) { try { approve = InetAddress.getByName(cn) .getHostAddress() .equals(InetAddress.getByName(hostname).getHostAddress()); } catch (UnknownHostException ex) { if (debug.messageEnabled()) { debug.message("AMHostnameVerifier:", ex); } approve = false; } } else { approve = false; } if (checkSubjectAltName && !approve) { try { Iterator i = (Iterator) peercert.getSubjectAlternativeNames().iterator(); for (; !approve && i.hasNext(); ) { approve = compareHosts((GeneralName) i.next(), hostname); } } catch (Exception ex) { return false; } } return approve; }
/** * Wraps an ssl socket over an existing socket and compares the host name from the address to the * common name in the server certificate. * * @param bareSocket plain socket connected to the server * @param address destination of the <tt>bareSocket</tt> * @param port destination of the <tt>bareSocket</tt> * @return SSL socket wrapped around original socket with server identity verified */ private SSLSocket sslWrap(Socket bareSocket, InetAddress address, int port) throws IOException { final String hostName = address.getHostName(); final SSLSocket sslSocket = (SSLSocket) m_factory.createSocket(bareSocket, hostName, port, true); sslSocket.startHandshake(); final SSLSession session = sslSocket.getSession(); final String DN = session.getPeerCertificateChain()[0].getSubjectDN().getName(); final String CN = getCN(DN); if (!hostName.equals(CN)) { final String message = "Host name mismatch, expected '" + hostName + "' recevied DN is " + DN; throw new IOException(message); } if (getLogger().isDebugEnabled()) { final String message = "DN of the server " + DN; getLogger().debug(message); final String message2 = "Session id " + bytesToString(session.getId()); getLogger().debug(message2); } return sslSocket; }
@Override public boolean verify(String hostname, SSLSession session) { X509Certificate peerCertificate; try { peerCertificate = (X509Certificate) session.getPeerCertificates()[0]; } catch (SSLPeerUnverifiedException e) { throw new IllegalStateException("The session does not contain a peer X.509 certificate."); } String peerCertificateCN = getCommonName(peerCertificate); return hostname.equals(peerCertificateCN); }
@Override public String getCipherSuite() throws IOException, RemoteException { try { // Look up the current SSLSession if (session == null) return null; return session.getCipherSuite(); } catch (Exception excp) { excp.printStackTrace(); } return null; }
public void handShake() throws IOException, RemoteException { try { if (ssl.getWantClientAuth()) { log.debug(sm.getString("jsseSupport.noCertWant")); } else { ssl.setNeedClientAuth(true); } if (ssl.getEnabledCipherSuites().length == 0) { // Handshake is never going to be successful. // Assume this is because handshakes are disabled log.warn(sm.getString("jsseSupport.serverRenegDisabled")); session.invalidate(); ssl.close(); return; } InputStream in = ssl.getInputStream(); int oldTimeout = ssl.getSoTimeout(); ssl.setSoTimeout(1000); byte[] b = new byte[1]; listener.reset(); ssl.startHandshake(); int maxTries = 60; // 60 * 1000 = example 1 minute time out for (int i = 0; i < maxTries; i++) { if (log.isTraceEnabled()) log.trace("Reading for try #" + i); try { int read = in.read(b); if (read > 0) { // Shouldn't happen as all input should have been swallowed // before trying to do the handshake. If it does, something // went wrong so lets bomb out now. throw new SSLException(sm.getString("jsseSupport.unexpectedData")); } } catch (SSLException sslex) { log.info(sm.getString("jsseSupport.clientCertError"), sslex); throw sslex; } catch (IOException e) { // ignore - presumably the timeout } if (listener.isCompleted()) { break; } } ssl.setSoTimeout(oldTimeout); if (listener.isCompleted() == false) { throw new SocketException("SSL Cert handshake timeout"); } } catch (Exception excp) { excp.printStackTrace(); } }
@SuppressLint("NewApi") private Socket enableSNI(SSLSocket ssl, String host) throws SSLPeerUnverifiedException { // enable TLSv1.1/1.2 if available // (see https://github.com/rfc2822/davdroid/issues/229) ssl.setEnabledProtocols(ssl.getSupportedProtocols()); // set up SNI before the handshake if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { AppLog.i(T.API, "Setting SNI hostname"); mFactory.setHostname(ssl, host); } else { AppLog.i(T.API, "No documented SNI support on Android <4.2, trying with reflection"); try { java.lang.reflect.Method setHostnameMethod = ssl.getClass().getMethod("setHostname", String.class); setHostnameMethod.invoke(ssl, host); } catch (Exception e) { AppLog.e(T.API, "SNI not useable", e); } } // verify hostname and certificate SSLSession session = ssl.getSession(); if (!mHostnameVerifier.verify(host, session)) { throw new SSLPeerUnverifiedException("Cannot verify hostname: " + host); } AppLog.i( T.API, "Established " + session.getProtocol() + " connection with " + session.getPeerHost() + " using " + session.getCipherSuite()); return ssl; }