SSLCertificateSocketFactorypublic class SSLCertificateSocketFactory extends SSLSocketFactory SSLSocketFactory that provides optional (on debug devices, only) skipping of ssl certificfate
chain validation and custom read timeouts used just when connecting to the server/negotiating
an ssl session.
You can skip the ssl certificate checking at runtime by setting socket.relaxsslcheck=yes on
devices that do not have have ro.secure set. |
Fields Summary |
---|
private static final String | LOG_TAG | private static X509TrustManager | sDefaultTrustManager | private static final TrustManager[] | TRUST_MANAGER | private final SSLSocketFactory | mFactory | private final int | mSocketReadTimeoutForSslHandshake |
Constructors Summary |
---|
public SSLCertificateSocketFactory(int socketReadTimeoutForSslHandshake)Do not use this constructor (will be deprecated). Use {@link #getDefault(int)} instead.
this(socketReadTimeoutForSslHandshake, null /* cache */);
| private SSLCertificateSocketFactory(int socketReadTimeoutForSslHandshake, org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache cache)
SSLContextImpl sslContext = new SSLContextImpl();
sslContext.engineInit(null /* kms */,
TRUST_MANAGER, new java.security.SecureRandom(),
cache /* client cache */, null /* server cache */);
this.mFactory = sslContext.engineGetSocketFactory();
this.mSocketReadTimeoutForSslHandshake = socketReadTimeoutForSslHandshake;
|
Methods Summary |
---|
public java.net.Socket | createSocket(java.lang.String s, int i, java.net.InetAddress inaddr, int j)
SSLSocket sslSock = (SSLSocket) mFactory.createSocket(s, i, inaddr, j);
if (mSocketReadTimeoutForSslHandshake >= 0) {
sslSock.setSoTimeout(mSocketReadTimeoutForSslHandshake);
}
validateSocket(sslSock,s);
sslSock.setSoTimeout(0);
return sslSock;
| public java.net.Socket | createSocket(java.lang.String s, int i)
SSLSocket sslSock = (SSLSocket) mFactory.createSocket(s, i);
if (mSocketReadTimeoutForSslHandshake >= 0) {
sslSock.setSoTimeout(mSocketReadTimeoutForSslHandshake);
}
validateSocket(sslSock,s);
sslSock.setSoTimeout(0);
return sslSock;
| public java.net.Socket | createSocket(java.net.Socket socket, java.lang.String s, int i, boolean flag)
throw new IOException("Cannot validate certification without a hostname");
| public java.net.Socket | createSocket(java.net.InetAddress inaddr, int i, java.net.InetAddress inaddr2, int j)
throw new IOException("Cannot validate certification without a hostname");
| public java.net.Socket | createSocket(java.net.InetAddress inaddr, int i)
throw new IOException("Cannot validate certification without a hostname");
| public static javax.net.SocketFactory | getDefault(int socketReadTimeoutForSslHandshake)Returns a new instance of a socket factory using the specified socket read
timeout while connecting with the server/negotiating an ssl session.
return getDefault(socketReadTimeoutForSslHandshake, null /* cache */);
| public static javax.net.SocketFactory | getDefault(int socketReadTimeoutForSslHandshake, org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache cache)Returns a new instance of a socket factory using the specified socket read
timeout while connecting with the server/negotiating an ssl session.
Persists ssl sessions using the provided {@link SSLClientSessionCache}.
try {
return new SSLCertificateSocketFactory(socketReadTimeoutForSslHandshake, cache);
} catch (NoSuchAlgorithmException e) {
Log.e(LOG_TAG,
"SSLCertifcateSocketFactory.getDefault" +
" NoSuchAlgorithmException " , e);
return null;
} catch (KeyManagementException e) {
Log.e(LOG_TAG,
"SSLCertifcateSocketFactory.getDefault" +
" KeyManagementException " , e);
return null;
}
| public java.lang.String[] | getDefaultCipherSuites()
return mFactory.getSupportedCipherSuites();
| public java.lang.String[] | getSupportedCipherSuites()
return mFactory.getSupportedCipherSuites();
| private boolean | hasValidCertificateChain(java.security.cert.Certificate[] certs)
if (sDefaultTrustManager == null) {
if (Config.LOGD) {
Log.d(LOG_TAG,"hasValidCertificateChain():" +
" null default trust manager!");
}
throw new IOException("null default trust manager");
}
boolean trusted = (certs != null && (certs.length > 0));
if (trusted) {
try {
// the authtype we pass in doesn't actually matter
sDefaultTrustManager.checkServerTrusted((X509Certificate[]) certs, "RSA");
} catch (GeneralSecurityException e) {
String exceptionMessage = e != null ? e.getMessage() : "none";
if (Config.LOGD) {
Log.d(LOG_TAG,"hasValidCertificateChain(): sec. exception: "
+ exceptionMessage);
}
trusted = false;
}
}
return trusted;
| private void | validateSocket(javax.net.ssl.SSLSocket sslSock, java.lang.String destHost)
if (Config.LOGV) {
Log.v(LOG_TAG,"validateSocket() to host "+destHost);
}
String relaxSslCheck = SystemProperties.get("socket.relaxsslcheck");
String secure = SystemProperties.get("ro.secure");
// only allow relaxing the ssl check on non-secure builds where the relaxation is
// specifically requested.
if ("0".equals(secure) && "yes".equals(relaxSslCheck)) {
if (Config.LOGD) {
Log.d(LOG_TAG,"sys prop socket.relaxsslcheck is set," +
" ignoring invalid certs");
}
return;
}
Certificate[] certs = null;
sslSock.setUseClientMode(true);
sslSock.startHandshake();
certs = sslSock.getSession().getPeerCertificates();
// check that the root certificate in the chain belongs to
// a CA we trust
if (certs == null) {
Log.e(LOG_TAG,
"[SSLCertificateSocketFactory] no trusted root CA");
throw new IOException("no trusted root CA");
}
if (Config.LOGV) {
Log.v(LOG_TAG,"validateSocket # certs = " +certs.length);
}
if (!hasValidCertificateChain(certs)) {
if (Config.LOGD) {
Log.d(LOG_TAG,"validateSocket(): certificate untrusted!");
}
throw new IOException("Certificate untrusted");
}
X509Certificate lastChainCert = (X509Certificate) certs[0];
if (!DomainNameChecker.match(lastChainCert, destHost)) {
if (Config.LOGD) {
Log.d(LOG_TAG,"validateSocket(): domain name check failed");
}
throw new IOException("Domain Name check failed");
}
|
|