📄 sslhandshakeprotocol.java
字号:
}
else {
throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE);
}
}
catch (CertificateException ex) {
throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE,
ex.getMessage());
}
catch (IOException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage() == null ? ex.getClass().getName() :
ex.getMessage());
}
if (secret[0] == 0) {
byte[] tmp = new byte[secret.length - 1];
System.arraycopy(secret, 1, tmp, 0, secret.length - 1);
secret = tmp;
}
sendMessage(CLIENT_KEY_EXCHANGE_MSG, secret);
// Calculate the master secret
calculateMasterSecret();
/* DEBUG */ log.debug("Generating key data");
// Generate the keys etc and put the cipher into use
byte[] keydata;
int length = 0;
length += pendingCipherSuite.getKeyLength() * 2;
length += pendingCipherSuite.getMACLength() * 2;
length += pendingCipherSuite.getIVLength() * 2;
ByteArrayOutputStream out = new ByteArrayOutputStream();
MD5Digest md5 = new MD5Digest();
SHA1Digest sha1 = new SHA1Digest();
int turn = 0;
while (out.size() < length) {
md5.reset();
sha1.reset();
for (int i = 0; i <= turn; i++) {
sha1.update( (byte) ('A' + turn));
}
sha1.update(masterSecret, 0, masterSecret.length);
sha1.update(serverRandom, 0, serverRandom.length);
sha1.update(clientRandom, 0, clientRandom.length);
md5.update(masterSecret, 0, masterSecret.length);
byte[] tmp = new byte[sha1.getDigestSize()];
sha1.doFinal(tmp, 0);
md5.update(tmp, 0, tmp.length);
tmp = new byte[md5.getDigestSize()];
md5.doFinal(tmp, 0);
// Write out a block of key data
out.write(tmp, 0, tmp.length);
turn++;
}
keydata = out.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(keydata);
byte[] encryptKey = new byte[pendingCipherSuite.getKeyLength()];
byte[] encryptIV = new byte[pendingCipherSuite.getIVLength()];
byte[] encryptMAC = new byte[pendingCipherSuite.getMACLength()];
byte[] decryptKey = new byte[pendingCipherSuite.getKeyLength()];
byte[] decryptIV = new byte[pendingCipherSuite.getIVLength()];
byte[] decryptMAC = new byte[pendingCipherSuite.getMACLength()];
try {
in.read(encryptMAC);
in.read(decryptMAC);
in.read(encryptKey);
in.read(decryptKey);
in.read(encryptIV);
in.read(decryptIV);
}
catch (IOException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage() == null ? ex.getClass().getName() :
ex.getMessage());
}
pendingCipherSuite.init(encryptKey, encryptIV, encryptMAC,
decryptKey, decryptIV, decryptMAC);
currentHandshakeStep = SERVER_HELLO_DONE_MSG;
// Send the change cipher spec
socket.sendCipherChangeSpec(pendingCipherSuite);
// Send the finished msg
sendHandshakeFinished();
}
SSLCipherSuite getPendingCipherSuite() {
return pendingCipherSuite;
}
void updateHandshakeHashes(byte[] data) {
/* DEBUG */ log.debug("Updating handshake hashes");
handshakeMD5.update(data, 0, data.length);
handshakeSHA1.update(data, 0, data.length);
}
private void completeHandshakeHashes() {
/* DEBUG */ log.debug("Completing handshake hashes");
// Complete the handshale hashes
handshakeMD5.update( (byte) 0x43);
handshakeMD5.update( (byte) 0x4c);
handshakeMD5.update( (byte) 0x4e);
handshakeMD5.update( (byte) 0x54);
handshakeMD5.update(masterSecret, 0, masterSecret.length);
for (int i = 0; i < 48; i++) {
handshakeMD5.update( (byte) 0x36);
}
byte[] tmp = new byte[handshakeMD5.getDigestSize()];
handshakeMD5.doFinal(tmp, 0);
handshakeMD5.reset();
/* DEBUG */log.debug("Master secret is " + masterSecret.length + " bytes long and first byte is " + masterSecret[0]);
handshakeMD5.update(masterSecret, 0, masterSecret.length);
for (int i = 0; i < 48; i++) {
handshakeMD5.update( (byte) 0x5c);
}
handshakeMD5.update(tmp, 0, tmp.length);
handshakeSHA1.update( (byte) 0x43);
handshakeSHA1.update( (byte) 0x4c);
handshakeSHA1.update( (byte) 0x4e);
handshakeSHA1.update( (byte) 0x54);
handshakeSHA1.update(masterSecret, 0, masterSecret.length);
for (int i = 0; i < 40; i++) {
handshakeSHA1.update( (byte) 0x36);
}
tmp = new byte[handshakeSHA1.getDigestSize()];
handshakeSHA1.doFinal(tmp, 0);
handshakeSHA1.reset();
handshakeSHA1.update(masterSecret, 0, masterSecret.length);
for (int i = 0; i < 40; i++) {
handshakeSHA1.update( (byte) 0x5c);
}
handshakeSHA1.update(tmp, 0, tmp.length);
}
private void sendHandshakeFinished() throws SSLException {
completeHandshakeHashes();
/* DEBUG */ log.debug("Sending client FINISHED");
byte[] msg = new byte[handshakeMD5.getDigestSize()
+ handshakeSHA1.getDigestSize()];
handshakeMD5.doFinal(msg, 0);
handshakeSHA1.doFinal(msg, handshakeMD5.getDigestSize());
sendMessage(FINISHED_MSG, msg);
currentHandshakeStep = FINISHED_MSG;
}
private void onCertificateMsg(byte[] msg) throws SSLException {
ByteArrayInputStream in = new ByteArrayInputStream(msg);
// Get the length of the certificate chain
int length2 = (in.read() & 0xFF) << 16
| (in.read() & 0xFF) << 8
| (in.read() & 0xFF);
try {
boolean trusted = false;
X509Certificate chainCert;
while(in.available() > 0 && !trusted) {
// The length of the next certificate (we dont need this as rthe DERInputStream does the work
int certlen = (in.read() & 0xFF) << 16
| (in.read() & 0xFF) << 8
| (in.read() & 0xFF);
// Now read the certificate
DERInputStream der = new
DERInputStream(in);
ASN1Sequence certificate =
(ASN1Sequence) der.readObject();
// Get the x509 certificate structure
chainCert = new X509Certificate(X509CertificateStructure.getInstance(
certificate));
if(x509==null)
x509 = chainCert;
// Verify if this part of the chain is trusted
try {
trusted = context.getTrustedCACerts().isTrustedCertificate(
chainCert,
context.isInvalidCertificateAllowed(),
context.isUntrustedCertificateAllowed());
}
catch (SSLException ex1) {
/* DEBUG */log.warn("Failed to verify certificate against trust store (This may not be an error)", ex1);
}
}
if(!trusted)
throw new SSLException(SSLException.BAD_CERTIFICATE,
"The server certificate was either invalid or untrusted");
}
catch (IOException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage());
}
/* DEBUG */ log.debug("Server X509 Certificate...");
/* DEBUG */ log.debug("Subject DN: " + x509.getSubjectDN());
/* DEBUG */ log.debug("Issuer DN: " + x509.getIssuerDN());
currentHandshakeStep = CERTIFICATE_MSG;
}
private void onServerHelloMsg(byte[] msg) throws SSLException {
try {
ByteArrayInputStream in = new ByteArrayInputStream(msg);
majorVersion = in.read();
minorVersion = in.read();
serverRandom = new byte[32];
in.read(serverRandom);
sessionID = new byte[ (in.read() & 0xFF)];
in.read(sessionID);
cipherSuiteID = new SSLCipherSuiteID(in.read(), in.read());
pendingCipherSuite = (SSLCipherSuite)
context.getCipherSuiteClass(cipherSuiteID).newInstance();
compressionID = in.read();
currentHandshakeStep = SERVER_HELLO_MSG;
}
catch (IllegalAccessException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage() == null ? ex.getClass().getName() :
ex.getMessage());
}
catch (InstantiationException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage() == null ? ex.getClass().getName() :
ex.getMessage());
}
catch (IOException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage() == null ? ex.getClass().getName() :
ex.getMessage());
}
}
private void sendClientHello() throws SSLException {
/* DEBUG */ log.debug("Sending client HELLO");
ByteArrayOutputStream msg = new ByteArrayOutputStream();
try {
clientRandom = new byte[32];
context.getRND().nextBytes(clientRandom);
long time = System.currentTimeMillis();
clientRandom[0] = (byte) ( (time >> 24) & 0xFF);
clientRandom[1] = (byte) ( (time >> 16) & 0xFF);
clientRandom[2] = (byte) ( (time >> 8) & 0xFF);
clientRandom[3] = (byte) (time & 0xFF);
// Write the version
msg.write(SSLTransport.VERSION_MAJOR);
msg.write(SSLTransport.VERSION_MINOR);
// Write the random bytes
msg.write(clientRandom);
// Write the session identifier - currently were not caching so zero length
msg.write(0);
// Write the cipher ids - TODO: we need to set the preferred as first
SSLCipherSuiteID[] ids = context.getCipherSuiteIDs();
msg.write(0);
msg.write(ids.length * 2);
for (int i = 0; i < ids.length; i++) {
msg.write(ids[i].id1);
msg.write(ids[i].id2);
}
// Compression - no compression is currently supported
msg.write(1);
msg.write(0);
}
catch (IOException ex) {
throw new SSLException(SSLException.INTERNAL_ERROR,
ex.getMessage() == null ? ex.getClass().getName() :
ex.getMessage());
}
sendMessage(CLIENT_HELLO_MSG, msg.toByteArray());
currentHandshakeStep = CLIENT_HELLO_MSG;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -