| package org.bouncycastle.crypto.tls; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.security.SecureRandom; |
| import java.util.Hashtable; |
| import java.util.Vector; |
| |
| import org.bouncycastle.util.Arrays; |
| |
| public abstract class DTLSProtocol |
| { |
| protected final SecureRandom secureRandom; |
| |
| protected DTLSProtocol(SecureRandom secureRandom) |
| { |
| if (secureRandom == null) |
| { |
| throw new IllegalArgumentException("'secureRandom' cannot be null"); |
| } |
| |
| this.secureRandom = secureRandom; |
| } |
| |
| protected void processFinished(byte[] body, byte[] expected_verify_data) |
| throws IOException |
| { |
| ByteArrayInputStream buf = new ByteArrayInputStream(body); |
| |
| byte[] verify_data = TlsUtils.readFully(expected_verify_data.length, buf); |
| |
| TlsProtocol.assertEmpty(buf); |
| |
| if (!Arrays.constantTimeAreEqual(expected_verify_data, verify_data)) |
| { |
| throw new TlsFatalAlert(AlertDescription.handshake_failure); |
| } |
| } |
| |
| protected static short evaluateMaxFragmentLengthExtension(Hashtable clientExtensions, Hashtable serverExtensions, |
| short alertDescription) throws IOException |
| { |
| short maxFragmentLength = TlsExtensionsUtils.getMaxFragmentLengthExtension(serverExtensions); |
| if (maxFragmentLength >= 0 && maxFragmentLength != TlsExtensionsUtils.getMaxFragmentLengthExtension(clientExtensions)) |
| { |
| throw new TlsFatalAlert(alertDescription); |
| } |
| return maxFragmentLength; |
| } |
| |
| protected static byte[] generateCertificate(Certificate certificate) |
| throws IOException |
| { |
| ByteArrayOutputStream buf = new ByteArrayOutputStream(); |
| certificate.encode(buf); |
| return buf.toByteArray(); |
| } |
| |
| protected static byte[] generateSupplementalData(Vector supplementalData) |
| throws IOException |
| { |
| ByteArrayOutputStream buf = new ByteArrayOutputStream(); |
| TlsProtocol.writeSupplementalData(buf, supplementalData); |
| return buf.toByteArray(); |
| } |
| |
| protected static void validateSelectedCipherSuite(int selectedCipherSuite, short alertDescription) |
| throws IOException |
| { |
| switch (selectedCipherSuite) |
| { |
| case CipherSuite.TLS_RSA_EXPORT_WITH_RC4_40_MD5: |
| case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: |
| case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_DH_anon_EXPORT_WITH_RC4_40_MD5: |
| case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: |
| case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: |
| case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: |
| // TODO Alert |
| throw new IllegalStateException("RC4 MUST NOT be used with DTLS"); |
| } |
| } |
| } |