in modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java [365:533]
void processServerHelloDone() {
PrivateKey clientKey = null;
if (serverCert != null) {
if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
unexpectedMessage();
return;
}
verifyServerCert();
} else {
if (session.cipherSuite.keyExchange != CipherSuite.KeyExchange_DH_anon
&& session.cipherSuite.keyExchange != CipherSuite.KeyExchange_DH_anon_EXPORT) {
unexpectedMessage();
return;
}
}
// Client certificate
if (certificateRequest != null) {
X509Certificate[] certs = null;
String clientAlias = ((X509ExtendedKeyManager) parameters
.getKeyManager()).chooseClientAlias(certificateRequest
.getTypesAsString(),
certificateRequest.certificate_authorities, null);
if (clientAlias != null) {
X509ExtendedKeyManager km = (X509ExtendedKeyManager) parameters
.getKeyManager();
certs = km.getCertificateChain((clientAlias));
clientKey = km.getPrivateKey(clientAlias);
}
session.localCertificates = certs;
clientCert = new CertificateMessage(certs);
send(clientCert);
}
// Client key exchange
if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
// RSA encrypted premaster secret message
Cipher c;
try {
c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
if (serverKeyExchange != null) {
c.init(Cipher.ENCRYPT_MODE, serverKeyExchange
.getRSAPublicKey());
} else {
c.init(Cipher.ENCRYPT_MODE, serverCert.certs[0]);
}
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR,
"Unexpected exception", e);
return;
}
preMasterSecret = new byte[48];
parameters.getSecureRandom().nextBytes(preMasterSecret);
System.arraycopy(clientHello.client_version, 0, preMasterSecret, 0,
2);
try {
clientKeyExchange = new ClientKeyExchange(c
.doFinal(preMasterSecret),
serverHello.server_version[1] == 1);
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR,
"Unexpected exception", e);
return;
}
} else {
PublicKey serverPublic;
KeyAgreement agreement = null;
DHParameterSpec spec;
try {
KeyFactory kf = null;
try {
kf = KeyFactory.getInstance("DH");
} catch (NoSuchAlgorithmException e) {
kf = KeyFactory.getInstance("DiffieHellman");
}
try {
agreement = KeyAgreement.getInstance("DH");
} catch (NoSuchAlgorithmException ee) {
agreement = KeyAgreement.getInstance("DiffieHellman");
}
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("DH");
} catch (NoSuchAlgorithmException e) {
kpg = KeyPairGenerator.getInstance("DiffieHellman");
}
if (serverKeyExchange != null) {
serverPublic = kf.generatePublic(new DHPublicKeySpec(
serverKeyExchange.par3, serverKeyExchange.par1,
serverKeyExchange.par2));
spec = new DHParameterSpec(serverKeyExchange.par1,
serverKeyExchange.par2);
} else {
serverPublic = serverCert.certs[0].getPublicKey();
spec = ((DHPublicKey) serverPublic).getParams();
}
kpg.initialize(spec);
KeyPair kp = kpg.generateKeyPair();
Key key = kp.getPublic();
if (clientCert != null
&& serverCert != null
&& (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS)) {
PublicKey client_pk = clientCert.certs[0].getPublicKey();
PublicKey server_pk = serverCert.certs[0].getPublicKey();
if (client_pk instanceof DHKey
&& server_pk instanceof DHKey) {
if (((DHKey) client_pk).getParams().getG().equals(
((DHKey) server_pk).getParams().getG())
&& ((DHKey) client_pk).getParams().getP()
.equals(((DHKey) server_pk).getParams().getG())) {
// client cert message DH public key parameters
// matched those specified by the
// server in its certificate,
clientKeyExchange = new ClientKeyExchange(); // empty
}
}
} else {
clientKeyExchange = new ClientKeyExchange(
((DHPublicKey) key).getY());
}
key = kp.getPrivate();
agreement.init(key);
agreement.doPhase(serverPublic, true);
preMasterSecret = agreement.generateSecret();
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR,
"Unexpected exception", e);
return;
}
}
if (clientKeyExchange != null) {
send(clientKeyExchange);
}
computerMasterSecret();
// send certificate verify for all certificates except those containing
// fixed DH parameters
if (clientCert != null && !clientKeyExchange.isEmpty()) {
// Certificate verify
DigitalSignature ds = new DigitalSignature(
session.cipherSuite.keyExchange);
ds.init(clientKey);
if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
ds.setMD5(io_stream.getDigestMD5());
ds.setSHA(io_stream.getDigestSHA());
} else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
|| session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) {
ds.setSHA(io_stream.getDigestSHA());
// The Signature should be empty in case of anonimous signature algorithm:
// } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon ||
// session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
}
certificateVerify = new CertificateVerify(ds.sign());
send(certificateVerify);
}
sendChangeCipherSpec();
}