use of javax.crypto.KeyAgreement in project XobotOS by xamarin.
the class ClientHandshakeImpl method processServerHelloDone.
/**
* Processes ServerHelloDone: makes verification of the server messages; sends
* client messages, computers masterSecret, sends ChangeCipherSpec
*/
void processServerHelloDone() {
PrivateKey clientKey = null;
if (serverCert != null) {
if (session.cipherSuite.isAnonymous()) {
unexpectedMessage();
return;
}
verifyServerCert();
} else {
if (!session.cipherSuite.isAnonymous()) {
unexpectedMessage();
return;
}
}
// Client certificate
if (certificateRequest != null) {
X509Certificate[] certs = null;
// obtain certificates from key manager
String alias = null;
String[] certTypes = certificateRequest.getTypesAsString();
X500Principal[] issuers = certificateRequest.certificate_authorities;
X509KeyManager km = parameters.getKeyManager();
if (km instanceof X509ExtendedKeyManager) {
X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) km;
if (this.socketOwner != null) {
alias = ekm.chooseClientAlias(certTypes, issuers, this.socketOwner);
} else {
alias = ekm.chooseEngineClientAlias(certTypes, issuers, this.engineOwner);
}
if (alias != null) {
certs = ekm.getCertificateChain(alias);
}
} else {
alias = km.chooseClientAlias(certTypes, issuers, this.socketOwner);
if (alias != null) {
certs = km.getCertificateChain(alias);
}
}
session.localCertificates = certs;
clientCert = new CertificateMessage(certs);
clientKey = km.getPrivateKey(alias);
send(clientCert);
}
// Client key exchange
if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_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 {
try {
KeyFactory kf = KeyFactory.getInstance("DH");
KeyAgreement agreement = KeyAgreement.getInstance("DH");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
PublicKey serverPublic;
DHParameterSpec spec;
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.KEY_EXCHANGE_DHE_RSA || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_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,
// empty
clientKeyExchange = new ClientKeyExchange();
}
}
} 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();
// fixed DH parameters
if (clientCert != null && !clientKeyExchange.isEmpty()) {
// Certificate verify
String authType = clientKey.getAlgorithm();
DigitalSignature ds = new DigitalSignature(authType);
ds.init(clientKey);
if ("RSA".equals(authType)) {
ds.setMD5(io_stream.getDigestMD5());
ds.setSHA(io_stream.getDigestSHA());
} else if ("DSA".equals(authType)) {
ds.setSHA(io_stream.getDigestSHA());
// The Signature should be empty in case of anonymous signature algorithm:
// } else if ("DH".equals(authType)) {
}
certificateVerify = new CertificateVerify(ds.sign());
send(certificateVerify);
}
sendChangeCipherSpec();
}
use of javax.crypto.KeyAgreement in project XobotOS by xamarin.
the class ServerHandshakeImpl method unwrap.
/**
* Proceses inbound handshake messages
* @param bytes
*/
@Override
public void unwrap(byte[] bytes) {
io_stream.append(bytes);
while (io_stream.available() > 0) {
int handshakeType;
int length;
io_stream.mark();
try {
handshakeType = io_stream.read();
length = io_stream.readUint24();
if (io_stream.available() < length) {
io_stream.reset();
return;
}
switch(handshakeType) {
case // CLIENT_HELLO
1:
if (clientHello != null && this.status != FINISHED) {
// Client hello has been received during handshake
unexpectedMessage();
return;
}
// if protocol planed to send Hello Request message
// - cancel this demand.
needSendHelloRequest = false;
clientHello = new ClientHello(io_stream, length);
if (nonBlocking) {
delegatedTasks.add(new DelegatedTask(new Runnable() {
public void run() {
processClientHello();
}
}, this));
return;
}
processClientHello();
break;
case // CLIENT CERTIFICATE
11:
if (isResuming || certificateRequest == null || serverHelloDone == null || clientCert != null) {
unexpectedMessage();
return;
}
clientCert = new CertificateMessage(io_stream, length);
if (clientCert.certs.length == 0) {
if (parameters.getNeedClientAuth()) {
fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "HANDSHAKE FAILURE: no client certificate received");
}
} else {
String authType = clientCert.getAuthType();
try {
parameters.getTrustManager().checkClientTrusted(clientCert.certs, authType);
} catch (CertificateException e) {
fatalAlert(AlertProtocol.BAD_CERTIFICATE, "Untrusted Client Certificate ", e);
}
session.peerCertificates = clientCert.certs;
}
break;
case // CERTIFICATE_VERIFY
15:
if (isResuming || clientKeyExchange == null || clientCert == null || //client certificate
clientKeyExchange.isEmpty() || // parameters
certificateVerify != null || changeCipherSpecReceived) {
unexpectedMessage();
return;
}
certificateVerify = new CertificateVerify(io_stream, length);
String authType = clientCert.getAuthType();
DigitalSignature ds = new DigitalSignature(authType);
ds.init(clientCert.certs[0]);
byte[] md5_hash = null;
byte[] sha_hash = null;
if ("RSA".equals(authType)) {
md5_hash = io_stream.getDigestMD5withoutLast();
sha_hash = io_stream.getDigestSHAwithoutLast();
} else if ("DSA".equals(authType)) {
sha_hash = io_stream.getDigestSHAwithoutLast();
// The Signature should be empty in case of anonymous signature algorithm:
// } else if ("DH".equals(authType)) {
}
ds.setMD5(md5_hash);
ds.setSHA(sha_hash);
if (!ds.verifySignature(certificateVerify.signedHash)) {
fatalAlert(AlertProtocol.DECRYPT_ERROR, "DECRYPT ERROR: CERTIFICATE_VERIFY incorrect signature");
}
break;
case // CLIENT_KEY_EXCHANGE
16:
if (isResuming || serverHelloDone == null || clientKeyExchange != null || (clientCert == null && parameters.getNeedClientAuth())) {
unexpectedMessage();
return;
}
if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
clientKeyExchange = new ClientKeyExchange(io_stream, length, serverHello.server_version[1] == 1, true);
Cipher c = null;
try {
c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, privKey);
preMasterSecret = c.doFinal(clientKeyExchange.exchange_keys);
// check preMasterSecret:
if (preMasterSecret.length != 48 || preMasterSecret[0] != clientHello.client_version[0] || preMasterSecret[1] != clientHello.client_version[1]) {
// incorrect preMasterSecret
// prevent an attack (see TLS 1.0 spec., 7.4.7.1.)
preMasterSecret = new byte[48];
parameters.getSecureRandom().nextBytes(preMasterSecret);
}
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
}
} else {
// diffie hellman key exchange
clientKeyExchange = new ClientKeyExchange(io_stream, length, serverHello.server_version[1] == 1, false);
if (clientKeyExchange.isEmpty()) {
// TODO check that client cert. DH params
// matched server cert. DH params
// client cert. contains fixed DH parameters
preMasterSecret = ((DHPublicKey) clientCert.certs[0].getPublicKey()).getY().toByteArray();
} else {
try {
KeyFactory kf = KeyFactory.getInstance("DH");
KeyAgreement agreement = KeyAgreement.getInstance("DH");
PublicKey clientPublic = kf.generatePublic(new DHPublicKeySpec(new BigInteger(1, clientKeyExchange.exchange_keys), serverKeyExchange.par1, serverKeyExchange.par2));
agreement.init(privKey);
agreement.doPhase(clientPublic, true);
preMasterSecret = agreement.generateSecret();
} catch (Exception e) {
fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
return;
}
}
}
computerMasterSecret();
break;
case // FINISHED
20:
if (!isResuming && !changeCipherSpecReceived) {
unexpectedMessage();
return;
}
clientFinished = new Finished(io_stream, length);
verifyFinished(clientFinished.getData());
session.context = parameters.getServerSessionContext();
parameters.getServerSessionContext().putSession(session);
if (!isResuming) {
sendChangeCipherSpec();
} else {
session.lastAccessedTime = System.currentTimeMillis();
status = FINISHED;
}
break;
default:
unexpectedMessage();
return;
}
} catch (IOException e) {
// io stream dosn't contain complete handshake message
io_stream.reset();
return;
}
}
}
use of javax.crypto.KeyAgreement in project geode by apache.
the class HandShake method readCredentials.
// This assumes that authentication is the last piece of info in handshake
public static Properties readCredentials(DataInputStream dis, DataOutputStream dos, DistributedSystem system) throws GemFireSecurityException, IOException {
boolean requireAuthentication = securityService.isClientSecurityRequired();
Properties credentials = null;
try {
byte secureMode = dis.readByte();
throwIfMissingRequiredCredentials(requireAuthentication, secureMode != CREDENTIALS_NONE);
if (secureMode == CREDENTIALS_NORMAL) {
if (requireAuthentication) {
credentials = DataSerializer.readProperties(dis);
} else {
// ignore the credentials
DataSerializer.readProperties(dis);
}
} else if (secureMode == CREDENTIALS_DHENCRYPT) {
boolean sendAuthentication = dis.readBoolean();
InternalLogWriter securityLogWriter = (InternalLogWriter) system.getSecurityLogWriter();
// Get the symmetric encryption algorithm to be used
String skAlgo = DataSerializer.readString(dis);
// Get the public key of the other side
byte[] keyBytes = DataSerializer.readByteArray(dis);
byte[] challenge = null;
PublicKey pubKey = null;
if (requireAuthentication) {
// Generate PublicKey from encoded form
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFact = KeyFactory.getInstance("DH");
pubKey = keyFact.generatePublic(x509KeySpec);
// Send the public key to other side
keyBytes = dhPublicKey.getEncoded();
challenge = new byte[64];
random.nextBytes(challenge);
// sign the challenge from client.
if (sendAuthentication) {
// Get the challenge string from client
byte[] clientChallenge = DataSerializer.readByteArray(dis);
if (privateKeyEncrypt == null) {
throw new AuthenticationFailedException(LocalizedStrings.HandShake_SERVER_PRIVATE_KEY_NOT_AVAILABLE_FOR_CREATING_SIGNATURE.toLocalizedString());
}
// Sign the challenge from client and send it to the client
Signature sig = Signature.getInstance(privateKeySignAlgo);
sig.initSign(privateKeyEncrypt);
sig.update(clientChallenge);
byte[] signedBytes = sig.sign();
dos.writeByte(REPLY_OK);
DataSerializer.writeByteArray(keyBytes, dos);
// DataSerializer.writeString(privateKeyAlias, dos);
DataSerializer.writeString(privateKeySubject, dos);
DataSerializer.writeByteArray(signedBytes, dos);
securityLogWriter.fine("HandShake: sent the signed client challenge");
} else {
// These two lines should not be moved before the if{} statement in
// a common block for both if...then...else parts. This is to handle
// the case when an AuthenticationFailedException is thrown by the
// if...then part when sending the signature.
dos.writeByte(REPLY_OK);
DataSerializer.writeByteArray(keyBytes, dos);
}
// Now send the server challenge
DataSerializer.writeByteArray(challenge, dos);
securityLogWriter.fine("HandShake: sent the public key and challenge");
dos.flush();
// Read and decrypt the credentials
byte[] encBytes = DataSerializer.readByteArray(dis);
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(dhPrivateKey);
ka.doPhase(pubKey, true);
Cipher decrypt;
int keysize = getKeySize(skAlgo);
int blocksize = getBlockSize(skAlgo);
if (keysize == -1 || blocksize == -1) {
SecretKey sKey = ka.generateSecret(skAlgo);
decrypt = Cipher.getInstance(skAlgo);
decrypt.init(Cipher.DECRYPT_MODE, sKey);
} else {
String algoStr = getDhAlgoStr(skAlgo);
byte[] sKeyBytes = ka.generateSecret();
SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
}
byte[] credentialBytes = decrypt.doFinal(encBytes);
ByteArrayInputStream bis = new ByteArrayInputStream(credentialBytes);
DataInputStream dinp = new DataInputStream(bis);
credentials = DataSerializer.readProperties(dinp);
byte[] challengeRes = DataSerializer.readByteArray(dinp);
// Check the challenge string
if (!Arrays.equals(challenge, challengeRes)) {
throw new AuthenticationFailedException(LocalizedStrings.HandShake_MISMATCH_IN_CHALLENGE_BYTES_MALICIOUS_CLIENT.toLocalizedString());
}
dinp.close();
} else {
if (sendAuthentication) {
// Read and ignore the client challenge
DataSerializer.readByteArray(dis);
}
dos.writeByte(REPLY_AUTH_NOT_REQUIRED);
dos.flush();
}
} else if (secureMode == SECURITY_MULTIUSER_NOTIFICATIONCHANNEL) {
// hitesh there will be no credential CCP will get credential(Principal) using
// ServerConnection..
logger.debug("readCredential where multiuser mode creating callback connection");
}
} catch (IOException ex) {
throw ex;
} catch (GemFireSecurityException ex) {
throw ex;
} catch (Exception ex) {
throw new AuthenticationFailedException(LocalizedStrings.HandShake_FAILURE_IN_READING_CREDENTIALS.toLocalizedString(), ex);
}
return credentials;
}
use of javax.crypto.KeyAgreement in project geode by apache.
the class HandShake method getDecryptCipher.
private Cipher getDecryptCipher(String dhSKAlgo, PublicKey publicKey) throws Exception {
if (_decrypt == null) {
try {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(dhPrivateKey);
ka.doPhase(publicKey, true);
Cipher decrypt;
int keysize = getKeySize(dhSKAlgo);
int blocksize = getBlockSize(dhSKAlgo);
if (keysize == -1 || blocksize == -1) {
SecretKey sKey = ka.generateSecret(dhSKAlgo);
decrypt = Cipher.getInstance(dhSKAlgo);
decrypt.init(Cipher.DECRYPT_MODE, sKey);
} else {
String algoStr = getDhAlgoStr(dhSKAlgo);
byte[] sKeyBytes = ka.generateSecret();
SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
}
_decrypt = decrypt;
} catch (Exception ex) {
throw ex;
}
}
return _decrypt;
}
use of javax.crypto.KeyAgreement in project geode by apache.
the class HandShake method getEncryptCipher.
private Cipher getEncryptCipher(String dhSKAlgo, PublicKey publicKey) throws Exception {
try {
if (_encrypt == null) {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(dhPrivateKey);
ka.doPhase(publicKey, true);
Cipher encrypt;
int keysize = getKeySize(dhSKAlgo);
int blocksize = getBlockSize(dhSKAlgo);
if (keysize == -1 || blocksize == -1) {
SecretKey sKey = ka.generateSecret(dhSKAlgo);
encrypt = Cipher.getInstance(dhSKAlgo);
encrypt.init(Cipher.ENCRYPT_MODE, sKey);
} else {
String dhAlgoStr = getDhAlgoStr(dhSKAlgo);
byte[] sKeyBytes = ka.generateSecret();
SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, dhAlgoStr);
IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
encrypt = Cipher.getInstance(dhAlgoStr + "/CBC/PKCS5Padding");
encrypt.init(Cipher.ENCRYPT_MODE, sks, ivps);
}
_encrypt = encrypt;
}
} catch (Exception ex) {
throw ex;
}
return _encrypt;
}
Aggregations