aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/TlsServerProtocol.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/TlsServerProtocol.java')
-rw-r--r--libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/TlsServerProtocol.java760
1 files changed, 0 insertions, 760 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/TlsServerProtocol.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/TlsServerProtocol.java
deleted file mode 100644
index 3411086e2..000000000
--- a/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/TlsServerProtocol.java
+++ /dev/null
@@ -1,760 +0,0 @@
-package org.spongycastle.crypto.tls;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SecureRandom;
-import java.util.Vector;
-
-import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.spongycastle.crypto.params.AsymmetricKeyParameter;
-import org.spongycastle.crypto.util.PublicKeyFactory;
-import org.spongycastle.util.Arrays;
-
-public class TlsServerProtocol
- extends TlsProtocol
-{
- protected TlsServer tlsServer = null;
- protected TlsServerContextImpl tlsServerContext = null;
-
- protected TlsKeyExchange keyExchange = null;
- protected TlsCredentials serverCredentials = null;
- protected CertificateRequest certificateRequest = null;
-
- protected short clientCertificateType = -1;
- protected TlsHandshakeHash prepareFinishHash = null;
-
- public TlsServerProtocol(InputStream input, OutputStream output, SecureRandom secureRandom)
- {
- super(input, output, secureRandom);
- }
-
- /**
- * Receives a TLS handshake in the role of server
- *
- * @param tlsServer
- * @throws IOException If handshake was not successful.
- */
- public void accept(TlsServer tlsServer)
- throws IOException
- {
- if (tlsServer == null)
- {
- throw new IllegalArgumentException("'tlsServer' cannot be null");
- }
- if (this.tlsServer != null)
- {
- throw new IllegalStateException("'accept' can only be called once");
- }
-
- this.tlsServer = tlsServer;
-
- this.securityParameters = new SecurityParameters();
- this.securityParameters.entity = ConnectionEnd.server;
- this.securityParameters.serverRandom = createRandomBlock(secureRandom);
-
- this.tlsServerContext = new TlsServerContextImpl(secureRandom, securityParameters);
- this.tlsServer.init(tlsServerContext);
- this.recordStream.init(tlsServerContext);
-
- this.recordStream.setRestrictReadVersion(false);
-
- completeHandshake();
- }
-
- protected void cleanupHandshake()
- {
- super.cleanupHandshake();
-
- this.keyExchange = null;
- this.serverCredentials = null;
- this.certificateRequest = null;
- this.prepareFinishHash = null;
- }
-
- protected AbstractTlsContext getContext()
- {
- return tlsServerContext;
- }
-
- protected TlsPeer getPeer()
- {
- return tlsServer;
- }
-
- protected void handleHandshakeMessage(short type, byte[] data)
- throws IOException
- {
- ByteArrayInputStream buf = new ByteArrayInputStream(data);
-
- switch (type)
- {
- case HandshakeType.client_hello:
- {
- switch (this.connection_state)
- {
- case CS_START:
- {
- receiveClientHelloMessage(buf);
- this.connection_state = CS_CLIENT_HELLO;
-
- sendServerHelloMessage();
- this.connection_state = CS_SERVER_HELLO;
-
- Vector serverSupplementalData = tlsServer.getServerSupplementalData();
- if (serverSupplementalData != null)
- {
- sendSupplementalDataMessage(serverSupplementalData);
- }
- this.connection_state = CS_SERVER_SUPPLEMENTAL_DATA;
-
- this.keyExchange = tlsServer.getKeyExchange();
- this.keyExchange.init(getContext());
-
- this.serverCredentials = tlsServer.getCredentials();
-
- Certificate serverCertificate = null;
-
- if (this.serverCredentials == null)
- {
- this.keyExchange.skipServerCredentials();
- }
- else
- {
- this.keyExchange.processServerCredentials(this.serverCredentials);
-
- serverCertificate = this.serverCredentials.getCertificate();
- sendCertificateMessage(serverCertificate);
- }
- this.connection_state = CS_SERVER_CERTIFICATE;
-
- // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus
- if (serverCertificate == null || serverCertificate.isEmpty())
- {
- this.allowCertificateStatus = false;
- }
-
- if (this.allowCertificateStatus)
- {
- CertificateStatus certificateStatus = tlsServer.getCertificateStatus();
- if (certificateStatus != null)
- {
- sendCertificateStatusMessage(certificateStatus);
- }
- }
-
- this.connection_state = CS_CERTIFICATE_STATUS;
-
- byte[] serverKeyExchange = this.keyExchange.generateServerKeyExchange();
- if (serverKeyExchange != null)
- {
- sendServerKeyExchangeMessage(serverKeyExchange);
- }
- this.connection_state = CS_SERVER_KEY_EXCHANGE;
-
- if (this.serverCredentials != null)
- {
- this.certificateRequest = tlsServer.getCertificateRequest();
- if (this.certificateRequest != null)
- {
- this.keyExchange.validateCertificateRequest(certificateRequest);
-
- sendCertificateRequestMessage(certificateRequest);
-
- TlsUtils.trackHashAlgorithms(this.recordStream.getHandshakeHash(),
- this.certificateRequest.getSupportedSignatureAlgorithms());
- }
- }
- this.connection_state = CS_CERTIFICATE_REQUEST;
-
- sendServerHelloDoneMessage();
- this.connection_state = CS_SERVER_HELLO_DONE;
-
- this.recordStream.getHandshakeHash().sealHashAlgorithms();
-
- break;
- }
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- break;
- }
- case HandshakeType.supplemental_data:
- {
- switch (this.connection_state)
- {
- case CS_SERVER_HELLO_DONE:
- {
- tlsServer.processClientSupplementalData(readSupplementalDataMessage(buf));
- this.connection_state = CS_CLIENT_SUPPLEMENTAL_DATA;
- break;
- }
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- break;
- }
- case HandshakeType.certificate:
- {
- switch (this.connection_state)
- {
- case CS_SERVER_HELLO_DONE:
- {
- tlsServer.processClientSupplementalData(null);
- // NB: Fall through to next case label
- }
- case CS_CLIENT_SUPPLEMENTAL_DATA:
- {
- if (this.certificateRequest == null)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- receiveCertificateMessage(buf);
- this.connection_state = CS_CLIENT_CERTIFICATE;
- break;
- }
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- break;
- }
- case HandshakeType.client_key_exchange:
- {
- switch (this.connection_state)
- {
- case CS_SERVER_HELLO_DONE:
- {
- tlsServer.processClientSupplementalData(null);
- // NB: Fall through to next case label
- }
- case CS_CLIENT_SUPPLEMENTAL_DATA:
- {
- if (this.certificateRequest == null)
- {
- this.keyExchange.skipClientCredentials();
- }
- else
- {
- if (TlsUtils.isTLSv12(getContext()))
- {
- /*
- * RFC 5246 If no suitable certificate is available, the client MUST send a
- * certificate message containing no certificates.
- *
- * NOTE: In previous RFCs, this was SHOULD instead of MUST.
- */
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- else if (TlsUtils.isSSL(getContext()))
- {
- if (this.peerCertificate == null)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- }
- else
- {
- notifyClientCertificate(Certificate.EMPTY_CHAIN);
- }
- }
- // NB: Fall through to next case label
- }
- case CS_CLIENT_CERTIFICATE:
- {
- receiveClientKeyExchangeMessage(buf);
- this.connection_state = CS_CLIENT_KEY_EXCHANGE;
- break;
- }
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- break;
- }
- case HandshakeType.certificate_verify:
- {
- switch (this.connection_state)
- {
- case CS_CLIENT_KEY_EXCHANGE:
- {
- /*
- * RFC 5246 7.4.8 This message is only sent following a client certificate that has
- * signing capability (i.e., all certificates except those containing fixed
- * Diffie-Hellman parameters).
- */
- if (!expectCertificateVerifyMessage())
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- receiveCertificateVerifyMessage(buf);
- this.connection_state = CS_CERTIFICATE_VERIFY;
-
- break;
- }
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- break;
- }
- case HandshakeType.finished:
- {
- switch (this.connection_state)
- {
- case CS_CLIENT_KEY_EXCHANGE:
- {
- if (expectCertificateVerifyMessage())
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- // NB: Fall through to next case label
- }
- case CS_CERTIFICATE_VERIFY:
- {
- processFinishedMessage(buf);
- this.connection_state = CS_CLIENT_FINISHED;
-
- if (this.expectSessionTicket)
- {
- sendNewSessionTicketMessage(tlsServer.getNewSessionTicket());
- sendChangeCipherSpecMessage();
- }
- this.connection_state = CS_SERVER_SESSION_TICKET;
-
- sendFinishedMessage();
- this.connection_state = CS_SERVER_FINISHED;
- this.connection_state = CS_END;
- break;
- }
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- break;
- }
- case HandshakeType.hello_request:
- case HandshakeType.hello_verify_request:
- case HandshakeType.server_hello:
- case HandshakeType.server_key_exchange:
- case HandshakeType.certificate_request:
- case HandshakeType.server_hello_done:
- case HandshakeType.session_ticket:
- default:
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- }
-
- protected void handleWarningMessage(short description)
- throws IOException
- {
- switch (description)
- {
- case AlertDescription.no_certificate:
- {
- /*
- * SSL 3.0 If the server has sent a certificate request Message, the client must send
- * either the certificate message or a no_certificate alert.
- */
- if (TlsUtils.isSSL(getContext()) && certificateRequest != null)
- {
- notifyClientCertificate(Certificate.EMPTY_CHAIN);
- }
- break;
- }
- default:
- {
- super.handleWarningMessage(description);
- }
- }
- }
-
- protected void notifyClientCertificate(Certificate clientCertificate)
- throws IOException
- {
- if (certificateRequest == null)
- {
- throw new IllegalStateException();
- }
-
- if (this.peerCertificate != null)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- this.peerCertificate = clientCertificate;
-
- if (clientCertificate.isEmpty())
- {
- this.keyExchange.skipClientCredentials();
- }
- else
- {
-
- /*
- * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request
- * message was non-empty, one of the certificates in the certificate chain SHOULD be
- * issued by one of the listed CAs.
- */
-
- this.clientCertificateType = TlsUtils.getClientCertificateType(clientCertificate,
- this.serverCredentials.getCertificate());
-
- this.keyExchange.processClientCertificate(clientCertificate);
- }
-
- /*
- * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its
- * discretion either continue the handshake without client authentication, or respond with a
- * fatal handshake_failure alert. Also, if some aspect of the certificate chain was
- * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its
- * discretion either continue the handshake (considering the client unauthenticated) or send
- * a fatal alert.
- */
- this.tlsServer.notifyClientCertificate(clientCertificate);
- }
-
- protected void receiveCertificateMessage(ByteArrayInputStream buf)
- throws IOException
- {
- Certificate clientCertificate = Certificate.parse(buf);
-
- assertEmpty(buf);
-
- notifyClientCertificate(clientCertificate);
- }
-
- protected void receiveCertificateVerifyMessage(ByteArrayInputStream buf)
- throws IOException
- {
- DigitallySigned clientCertificateVerify = DigitallySigned.parse(getContext(), buf);
-
- assertEmpty(buf);
-
- // Verify the CertificateVerify message contains a correct signature.
- try
- {
- // TODO For TLS 1.2, this needs to be the hash specified in the DigitallySigned
- byte[] certificateVerifyHash = getCurrentPRFHash(getContext(), prepareFinishHash, null);
-
- org.spongycastle.asn1.x509.Certificate x509Cert = this.peerCertificate.getCertificateAt(0);
- SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
- AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo);
-
- TlsSigner tlsSigner = TlsUtils.createTlsSigner(this.clientCertificateType);
- tlsSigner.init(getContext());
- tlsSigner.verifyRawSignature(clientCertificateVerify.getAlgorithm(),
- clientCertificateVerify.getSignature(), publicKey, certificateVerifyHash);
- }
- catch (Exception e)
- {
- throw new TlsFatalAlert(AlertDescription.decrypt_error);
- }
- }
-
- protected void receiveClientHelloMessage(ByteArrayInputStream buf)
- throws IOException
- {
- ProtocolVersion client_version = TlsUtils.readVersion(buf);
- if (client_version.isDTLS())
- {
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
-
- byte[] client_random = TlsUtils.readFully(32, buf);
-
- /*
- * TODO RFC 5077 3.4. If a ticket is presented by the client, the server MUST NOT attempt to
- * use the Session ID in the ClientHello for stateful session resumption.
- */
- byte[] sessionID = TlsUtils.readOpaque8(buf);
- if (sessionID.length > 32)
- {
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
-
- /*
- * TODO RFC 5246 7.4.1.2. If the session_id field is not empty (implying a session
- * resumption request), this vector MUST include at least the cipher_suite from that
- * session.
- */
- int cipher_suites_length = TlsUtils.readUint16(buf);
- if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0)
- {
- throw new TlsFatalAlert(AlertDescription.decode_error);
- }
- this.offeredCipherSuites = TlsUtils.readUint16Array(cipher_suites_length / 2, buf);
-
- /*
- * TODO RFC 5246 7.4.1.2. If the session_id field is not empty (implying a session
- * resumption request), it MUST include the compression_method from that session.
- */
- int compression_methods_length = TlsUtils.readUint8(buf);
- if (compression_methods_length < 1)
- {
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
- this.offeredCompressionMethods = TlsUtils.readUint8Array(compression_methods_length, buf);
-
- /*
- * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore
- * extensions appearing in the client hello, and send a server hello containing no
- * extensions.
- */
- this.clientExtensions = readExtensions(buf);
-
- getContext().setClientVersion(client_version);
-
- tlsServer.notifyClientVersion(client_version);
-
- securityParameters.clientRandom = client_random;
-
- tlsServer.notifyOfferedCipherSuites(offeredCipherSuites);
- tlsServer.notifyOfferedCompressionMethods(offeredCompressionMethods);
-
- /*
- * RFC 5746 3.6. Server Behavior: Initial Handshake
- */
- {
- /*
- * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension,
- * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the
- * ClientHello. Including both is NOT RECOMMENDED.
- */
-
- /*
- * When a ClientHello is received, the server MUST check if it includes the
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag
- * to TRUE.
- */
- if (Arrays.contains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV))
- {
- this.secure_renegotiation = true;
- }
-
- /*
- * The server MUST check if the "renegotiation_info" extension is included in the
- * ClientHello.
- */
- byte[] renegExtData = TlsUtils.getExtensionData(clientExtensions, EXT_RenegotiationInfo);
- if (renegExtData != null)
- {
- /*
- * If the extension is present, set secure_renegotiation flag to TRUE. The
- * server MUST then verify that the length of the "renegotiated_connection"
- * field is zero, and if it is not, MUST abort the handshake.
- */
- this.secure_renegotiation = true;
-
- if (!Arrays.constantTimeAreEqual(renegExtData, createRenegotiationInfo(TlsUtils.EMPTY_BYTES)))
- {
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
- }
- }
- }
-
- tlsServer.notifySecureRenegotiation(this.secure_renegotiation);
-
- if (clientExtensions != null)
- {
- tlsServer.processClientExtensions(clientExtensions);
- }
- }
-
- protected void receiveClientKeyExchangeMessage(ByteArrayInputStream buf)
- throws IOException
- {
- this.keyExchange.processClientKeyExchange(buf);
-
- assertEmpty(buf);
-
- establishMasterSecret(getContext(), keyExchange);
- recordStream.setPendingConnectionState(getPeer().getCompression(), getPeer().getCipher());
-
- this.prepareFinishHash = recordStream.prepareToFinish();
-
- if (!expectSessionTicket)
- {
- sendChangeCipherSpecMessage();
- }
- }
-
- protected void sendCertificateRequestMessage(CertificateRequest certificateRequest)
- throws IOException
- {
- HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_request);
-
- certificateRequest.encode(message);
-
- message.writeToRecordStream();
- }
-
- protected void sendCertificateStatusMessage(CertificateStatus certificateStatus)
- throws IOException
- {
- HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_status);
-
- certificateStatus.encode(message);
-
- message.writeToRecordStream();
- }
-
- protected void sendNewSessionTicketMessage(NewSessionTicket newSessionTicket)
- throws IOException
- {
- if (newSessionTicket == null)
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
-
- HandshakeMessage message = new HandshakeMessage(HandshakeType.session_ticket);
-
- newSessionTicket.encode(message);
-
- message.writeToRecordStream();
- }
-
- protected void sendServerHelloMessage()
- throws IOException
- {
- HandshakeMessage message = new HandshakeMessage(HandshakeType.server_hello);
-
- ProtocolVersion server_version = tlsServer.getServerVersion();
- if (!server_version.isEqualOrEarlierVersionOf(getContext().getClientVersion()))
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
-
- recordStream.setReadVersion(server_version);
- recordStream.setWriteVersion(server_version);
- recordStream.setRestrictReadVersion(true);
- getContext().setServerVersion(server_version);
-
- TlsUtils.writeVersion(server_version, message);
-
- message.write(this.securityParameters.serverRandom);
-
- /*
- * The server may return an empty session_id to indicate that the session will not be cached
- * and therefore cannot be resumed.
- */
- TlsUtils.writeOpaque8(TlsUtils.EMPTY_BYTES, message);
-
- int selectedCipherSuite = tlsServer.getSelectedCipherSuite();
- if (!Arrays.contains(this.offeredCipherSuites, selectedCipherSuite)
- || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL
- || selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- securityParameters.cipherSuite = selectedCipherSuite;
-
- short selectedCompressionMethod = tlsServer.getSelectedCompressionMethod();
- if (!Arrays.contains(this.offeredCompressionMethods, selectedCompressionMethod))
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- securityParameters.compressionAlgorithm = selectedCompressionMethod;
-
- TlsUtils.writeUint16(selectedCipherSuite, message);
- TlsUtils.writeUint8(selectedCompressionMethod, message);
-
- this.serverExtensions = tlsServer.getServerExtensions();
-
- /*
- * RFC 5746 3.6. Server Behavior: Initial Handshake
- */
- if (this.secure_renegotiation)
- {
- byte[] renegExtData = TlsUtils.getExtensionData(this.serverExtensions, EXT_RenegotiationInfo);
- boolean noRenegExt = (null == renegExtData);
-
- if (noRenegExt)
- {
- /*
- * Note that sending a "renegotiation_info" extension in response to a ClientHello
- * containing only the SCSV is an explicit exception to the prohibition in RFC 5246,
- * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed
- * because the client is signaling its willingness to receive the extension via the
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV.
- */
-
- /*
- * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty
- * "renegotiation_info" extension in the ServerHello message.
- */
- this.serverExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(this.serverExtensions);
- this.serverExtensions.put(EXT_RenegotiationInfo, createRenegotiationInfo(TlsUtils.EMPTY_BYTES));
- }
- }
-
- /*
- * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore
- * extensions appearing in the client hello, and send a server hello containing no
- * extensions.
- */
-
- if (this.serverExtensions != null)
- {
- this.securityParameters.maxFragmentLength = processMaxFragmentLengthExtension(clientExtensions,
- this.serverExtensions, AlertDescription.internal_error);
-
- this.securityParameters.truncatedHMac = TlsExtensionsUtils.hasTruncatedHMacExtension(this.serverExtensions);
-
- /*
- * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in
- * a session resumption handshake.
- */
- this.allowCertificateStatus = !this.resumedSession
- && TlsUtils.hasExpectedEmptyExtensionData(this.serverExtensions, TlsExtensionsUtils.EXT_status_request,
- AlertDescription.internal_error);
-
- this.expectSessionTicket = !this.resumedSession
- && TlsUtils.hasExpectedEmptyExtensionData(this.serverExtensions, TlsProtocol.EXT_SessionTicket,
- AlertDescription.internal_error);
-
- writeExtensions(message, this.serverExtensions);
- }
-
- if (this.securityParameters.maxFragmentLength >= 0)
- {
- int plainTextLimit = 1 << (8 + this.securityParameters.maxFragmentLength);
- recordStream.setPlaintextLimit(plainTextLimit);
- }
-
- securityParameters.prfAlgorithm = getPRFAlgorithm(getContext(), securityParameters.getCipherSuite());
-
- /*
- * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has
- * a verify_data_length equal to 12. This includes all existing cipher suites.
- */
- securityParameters.verifyDataLength = 12;
-
- message.writeToRecordStream();
-
- this.recordStream.notifyHelloComplete();
- }
-
- protected void sendServerHelloDoneMessage()
- throws IOException
- {
- byte[] message = new byte[4];
- TlsUtils.writeUint8(HandshakeType.server_hello_done, message, 0);
- TlsUtils.writeUint24(0, message, 1);
-
- writeHandshakeMessage(message, 0, message.length);
- }
-
- protected void sendServerKeyExchangeMessage(byte[] serverKeyExchange)
- throws IOException
- {
- HandshakeMessage message = new HandshakeMessage(HandshakeType.server_key_exchange, serverKeyExchange.length);
-
- message.write(serverKeyExchange);
-
- message.writeToRecordStream();
- }
-
- protected boolean expectCertificateVerifyMessage()
- {
- return this.clientCertificateType >= 0 && TlsUtils.hasSigningCapability(this.clientCertificateType);
- }
-}