📄 tlsprotocolhandler.java
字号:
} /* * We only support RSA certificates. Lets hope * this is one. */ RSAPublicKeyStructure rsaKey = null; try { rsaKey = RSAPublicKeyStructure.getInstance(cert.certs[0].getTBSCertificate().getSubjectPublicKeyInfo().getPublicKey()); } catch (Exception e) { /* * Sorry, we have to fail ;-( */ this.failWithError(AL_fatal, AP_unsupported_certificate); } /* * Parse the servers public RSA key. */ this.serverRsaKey = new RSAKeyParameters( false, rsaKey.getModulus(), rsaKey.getPublicExponent()); connection_state = CS_SERVER_CERTIFICATE_RECEIVED; read = true; break; default: this.failWithError(AL_fatal, AP_unexpected_message); } break; case HP_FINISHED: switch (connection_state) { case CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED: /* * Read the checksum from the finished message, * it has always 12 bytes. */ byte[] receivedChecksum = new byte[12]; TlsUtils.readFully(receivedChecksum, is); assertEmpty(is); /* * Calculate our own checksum. */ byte[] checksum = new byte[12]; byte[] md5andsha1 = new byte[16 + 20]; rs.hash2.doFinal(md5andsha1, 0); TlsUtils.PRF(this.ms, TlsUtils.toByteArray("server finished"), md5andsha1, checksum); /* * Compare both checksums. */ for (int i = 0; i < receivedChecksum.length; i++) { if (receivedChecksum[i] != checksum[i]) { /* * Wrong checksum in the finished message. */ this.failWithError(AL_fatal, AP_handshake_failure); } } connection_state = CS_DONE; /* * We are now ready to receive application data. */ this.appDataReady = true; read = true; break; default: this.failWithError(AL_fatal, AP_unexpected_message); } break; case HP_SERVER_HELLO: switch (connection_state) { case CS_CLIENT_HELLO_SEND: /* * Read the server hello message */ TlsUtils.checkVersion(is, this); /* * Read the server random */ this.serverRandom = new byte[32]; TlsUtils.readFully(this.serverRandom, is); /* * Currently, we don't support session ids */ short sessionIdLength = TlsUtils.readUint8(is); byte[] sessionId = new byte[sessionIdLength]; TlsUtils.readFully(sessionId, is); /* * Find out which ciphersuite the server has * chosen. If we don't support this ciphersuite, * the TlsCipherSuiteManager will throw an * exception. */ this.chosenCipherSuite = TlsCipherSuiteManager.getCipherSuite(TlsUtils.readUint16(is), this); /* * We support only the null compression which * means no compression. */ short compressionMethod = TlsUtils.readUint8(is); if (compressionMethod != 0) { this.failWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_illegal_parameter); } assertEmpty(is); connection_state = CS_SERVER_HELLO_RECEIVED; read = true; break; default: this.failWithError(AL_fatal, AP_unexpected_message); } break; case HP_SERVER_HELLO_DONE: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: /* * There was no server key exchange message, check * that we are doing RSA key exchange. */ if (this.chosenCipherSuite.getKeyExchangeAlgorithm() != TlsCipherSuite.KE_RSA) { this.failWithError(AL_fatal, AP_unexpected_message); } /* * NB: Fall through to next case label to continue RSA key exchange */ case CS_SERVER_KEY_EXCHANGE_RECEIVED: case CS_CERTIFICATE_REQUEST_RECEIVED: assertEmpty(is); boolean isCertReq = (connection_state == CS_CERTIFICATE_REQUEST_RECEIVED); connection_state = CS_SERVER_HELLO_DONE_RECEIVED; if (isCertReq) { sendClientCertificate(); } /* * Send the client key exchange message, depending * on the key exchange we are using in our * ciphersuite. */ short ke = this.chosenCipherSuite.getKeyExchangeAlgorithm(); switch (ke) { case TlsCipherSuite.KE_RSA: /* * We are doing RSA key exchange. We will * choose a pre master secret and send it * rsa encrypted to the server. * * Prepare pre master secret. */ pms = new byte[48]; pms[0] = 3; pms[1] = 1; for (int i = 2; i < 48; i++) { pms[i] = (byte)random.nextInt(); } /* * Encode the pms and send it to the server. * * Prepare an PKCS1Encoding with good random * padding. */ RSABlindedEngine rsa = new RSABlindedEngine(); PKCS1Encoding encoding = new PKCS1Encoding(rsa); encoding.init(true, new ParametersWithRandom(this.serverRsaKey, this.random)); byte[] encrypted = null; try { encrypted = encoding.processBlock(pms, 0, pms.length); } catch (InvalidCipherTextException e) { /* * This should never happen, only during decryption. */ this.failWithError(AL_fatal, AP_internal_error); } /* * Send the encrypted pms. */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HP_CLIENT_KEY_EXCHANGE, bos); TlsUtils.writeUint24(encrypted.length + 2, bos); TlsUtils.writeUint16(encrypted.length, bos); bos.write(encrypted); byte[] message = bos.toByteArray(); rs.writeMessage((short)RL_HANDSHAKE, message, 0, message.length); break; case TlsCipherSuite.KE_DHE_RSA: /* * Send the Client Key Exchange message for * DHE key exchange. */ byte[] YcByte = this.Yc.toByteArray(); ByteArrayOutputStream DHbos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HP_CLIENT_KEY_EXCHANGE, DHbos); TlsUtils.writeUint24(YcByte.length + 2, DHbos); TlsUtils.writeUint16(YcByte.length, DHbos); DHbos.write(YcByte); byte[] DHmessage = DHbos.toByteArray(); rs.writeMessage((short)RL_HANDSHAKE, DHmessage, 0, DHmessage.length); break; default: /* * Problem during handshake, we don't know * how to handle this key exchange method. */ this.failWithError(AL_fatal, AP_unexpected_message); } connection_state = CS_CLIENT_KEY_EXCHANGE_SEND; /* * Now, we send change cipher state */ byte[] cmessage = new byte[1]; cmessage[0] = 1; rs.writeMessage((short)RL_CHANGE_CIPHER_SPEC, cmessage, 0, cmessage.length); connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND; /* * Calculate the ms */ this.ms = new byte[48]; byte[] random = new byte[clientRandom.length + serverRandom.length]; System.arraycopy(clientRandom, 0, random, 0, clientRandom.length); System.arraycopy(serverRandom, 0, random, clientRandom.length, serverRandom.length); TlsUtils.PRF(pms, TlsUtils.toByteArray("master secret"), random, this.ms); /* * Initialize our cipher suite */ rs.writeSuite = this.chosenCipherSuite; rs.writeSuite.init(this.ms, clientRandom, serverRandom); /* * Send our finished message. */ byte[] checksum = new byte[12]; byte[] md5andsha1 = new byte[16 + 20]; rs.hash1.doFinal(md5andsha1, 0); TlsUtils.PRF(this.ms, TlsUtils.toByteArray("client finished"), md5andsha1, checksum); ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HP_FINISHED, bos); TlsUtils.writeUint24(12, bos); bos.write(checksum); byte[] message = bos.toByteArray(); rs.writeMessage((short)RL_HANDSHAKE, message, 0, message.length); this.connection_state = CS_CLIENT_FINISHED_SEND; read = true; break; default: this.failWithError(AL_fatal, AP_handshake_failure); } break; case HP_SERVER_KEY_EXCHANGE: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -