SSLPeerUnverifiedException without client's cert in server

Go To StackoverFlow.com

0

I'm trying to connect client and server with the same keystore . The client socket can get peer cert,while the server socket can't get peer cert but port. It failed to get cert and reported abnormal of SSLPeerUnverifiedException. Modified problems confused me several days,pls help to solve it,thanks

my android code is as follows:

client:

    java.security.Security.addProvider(
        new org.bouncycastle.jce.provider.BouncyCastleProvider());

SSLContext sslcontext = SSLContext.getInstance("TLS");
           sslcontext.init(getKeyManagers(), {new DummyTrustManager()}, null);
SocketFactory socketFactory = sslcontext.getSocketFactory();

SSLSocket socket = (SSLSocket) socketFactory.createSocket("127.0.0.1", 8080); 
socket.getSession().getLocalCertificates();
socket.getSession().getPeerHost();
socket.getSession().getPeerPort();
socket.getSession().getPeerCertificates();`

server:

    SSLContext sslcontext = SSLContext.getInstance("TLS");
    sslcontext.init(getKeyManagers(), {new DummyTrustManager()}, null);
ServerSocketFactory   mFactory = sslcontext.getServerSocketFactory();
ServerSocket serverSocket =mFactory.createServerSocket(8080);
SSLSocket clientSocket = serverSocket.accept();
socket.getSession().getLocalCertificates();
socket.getSession().getPeerHost();
socket.getSession().getPeerPort();
socket.getSession().getPeerCertificates();`

TrustManager:

import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class DummyTrustManager implements X509TrustManager {
  public void checkClientTrusted(X509Certificate[] chain, String authType) {
    // Does not throw CertificateException: all chains trusted
    return;
  }
  public void checkServerTrusted(X509Certificate[] chain, String authType) {
    // Does not throw CertificateException: all chains trusted
    return;
  }
  public X509Certificate[] getAcceptedIssuers() {
    return new X509Certificate[0];
  }
}

KeyStore :

public void initializeKeyStore(String id) {
try {
  Log.v(LOG_TAG, "Generating key pair ...");
  KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
  KeyPair keyPair = kg.generateKeyPair();


  Log.v(LOG_TAG, "Generating certificate ...");
  String name = getCertificateName(id);
  X509Certificate cert = SslUtil.generateX509V3Certificate(keyPair, name);
  Certificate[] chain = {cert};


  Log.v(LOG_TAG, "Adding key to keystore  ...");
  mKeyStore.setKeyEntry(
      LOCAL_IDENTITY_ALIAS, keyPair.getPrivate(), null, chain);


  Log.d(LOG_TAG, "Key added!");
} catch (GeneralSecurityException e) {
  throw new IllegalStateException("Unable to create identity KeyStore", e);
}
store(mKeyStore);}




public synchronized KeyManager[] getKeyManagers()
  throws GeneralSecurityException {
if (mKeyStore == null) {
  throw new NullPointerException("null mKeyStore");
}
KeyManagerFactory factory =
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
factory.init(mKeyStore, "".toCharArray());
return factory.getKeyManagers();

}

cert:

public static X509Certificate generateX509V3Certificate(KeyPair pair,
  String name) throws GeneralSecurityException {
Calendar calendar = Calendar.getInstance();
calendar.set(2009, 0, 1);
Date notBefore  = new Date(calendar.getTimeInMillis());
calendar.set(2099, 0, 1);
Date notAfter = new Date(calendar.getTimeInMillis());

BigInteger serialNumber = BigInteger.valueOf(Math.abs(
    System.currentTimeMillis()));

return generateX509V3Certificate(pair, name, notBefore, notAfter,
    serialNumber);

}

public static X509Certificate generateX509V3Certificate(KeyPair pair,
  String name, Date notBefore, Date notAfter, BigInteger serialNumber)
    throws GeneralSecurityException {
java.security.Security.addProvider(
    new org.bouncycastle.jce.provider.BouncyCastleProvider());
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
X509Name dnName = new X509Name(name);

certGen.setSerialNumber(serialNumber);
certGen.setIssuerDN(dnName);
certGen.setSubjectDN(dnName);   // note: same as issuer
certGen.setNotBefore(notBefore);
certGen.setNotAfter(notAfter);
certGen.setPublicKey(pair.getPublic());
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");


certGen.addExtension(X509Extensions.BasicConstraints, true,
    new BasicConstraints(false));

certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature
    | KeyUsage.keyEncipherment | KeyUsage.keyCertSign));
certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(
    KeyPurposeId.id_kp_serverAuth));


AuthorityKeyIdentifier authIdentifier = createAuthorityKeyIdentifier(
    pair.getPublic(), dnName, serialNumber);

certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, true,
    authIdentifier);
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, true,
    new SubjectKeyIdentifierStructure(pair.getPublic()));


certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(
    new GeneralName(GeneralName.rfc822Name, "googletv@test.test")));


// This method is deprecated, but Android Eclair does not provide the 
// generate() methods.
X509Certificate cert = certGen.generateX509Certificate(pair.getPrivate(), "BC");
return cert;

}

enter code here
2012-04-04 06:38
by user1312018


0

You probably need to call SSLServerSocket.setNeedClientAuth() to have the server side require client authentication. The client will then send its certificate, and you should be able to get it with getPeerCertificates().

Reference:

http://docs.oracle.com/javase/6/docs/api/javax/net/ssl/SSLServerSocket.html#setNeedClientAuth%28boolean%29

2012-04-04 07:14
by Nikolay Elenkov
okay ,i will try it. But i remembered call SSLServerSocket.setNeedClientAuth(), it's not ok - user1312018 2012-04-04 08:17
Sorry, I'm too late to reply. It run okay in android2.3 and android 2.4 , not in android 2.2. I trace it and found that it may be something wrong in openssl. How can i to resolve it - user1312018 2012-04-06 10:44
If it is a bug in the firmware, you can't really. Why do you think it's are problem with openssl - Nikolay Elenkov 2012-04-06 13:55
http://stackoverflow.com/questions/9538714/android-2-2-ssl-bug-with-client-certificate. I traced it and found the word (If we are a client ,cert-chain includes the peer's own certificate; if we are a server ,it does not.) in the function SSLgetpeercertchain in file SSL_lib.c - user1312018 2012-04-08 05:25
Now i get an other exception. Like this. http://stackoverflow.com/questions/9328699/ssl-handshake-failure-for-android-2-2-version - user1312018 2012-04-08 05:40
(SSL handshake aborted: ssl=0x4942f0: Failure in SSL library, usually a protocol error: 140770FC:SSL routines: SSL23GETSERVERHELLO: unknown protocol (external/openssl/s23clnt.c:683 0xacffa3f8:0x00000000)) . And i google it and find the url http://stackoverflow.com/questions/9328699/ssl-handshake-failure-for-android-2-2-version. I save the client's cert in server and the server's cert in client.How can i to resolve it - user1312018 2012-04-08 06:01


0

I'm trying to connect client and server with the same keystore

That's only a valid thing to do it the client entity and the server entity are really the same legal entity.

If not, you are certainly barking up the wrong tree entirely, in a way which has very profound legal ramifications. I suggest you seek advice from the business/legal side before continuing.

2012-04-04 09:39
by user207421
Ads