下面列出了怎么用javax.net.ssl.SSLSession的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
SSLSocket ssl = (SSLSocket)sslSocketFactory.createSocket(s, host, port, autoClose);
// set SNI before the handshake
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Logger.info(TAG, "Setting SNI hostname");
sslSocketFactory.setHostname(ssl, host);
} else {
Logger.warn(TAG, "No SNI support below Android 4.2!");
}
// now do the TLS handshake
ssl.startHandshake();
SSLSession session = ssl.getSession();
if (session == null)
throw new SSLException("Cannot verify SSL socket without session");
// verify host name (important!)
if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session))
throw new SSLPeerUnverifiedException("Cannot verify hostname: " + host);
return ssl;
}
@Named("cxfProducerEndpointRel")
@Produces
public CxfRsEndpoint createCxfProducerEndpointRel() {
CxfRsEndpoint cxfProducerEndpoint = this.camelContext.getEndpoint("cxfrs:" + CXF_ENDPOINT_REL_BASE_URI, CxfRsEndpoint.class);
cxfProducerEndpoint.setBeanId("cxfProducerEndpointRel");
cxfProducerEndpoint.addResourceClass(GreetingsService.class);
// Not for use in production
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
cxfProducerEndpoint.setHostnameVerifier(hostnameVerifier);
return cxfProducerEndpoint;
}
/**
* 创建okhttp,主要是用它进行缓存
*/
private void initHttpClient() {
//设置缓存的位置,还有缓存的大小,默认是100M
final Cache cache = new Cache(mCacheFile, mCacheSize);
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cache(cache)
.connectTimeout(mConnectTimeout, TimeUnit.SECONDS)
.readTimeout(mReadTimeout, TimeUnit.SECONDS)
.addNetworkInterceptor(new HttpCacheInterceptor());
if (mTrustAllHostname) {
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
if (mSSLSocketFactory != null && mX509TrustManager != null) {
builder.sslSocketFactory(mSSLSocketFactory, mX509TrustManager);
}
if(mDns!=null){
builder.dns(mDns);
}
mHttpClient = builder.build();
}
/**
* Returns the X509Certificate for the server this session is connected to. The certificate may be null.
*
* @param sslSession SSL session connected to upstream server
* @return the X.509 certificate from the upstream server, or null if no certificate is available
*/
public static X509Certificate getServerCertificate(SSLSession sslSession) {
Certificate[] peerCertificates;
try {
peerCertificates = sslSession.getPeerCertificates();
} catch (SSLPeerUnverifiedException e) {
peerCertificates = null;
}
if (peerCertificates != null && peerCertificates.length > 0) {
Certificate peerCertificate = peerCertificates[0];
if (peerCertificate != null && peerCertificate instanceof X509Certificate) {
return (X509Certificate) peerCertificates[0];
}
}
// no X.509 certificate was found for this server
return null;
}
@Nullable
private static String initSessionId(SSLSession session) {
byte [] bytes = session.getId();
if (bytes == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
String digit = Integer.toHexString(b);
if (digit.length() < 2) {
sb.append('0');
}
if (digit.length() > 2) {
digit = digit.substring(digit.length() - 2);
}
sb.append(digit);
}
return sb.toString();
}
@Nullable
private static X509Certificate[] initCertificates(SSLSession session) {
Certificate[] certificates;
try {
certificates = session.getPeerCertificates();
}
catch (Throwable ex) {
return null;
}
List<X509Certificate> result = new ArrayList<>(certificates.length);
for (Certificate certificate : certificates) {
if (certificate instanceof X509Certificate) {
result.add((X509Certificate) certificate);
}
}
return (!result.isEmpty() ? result.toArray(new X509Certificate[0]) : null);
}
public SSLEngine clientSslEngineFor(HttpRequest httpRequest, SSLSession serverSslSession) {
try {
X509Certificate upstreamCert = getCertificateFromSession(serverSslSession);
// TODO store the upstream cert by commonName to review it later
// A reasons to not use the common name and the alternative names
// from upstream certificate from serverSslSession to create the
// dynamic certificate:
//
// It's not necessary. The host name is accepted by the browser.
//
String commonName = getCommonName(upstreamCert);
SubjectAlternativeNameHolder san = new SubjectAlternativeNameHolder();
san.addAll(upstreamCert.getSubjectAlternativeNames());
LOG.debug("Subject Alternative Names: {}", san);
return sslEngineSource.createCertForHost(commonName, san);
} catch (Exception e) {
throw new FakeCertificateException(
"Creation dynamic certificate failed", e);
}
}
private ClientTlsChannel(
ByteChannel underlying,
SSLEngine engine,
Consumer<SSLSession> sessionInitCallback,
boolean runTasks,
BufferAllocator plainBufAllocator,
BufferAllocator encryptedBufAllocator,
boolean releaseBuffers,
boolean waitForCloseNotifyOnClose) {
if (!engine.getUseClientMode()) {
throw new IllegalArgumentException("SSLEngine must be in client mode");
}
this.underlying = underlying;
TrackingAllocator trackingPlainBufAllocator = new TrackingAllocator(plainBufAllocator);
TrackingAllocator trackingEncryptedAllocator = new TrackingAllocator(encryptedBufAllocator);
impl = new TlsChannelImpl(underlying, underlying, engine, Optional.empty(), sessionInitCallback, runTasks,
trackingPlainBufAllocator, trackingEncryptedAllocator, releaseBuffers, waitForCloseNotifyOnClose);
}
/**
* Returns the X509Certificate for the server this session is connected to. The certificate may be null.
*
* @param sslSession SSL session connected to upstream server
* @return the X.509 certificate from the upstream server, or null if no certificate is available
*/
public static X509Certificate getServerCertificate(SSLSession sslSession) {
Certificate[] peerCertificates;
try {
peerCertificates = sslSession.getPeerCertificates();
} catch (SSLPeerUnverifiedException e) {
peerCertificates = null;
}
if (peerCertificates != null && peerCertificates.length > 0) {
Certificate peerCertificate = peerCertificates[0];
if (peerCertificate != null && peerCertificate instanceof X509Certificate) {
return (X509Certificate) peerCertificates[0];
}
}
// no X.509 certificate was found for this server
return null;
}
@Test
public void testHostnameVerifier() throws IOException {
SSLSession session = Mockito.mock(SSLSession.class);
Path path = Paths.get("src/test/resources/athenz.instanceid.pem");
String pem = new String(Files.readAllBytes(path));
X509Certificate cert = Crypto.loadX509Certificate(pem);
Certificate[] certs = new Certificate[1];
certs[0] = cert;
Mockito.when(session.getPeerCertificates()).thenReturn(certs);
ProviderHostnameVerifier verifier1 = new ProviderHostnameVerifier("athenz.production");
assertTrue(verifier1.verify("athenz", session));
ProviderHostnameVerifier verifier2 = new ProviderHostnameVerifier("athenz.production2");
assertFalse(verifier2.verify("athenz", session));
}
@Nullable
private String initSessionId(SSLSession session) {
byte [] bytes = session.getId();
if (bytes == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
String digit = Integer.toHexString(b);
if (digit.length() < 2) {
sb.append('0');
}
if (digit.length() > 2) {
digit = digit.substring(digit.length() - 2);
}
sb.append(digit);
}
return sb.toString();
}
private HostnameVerifier getFriendlyToAllHostnameVerifier() {
final HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(final String hostname, final SSLSession session) { return true; }
};
return hv;
}
static void checkIdentity(SSLSession session,
X509Certificate [] trustedChain,
String algorithm,
boolean checkClientTrusted) throws CertificateException {
boolean identifiable = false;
String peerHost = session.getPeerHost();
if (!checkClientTrusted) {
List<SNIServerName> sniNames = getRequestedServerNames(session);
String sniHostName = getHostNameInSNI(sniNames);
if (sniHostName != null) {
try {
checkIdentity(sniHostName,
trustedChain[0], algorithm);
identifiable = true;
} catch (CertificateException ce) {
if (sniHostName.equalsIgnoreCase(peerHost)) {
throw ce;
}
// otherwisw, failover to check peer host
}
}
}
if (!identifiable) {
checkIdentity(peerHost,
trustedChain[0], algorithm);
}
}
private static Principal getPeerPrincipal(SSLSession session)
throws SSLPeerUnverifiedException {
Principal principal;
try {
principal = session.getPeerPrincipal();
} catch (AbstractMethodError e) {
// if the JSSE provider does not support it, return null, since
// we need it only for Kerberos.
principal = null;
}
return principal;
}
/**
* Verifies tha the SSL channel is established as expected, and also sends a message to the server
* and verifies if it is echoed back correctly.
*
* @param certs The certificate that the server should provide.
* @return The SSL session in current channel, can be used for further validation.
*/
static SSLSession setUpSslChannel(Channel channel, X509Certificate... certs) throws Exception {
SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
// Wait till the handshake is complete.
sslHandler.handshakeFuture().get();
assertThat(channel.isActive()).isTrue();
assertThat(sslHandler.handshakeFuture().isSuccess()).isTrue();
assertThat(sslHandler.engine().getSession().isValid()).isTrue();
assertThat(sslHandler.engine().getSession().getPeerCertificates())
.asList()
.containsExactlyElementsIn(certs);
// Returns the SSL session for further assertion.
return sslHandler.engine().getSession();
}
private Socket createSocket(HttpHost host) throws IOException {
Socket socket = new Socket();
socket.setSoTimeout(60 * 1000);
socket.setReuseAddress(true);
socket.setTcpNoDelay(true);
socket.setKeepAlive(true);
socket.setReceiveBufferSize(BUFFER);
socket.setSendBufferSize(BUFFER);
socket.setSoLinger(true, 0);
String scheme = host.getSchemeName();
String hostName = host.getHostName();
int port = host.getPort();
InetSocketAddress address = resolveAddress(scheme, hostName, port);
socket.connect(address, 10 * 1000);
if ("https".equalsIgnoreCase(scheme)) {
SSLSocket sslSocket = (SSLSocket) mSocketFactory.createSocket(socket, hostName, port, true);
try {
sslSocket.startHandshake();
final SSLSession session = sslSocket.getSession();
if (session == null) {
throw new SSLHandshakeException("SSL session not available.");
}
} catch (final IOException ex) {
IOUtils.closeQuietly(sslSocket);
throw ex;
}
return sslSocket;
}
return socket;
}
@Override
public void handle(Client client, HttpServerRequest request, Handler<AsyncResult<Client>> handler) {
// We ensure that the authentication is done over TLS thanks to the canHandle method which checks for an SSL
// session
SSLSession sslSession = request.sslSession();
try {
Certificate[] peerCertificates = sslSession.getPeerCertificates();
X509Certificate peerCertificate = (X509Certificate) peerCertificates[0];
String thumbprint = getThumbprint(peerCertificate, "SHA-1");
String thumbprint256 = getThumbprint(peerCertificate, "SHA-256");
jwkService.getKeys(client)
.subscribe(
jwkSet -> {
boolean match = jwkSet.getKeys()
.stream()
.anyMatch(jwk -> thumbprint256.equals(jwk.getX5tS256()) || thumbprint.equals(jwk.getX5t()));
if (match) {
handler.handle(Future.succeededFuture(client));
} else {
handler.handle(Future.failedFuture(new InvalidClientException("Invalid client: invalid self-signed certificate")));
}
},
throwable -> handler.handle(Future.failedFuture(new InvalidClientException("Invalid client: invalid self-signed certificate"))),
() -> handler.handle(Future.failedFuture(new InvalidClientException("Invalid client: missing or unsupported JWK Set"))));
} catch (Exception ex) {
handler.handle(Future.failedFuture(new InvalidClientException("Invalid client: missing or unsupported self-signed certificate")));
}
}
@Nullable
@Override
protected SslInfo initSslInfo() {
SSLSession session = this.exchange.getConnection().getSslSession();
if (session != null) {
return new DefaultSslInfo(session);
}
return null;
}
void doClientSide() throws Exception {
// Wait for server to get started.
while (!serverReady) {
Thread.sleep(50);
}
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}});
URL url = new URL("https://localhost:" + serverPort +"/");
// Run without a CookieHandler first
InputStream in = url.openConnection().getInputStream();
while (in.read() != -1); // read response body so connection can be reused
// Set a CookeHandler and retest using the HttpClient from the KAC
CookieManager manager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
in = url.openConnection().getInputStream();
while (in.read() != -1);
if (manager.getCookieStore().getCookies().isEmpty()) {
throw new RuntimeException("Failed: No cookies in the cookie Handler.");
}
}
/**
* Creates an SSLContext that will present an impersonated certificate for the specified hostname to the client.
* This is a convenience method for {@link #createImpersonatingSslContext(CertificateInfo)} that generates the
* {@link CertificateInfo} from the specified hostname using the {@link #certificateInfoGenerator}.
*
* @param sslSession sslSession between the proxy and the upstream server
* @param hostnameToImpersonate hostname (supplied by the client's HTTP CONNECT) that will be impersonated
* @return an SSLContext presenting a certificate matching the hostnameToImpersonate
*/
private SslContext createImpersonatingSslContext(SSLSession sslSession, String hostnameToImpersonate) {
// get the upstream server's certificate so the certificateInfoGenerator can (optionally) use it to construct a forged certificate
X509Certificate originalCertificate = SslUtil.getServerCertificate(sslSession);
// get the CertificateInfo that will be used to populate the impersonated X509Certificate
CertificateInfo certificateInfo = certificateInfoGenerator.generate(Collections.singletonList(hostnameToImpersonate), originalCertificate);
SslContext sslContext = createImpersonatingSslContext(certificateInfo);
return sslContext;
}
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
if (engine != null) {
SSLSession session = engine.getHandshakeSession();
if (session != null && (session instanceof ExtendedSSLSession)) {
ExtendedSSLSession extSession = (ExtendedSSLSession)session;
return extSession.getRequestedServerNames();
}
}
return Collections.<SNIServerName>emptyList();
}
/**
* Gets a {@link TenantObjectWithAuthId} from the X509 certificate of the given {@link SSLSession}.
*
* @param sslSession The SSL session.
* @param spanContext The OpenTracing context to use for tracking the operation (may be {@code null}).
* @return A future indicating the outcome of the operation.
* @throws NullPointerException if sslSession is {@code null}.
*/
protected final Future<TenantObjectWithAuthId> getFromClientCertificate(final SSLSession sslSession,
final SpanContext spanContext) {
Objects.requireNonNull(sslSession);
final X509Certificate deviceCert = getX509Cert(sslSession);
if (deviceCert == null) {
return Future.failedFuture("no cert found");
}
return getFromClientCertificate(deviceCert, spanContext);
}
protected HttpActivityExecutor createHttpActivityExecutor() {
HttpClientConfig config = CommandContextUtil.getCmmnEngineConfiguration().getHttpClientConfig();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// https settings
if (config.isDisableCertVerify()) {
try {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
httpClientBuilder.setSSLSocketFactory(
new SSLConnectionSocketFactory(builder.build(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}));
} catch (Exception e) {
LOGGER.error("Could not configure HTTP client SSL self signed strategy", e);
}
}
// request retry settings
int retryCount = 0;
if (config.getRequestRetryLimit() > 0) {
retryCount = config.getRequestRetryLimit();
}
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, false));
// client builder settings
if (config.isUseSystemProperties()) {
httpClientBuilder.useSystemProperties();
}
return new HttpActivityExecutor(httpClientBuilder, new NopErrorPropagator(),
CommandContextUtil.getCmmnEngineConfiguration().getObjectMapper());
}
private static Principal getPeerPrincipal(SSLSession session)
throws SSLPeerUnverifiedException {
Principal principal;
try {
principal = session.getPeerPrincipal();
} catch (AbstractMethodError e) {
// if the JSSE provider does not support it, return null, since
// we need it only for Kerberos.
principal = null;
}
return principal;
}
private X509Certificate getCertificateFromSession(SSLSession sslSession)
throws SSLPeerUnverifiedException {
Certificate[] peerCerts = sslSession.getPeerCertificates();
Certificate peerCert = peerCerts[0];
if (peerCert instanceof X509Certificate) {
return (X509Certificate) peerCert;
}
throw new IllegalStateException(
"Required java.security.cert.X509Certificate, found: "
+ peerCert);
}
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
// Disable SSL hostname verifier.
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession sslSes) {
return true;
}
});
super.beforeTest();
}
private ClientTlsChannel(
ByteChannel underlying,
SSLEngine engine,
Consumer<SSLSession> sessionInitCallback,
boolean runTasks,
BufferAllocator plainBufAllocator,
BufferAllocator encryptedBufAllocator,
boolean releaseBuffers,
boolean waitForCloseNotifyOnClose) {
if (!engine.getUseClientMode())
throw new IllegalArgumentException("SSLEngine must be in client mode");
this.underlying = underlying;
TrackingAllocator trackingPlainBufAllocator = new TrackingAllocator(plainBufAllocator);
TrackingAllocator trackingEncryptedAllocator = new TrackingAllocator(encryptedBufAllocator);
impl =
new TlsChannelImpl(
underlying,
underlying,
engine,
Optional.empty(),
sessionInitCallback,
runTasks,
trackingPlainBufAllocator,
trackingEncryptedAllocator,
releaseBuffers,
waitForCloseNotifyOnClose);
}
@Override
public X509Certificate[] getCertificateChain(HttpRequest httpRequest) {
Instance<RoutingContext> instances = CDI.current().select(RoutingContext.class);
if (instances.isResolvable()) {
RoutingContext context = instances.get();
try {
SSLSession sslSession = context.request().sslSession();
if (sslSession == null) {
return null;
}
X509Certificate[] certificates = (X509Certificate[]) sslSession.getPeerCertificates();
if (logger.isTraceEnabled() && certificates != null) {
for (X509Certificate cert : certificates) {
logger.tracef("Certificate's SubjectDN => \"%s\"", cert.getSubjectDN().getName());
}
}
return certificates;
} catch (SSLPeerUnverifiedException ignore) {
// client not authenticated
}
}
return null;
}
boolean isTimedout(SSLSession sess) {
if (timeout == 0) {
return false;
}
if ((sess != null) && ((sess.getCreationTime() + timeout * 1000L)
<= (System.currentTimeMillis()))) {
sess.invalidate();
return true;
}
return false;
}
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
if (engine != null) {
SSLSession session = engine.getHandshakeSession();
if (session != null && (session instanceof ExtendedSSLSession)) {
ExtendedSSLSession extSession = (ExtendedSSLSession)session;
return extSession.getRequestedServerNames();
}
}
return Collections.<SNIServerName>emptyList();
}