use of javax.net.ssl.SSLPeerUnverifiedException in project grpc-java by grpc.
the class OkHttpTlsUpgrader method upgrade.
/**
* Upgrades given Socket to be a SSLSocket.
*
* @throws IOException if an IO error was encountered during the upgrade handshake.
* @throws RuntimeException if the upgrade negotiation failed.
*/
public static SSLSocket upgrade(SSLSocketFactory sslSocketFactory, Socket socket, String host, int port, ConnectionSpec spec) throws IOException {
Preconditions.checkNotNull(sslSocketFactory, "sslSocketFactory");
Preconditions.checkNotNull(socket, "socket");
Preconditions.checkNotNull(spec, "spec");
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, host, port, true);
spec.apply(sslSocket, false);
String negotiatedProtocol = OkHttpProtocolNegotiator.get().negotiate(sslSocket, host, spec.supportsTlsExtensions() ? TLS_PROTOCOLS : null);
Preconditions.checkState(TLS_PROTOCOLS.contains(Protocol.get(negotiatedProtocol)), "Only " + TLS_PROTOCOLS + " are supported, but negotiated protocol is %s", negotiatedProtocol);
if (!OkHostnameVerifier.INSTANCE.verify(host, sslSocket.getSession())) {
throw new SSLPeerUnverifiedException("Cannot verify hostname: " + host);
}
return sslSocket;
}
use of javax.net.ssl.SSLPeerUnverifiedException in project okhttp by square.
the class RealConnection method connectTls.
private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
Address address = route.address();
SSLSocketFactory sslSocketFactory = address.sslSocketFactory();
boolean success = false;
SSLSocket sslSocket = null;
try {
// Create the wrapper over the connected socket.
sslSocket = (SSLSocket) sslSocketFactory.createSocket(rawSocket, address.url().host(), address.url().port(), true);
// Configure the socket's ciphers, TLS versions, and extensions.
ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);
if (connectionSpec.supportsTlsExtensions()) {
Platform.get().configureTlsExtensions(sslSocket, address.url().host(), address.protocols());
}
// Force handshake. This can throw!
sslSocket.startHandshake();
Handshake unverifiedHandshake = Handshake.get(sslSocket.getSession());
// Verify that the socket's certificates are acceptable for the target host.
if (!address.hostnameVerifier().verify(address.url().host(), sslSocket.getSession())) {
X509Certificate cert = (X509Certificate) unverifiedHandshake.peerCertificates().get(0);
throw new SSLPeerUnverifiedException("Hostname " + address.url().host() + " not verified:" + "\n certificate: " + CertificatePinner.pin(cert) + "\n DN: " + cert.getSubjectDN().getName() + "\n subjectAltNames: " + OkHostnameVerifier.allSubjectAltNames(cert));
}
// Check that the certificate pinner is satisfied by the certificates presented.
address.certificatePinner().check(address.url().host(), unverifiedHandshake.peerCertificates());
// Success! Save the handshake and the ALPN protocol.
String maybeProtocol = connectionSpec.supportsTlsExtensions() ? Platform.get().getSelectedProtocol(sslSocket) : null;
socket = sslSocket;
source = Okio.buffer(Okio.source(socket));
sink = Okio.buffer(Okio.sink(socket));
handshake = unverifiedHandshake;
protocol = maybeProtocol != null ? Protocol.get(maybeProtocol) : Protocol.HTTP_1_1;
success = true;
} catch (AssertionError e) {
if (Util.isAndroidGetsocknameError(e))
throw new IOException(e);
throw e;
} finally {
if (sslSocket != null) {
Platform.get().afterHandshake(sslSocket);
}
if (!success) {
closeQuietly(sslSocket);
}
}
}
use of javax.net.ssl.SSLPeerUnverifiedException in project okhttp by square.
the class BasicCertificateChainCleaner method clean.
/**
* Returns a cleaned chain for {@code chain}.
*
* <p>This method throws if the complete chain to a trusted CA certificate cannot be constructed.
* This is unexpected unless the trust root index in this class has a different trust manager than
* what was used to establish {@code chain}.
*/
@Override
public List<Certificate> clean(List<Certificate> chain, String hostname) throws SSLPeerUnverifiedException {
Deque<Certificate> queue = new ArrayDeque<>(chain);
List<Certificate> result = new ArrayList<>();
result.add(queue.removeFirst());
boolean foundTrustedCertificate = false;
followIssuerChain: for (int c = 0; c < MAX_SIGNERS; c++) {
X509Certificate toVerify = (X509Certificate) result.get(result.size() - 1);
// If this cert has been signed by a trusted cert, use that. Add the trusted certificate to
// the end of the chain unless it's already present. (That would happen if the first
// certificate in the chain is itself a self-signed and trusted CA certificate.)
X509Certificate trustedCert = trustRootIndex.findByIssuerAndSignature(toVerify);
if (trustedCert != null) {
if (result.size() > 1 || !toVerify.equals(trustedCert)) {
result.add(trustedCert);
}
if (verifySignature(trustedCert, trustedCert)) {
// The self-signed cert is a root CA. We're done.
return result;
}
foundTrustedCertificate = true;
continue;
}
// the next element in the chain, but it could be any element.
for (Iterator<Certificate> i = queue.iterator(); i.hasNext(); ) {
X509Certificate signingCert = (X509Certificate) i.next();
if (verifySignature(toVerify, signingCert)) {
i.remove();
result.add(signingCert);
continue followIssuerChain;
}
}
// We've reached the end of the chain. If any cert in the chain is trusted, we're done.
if (foundTrustedCertificate) {
return result;
}
// The last link isn't trusted. Fail.
throw new SSLPeerUnverifiedException("Failed to find a trusted cert that signed " + toVerify);
}
throw new SSLPeerUnverifiedException("Certificate chain too long: " + result);
}
use of javax.net.ssl.SSLPeerUnverifiedException in project okhttp by square.
the class JavaApiConverter method createOkResponseForCacheGet.
/**
* Creates an OkHttp {@link Response} using the supplied {@link Request} and {@link CacheResponse}
* to supply the data.
*/
static Response createOkResponseForCacheGet(Request request, CacheResponse javaResponse) throws IOException {
// Build a cache request for the response to use.
Headers responseHeaders = createHeaders(javaResponse.getHeaders());
Headers varyHeaders;
if (HttpHeaders.hasVaryAll(responseHeaders)) {
// "*" means that this will be treated as uncacheable anyway.
varyHeaders = new Headers.Builder().build();
} else {
varyHeaders = HttpHeaders.varyHeaders(request.headers(), responseHeaders);
}
Request cacheRequest = new Request.Builder().url(request.url()).method(request.method(), null).headers(varyHeaders).build();
Response.Builder okResponseBuilder = new Response.Builder();
// Request: Use the cacheRequest we built.
okResponseBuilder.request(cacheRequest);
// Status line: Java has this as one of the headers.
StatusLine statusLine = StatusLine.parse(extractStatusLine(javaResponse));
okResponseBuilder.protocol(statusLine.protocol);
okResponseBuilder.code(statusLine.code);
okResponseBuilder.message(statusLine.message);
// Response headers
Headers okHeaders = extractOkHeaders(javaResponse, okResponseBuilder);
okResponseBuilder.headers(okHeaders);
// Response body
ResponseBody okBody = createOkBody(okHeaders, javaResponse);
okResponseBuilder.body(okBody);
// Handle SSL handshake information as needed.
if (javaResponse instanceof SecureCacheResponse) {
SecureCacheResponse javaSecureCacheResponse = (SecureCacheResponse) javaResponse;
// Handshake doesn't support null lists.
List<Certificate> peerCertificates;
try {
peerCertificates = javaSecureCacheResponse.getServerCertificateChain();
} catch (SSLPeerUnverifiedException e) {
peerCertificates = Collections.emptyList();
}
List<Certificate> localCertificates = javaSecureCacheResponse.getLocalCertificateChain();
if (localCertificates == null) {
localCertificates = Collections.emptyList();
}
String cipherSuiteString = javaSecureCacheResponse.getCipherSuite();
CipherSuite cipherSuite = CipherSuite.forJavaName(cipherSuiteString);
Handshake handshake = Handshake.get(null, cipherSuite, peerCertificates, localCertificates);
okResponseBuilder.handshake(handshake);
}
return okResponseBuilder.build();
}
use of javax.net.ssl.SSLPeerUnverifiedException in project okhttp by square.
the class CertificatePinner method check.
/**
* Confirms that at least one of the certificates pinned for {@code hostname} is in {@code
* peerCertificates}. Does nothing if there are no certificates pinned for {@code hostname}.
* OkHttp calls this after a successful TLS handshake, but before the connection is used.
*
* @throws SSLPeerUnverifiedException if {@code peerCertificates} don't match the certificates
* pinned for {@code hostname}.
*/
public void check(String hostname, List<Certificate> peerCertificates) throws SSLPeerUnverifiedException {
List<Pin> pins = findMatchingPins(hostname);
if (pins.isEmpty())
return;
if (certificateChainCleaner != null) {
peerCertificates = certificateChainCleaner.clean(peerCertificates, hostname);
}
for (int c = 0, certsSize = peerCertificates.size(); c < certsSize; c++) {
X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(c);
// Lazily compute the hashes for each certificate.
ByteString sha1 = null;
ByteString sha256 = null;
for (int p = 0, pinsSize = pins.size(); p < pinsSize; p++) {
Pin pin = pins.get(p);
if (pin.hashAlgorithm.equals("sha256/")) {
if (sha256 == null)
sha256 = sha256(x509Certificate);
// Success!
if (pin.hash.equals(sha256))
return;
} else if (pin.hashAlgorithm.equals("sha1/")) {
if (sha1 == null)
sha1 = sha1(x509Certificate);
// Success!
if (pin.hash.equals(sha1))
return;
} else {
throw new AssertionError();
}
}
}
// If we couldn't find a matching pin, format a nice exception.
StringBuilder message = new StringBuilder().append("Certificate pinning failure!").append("\n Peer certificate chain:");
for (int c = 0, certsSize = peerCertificates.size(); c < certsSize; c++) {
X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(c);
message.append("\n ").append(pin(x509Certificate)).append(": ").append(x509Certificate.getSubjectDN().getName());
}
message.append("\n Pinned certificates for ").append(hostname).append(":");
for (int p = 0, pinsSize = pins.size(); p < pinsSize; p++) {
Pin pin = pins.get(p);
message.append("\n ").append(pin);
}
throw new SSLPeerUnverifiedException(message.toString());
}
Aggregations