📄 tlsprotocolhandler.java
字号:
* Check that we are doing DHE key exchange */ if (this.chosenCipherSuite.getKeyExchangeAlgorithm() != TlsCipherSuite.KE_DHE_RSA) { this.failWithError(AL_fatal, AP_unexpected_message); } /* * Parse the Structure */ int pLength = TlsUtils.readUint16(is); byte[] pByte = new byte[pLength]; TlsUtils.readFully(pByte, is); int gLength = TlsUtils.readUint16(is); byte[] gByte = new byte[gLength]; TlsUtils.readFully(gByte, is); int YsLength = TlsUtils.readUint16(is); byte[] YsByte = new byte[YsLength]; TlsUtils.readFully(YsByte, is); int sigLength = TlsUtils.readUint16(is); byte[] sigByte = new byte[sigLength]; TlsUtils.readFully(sigByte, is); this.assertEmpty(is); /* * Verify the Signature. * * First, calculate the hash. */ CombinedHash sigDigest = new CombinedHash(); ByteArrayOutputStream signedData = new ByteArrayOutputStream(); TlsUtils.writeUint16(pLength, signedData); signedData.write(pByte); TlsUtils.writeUint16(gLength, signedData); signedData.write(gByte); TlsUtils.writeUint16(YsLength, signedData); signedData.write(YsByte); byte[] signed = signedData.toByteArray(); sigDigest.update(this.clientRandom, 0, this.clientRandom.length); sigDigest.update(this.serverRandom, 0, this.serverRandom.length); sigDigest.update(signed, 0, signed.length); byte[] hash = new byte[sigDigest.getDigestSize()]; sigDigest.doFinal(hash, 0); /* * Now, do the RSA operation */ RSABlindedEngine rsa = new RSABlindedEngine(); PKCS1Encoding encoding = new PKCS1Encoding(rsa); encoding.init(false, this.serverRsaKey); /* * The data which was signed */ byte[] sigHash = null; try { sigHash = encoding.processBlock(sigByte, 0, sigByte.length); } catch (InvalidCipherTextException e) { this.failWithError(AL_fatal, AP_bad_certificate); } /* * Check if the data which was signed is equal to * the hash we calculated. */ if (sigHash.length != hash.length) { this.failWithError(AL_fatal, AP_bad_certificate); } for (int i = 0; i < sigHash.length; i++) { if (sigHash[i] != hash[i]) { this.failWithError(AL_fatal, AP_bad_certificate); } } /* * OK, Signature was correct. * * Do the DH calculation. */ BigInteger p = new BigInteger(1, pByte); BigInteger g = new BigInteger(1, gByte); BigInteger Ys = new BigInteger(1, YsByte); BigInteger x = new BigInteger(p.bitLength() - 1, this.random); Yc = g.modPow(x, p); this.pms = BigIntegers.asUnsignedByteArray(Ys.modPow(x, p)); this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED; read = true; break; default: this.failWithError(AL_fatal, AP_unexpected_message); } break; case HP_CERTIFICATE_REQUEST: 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: short typesLength = TlsUtils.readUint8(is); byte[] types = new byte[typesLength]; TlsUtils.readFully(types, is); int authsLength = TlsUtils.readUint16(is); byte[] auths = new byte[authsLength]; TlsUtils.readFully(auths, is); assertEmpty(is); this.connection_state = CS_CERTIFICATE_REQUEST_RECEIVED; read = true; break; default: this.failWithError(AL_fatal, AP_unexpected_message); } break; case HP_HELLO_REQUEST: case HP_CLIENT_KEY_EXCHANGE: case HP_CERTIFICATE_VERIFY: case HP_CLIENT_HELLO: default: // We do not support this! this.failWithError(AL_fatal, AP_unexpected_message); break; } } } } while (read); } private void processApplicationData() { /* * There is nothing we need to do here. * * This function could be used for callbacks when application * data arrives in the future. */ } private void processAlert() throws IOException { while (alertQueue.size() >= 2) { /* * An alert is always 2 bytes. Read the alert. */ byte[] tmp = new byte[2]; alertQueue.read(tmp, 0, 2, 0); alertQueue.removeData(2); short level = tmp[0]; short description = tmp[1]; if (level == AL_fatal) { /* * This is a fatal error. */ this.failedWithError = true; this.closed = true; /* * Now try to close the stream, ignore errors. */ try { rs.close(); } catch (Exception e) { } throw new IOException(TLS_ERROR_MESSAGE); } else { /* * This is just a warning. */ if (description == AP_close_notify) { /* * Close notify */ this.failWithError(AL_warning, AP_close_notify); } /* * If it is just a warning, we continue. */ } } } /** * This method is called, when a change cipher spec message is received. * * @throws IOException If the message has an invalid content or the * handshake is not in the correct state. */ private void processChangeCipherSpec() throws IOException { while (changeCipherSpecQueue.size() > 0) { /* * A change cipher spec message is only one byte with the value 1. */ byte[] b = new byte[1]; changeCipherSpecQueue.read(b, 0, 1, 0); changeCipherSpecQueue.removeData(1); if (b[0] != 1) { /* * This should never happen. */ this.failWithError(AL_fatal, AP_unexpected_message); } else { /* * Check if we are in the correct connection state. */ if (this.connection_state == CS_CLIENT_FINISHED_SEND) { rs.readSuite = rs.writeSuite; this.connection_state = CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED; } else { /* * We are not in the correct connection state. */ this.failWithError(AL_fatal, AP_handshake_failure); } } } } private void sendClientCertificate() throws IOException { /* * just write back the "no client certificate" message * see also gnutls, auth_cert.c:643 (0B 00 00 03 00 00 00) */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HP_CERTIFICATE, bos); TlsUtils.writeUint24(3, bos); TlsUtils.writeUint24(0, bos); byte[] message = bos.toByteArray(); rs.writeMessage((short)RL_HANDSHAKE, message, 0, message.length); } /** * Connects to the remote system. * * @param verifyer Will be used when a certificate is received to verify * that this certificate is accepted by the client. * @throws IOException If handshake was not successful. */ public void connect(CertificateVerifyer verifyer) throws IOException { this.verifyer = verifyer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -