--- Http11AprProcessor.java (revision 496746) +++ Http11AprProcessor.java (working copy) @@ -1095,16 +1095,29 @@ (AprEndpoint.CIPHER_SUITE_KEY, sslO); } // Client certificate chain if present + ////////////////////////////////////////////////// + // CP: does not include client certificate, only CA certificates + // see documentation of SSL_get_peer_cert_chain() in openssl and sslinfo.c in native APR code + // SSL_get_peer_cert_chain() returns a pointer to STACKOF(X509) certificates forming the certificate chain of the peer. + // If called on the client side, the stack also contains the peer's certificate; + // if called on the server side, the peer's certificate must be obtained separately using SSL_get_peer_certificate(3). + // If the peer did not present a certificate, NULL is returned. + // int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN); + // retrieve client certificate + byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT); X509Certificate[] certs = null; - if (certLength > 0) { - certs = new X509Certificate[certLength]; + if (clientCert != null) { + certs = new X509Certificate[certLength+1]; // add one for the client certificate + + CertificateFactory cf = + CertificateFactory.getInstance("X.509"); + + certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert)); + for (int i = 0; i < certLength; i++) { byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i); - CertificateFactory cf = - CertificateFactory.getInstance("X.509"); - ByteArrayInputStream stream = new ByteArrayInputStream(data); - certs[i] = (X509Certificate) cf.generateCertificate(stream); + certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data)); } } if (certs != null) { @@ -1142,16 +1155,29 @@ // Renegociate certificates SSLSocket.renegotiate(socket); // Client certificate chain if present + ////////////////////////////////////////////////// + // CP: does not include client certificate, only CA certificates + // see documentation of SSL_get_peer_cert_chain() in openssl and sslinfo.c in native APR code + // SSL_get_peer_cert_chain() returns a pointer to STACKOF(X509) certificates forming the certificate chain of the peer. + // If called on the client side, the stack also contains the peer's certificate; + // if called on the server side, the peer's certificate must be obtained separately using SSL_get_peer_certificate(3). + // If the peer did not present a certificate, NULL is returned. + // int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN); + // retrieve client certificate + byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT); X509Certificate[] certs = null; - if (certLength > 0) { - certs = new X509Certificate[certLength]; + if (clientCert != null) { + certs = new X509Certificate[certLength+1]; // add one for the client certificate + + CertificateFactory cf = + CertificateFactory.getInstance("X.509"); + + certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert)); + for (int i = 0; i < certLength; i++) { byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i); - CertificateFactory cf = - CertificateFactory.getInstance("X.509"); - ByteArrayInputStream stream = new ByteArrayInputStream(data); - certs[i] = (X509Certificate) cf.generateCertificate(stream); + certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data)); } } if (certs != null) {