privKey = parameters.getKeyManager().getPrivateKey(alias);
send(serverCert);
}
// create and send server key exchange message if needed
RSAPublicKey rsakey = null;
DHPublicKeySpec dhkeySpec = null;
byte[] hash = null;
BigInteger p = null;
BigInteger g = null;
KeyPairGenerator kpg = null;
try {
if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
PublicKey pk = serverCert.certs[0].getPublicKey();
if (getRSAKeyLength(pk) > 512) {
// key is longer than 512 bits
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
}
} else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
|| cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT
|| cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
|| cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT
|| cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_anon
|| cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
try {
kpg = KeyPairGenerator.getInstance("DH");
} catch (NoSuchAlgorithmException ee) {
kpg = KeyPairGenerator.getInstance("DiffieHellman");
}
p = new BigInteger(1, DHParameters.getPrime());
g = new BigInteger("2");
DHParameterSpec spec = new DHParameterSpec(p, g);
kpg.initialize(spec);
}
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
}
if (kpg != null) {
// need to send server key exchange message
DigitalSignature ds = new DigitalSignature(cipher_suite.keyExchange);
KeyPair kp = null;
try {
kp = kpg.genKeyPair();
if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
rsakey = (RSAPublicKey) kp.getPublic();
} else {
DHPublicKey dhkey = (DHPublicKey) kp.getPublic();
KeyFactory kf = null;
try {
kf = KeyFactory.getInstance("DH");
} catch (NoSuchAlgorithmException e) {
kf = KeyFactory.getInstance("DiffieHellman");
}
dhkeySpec = (DHPublicKeySpec) kf.getKeySpec(dhkey,
DHPublicKeySpec.class);
}
if (!cipher_suite.isAnonymous()) { // calculate signed_params
// init by private key which correspond to
// server certificate
ds.init(privKey);
// use emphemeral key for key exchange
privKey = kp.getPrivate();
ds.update(clientHello.getRandom());
ds.update(serverHello.getRandom());
byte[] tmp;
byte[] tmpLength = new byte[2];
//FIXME 1_byte==0x00
if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
tmp = rsakey.getModulus().toByteArray();
tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
tmpLength[1] = (byte) (tmp.length & 0xFF);
ds.update(tmpLength);
ds.update(tmp);
tmp = rsakey.getPublicExponent().toByteArray();
tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
tmpLength[1] = (byte) (tmp.length & 0xFF);
ds.update(tmp);
} else {
tmp = dhkeySpec.getP().toByteArray();
tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
tmpLength[1] = (byte) (tmp.length & 0xFF);
ds.update(tmp);
tmp = dhkeySpec.getG().toByteArray();
tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
tmpLength[1] = (byte) (tmp.length & 0xFF);
ds.update(tmp);
tmp = dhkeySpec.getY().toByteArray();
tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
tmpLength[1] = (byte) (tmp.length & 0xFF);
ds.update(tmp);
}
hash = ds.sign();
} else {
privKey = kp.getPrivate(); // use emphemeral key for key exchange
}
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
}
if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
serverKeyExchange = new ServerKeyExchange(rsakey.getModulus(),
rsakey.getPublicExponent(), null, hash);
} else {
serverKeyExchange = new ServerKeyExchange(p,
g, dhkeySpec.getY(), hash);
}
send(serverKeyExchange);