Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.bouncycastle.tls;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;
import org.bouncycastle.tls.crypto.TlsECConfig;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
public class TlsECCUtils
{
public static final Integer EXT_elliptic_curves = Integers.valueOf(ExtensionType.supported_groups);
public static final Integer EXT_ec_point_formats = Integers.valueOf(ExtensionType.ec_point_formats);
public static void addSupportedEllipticCurvesExtension(Hashtable extensions, int[] namedCurves) throws IOException
{
extensions.put(EXT_elliptic_curves, createSupportedEllipticCurvesExtension(namedCurves));
}
public static void addSupportedPointFormatsExtension(Hashtable extensions, short[] ecPointFormats)
throws IOException
{
extensions.put(EXT_ec_point_formats, createSupportedPointFormatsExtension(ecPointFormats));
}
public static int[] getSupportedEllipticCurvesExtension(Hashtable extensions) throws IOException
{
byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_elliptic_curves);
return extensionData == null ? null : readSupportedEllipticCurvesExtension(extensionData);
}
public static short[] getSupportedPointFormatsExtension(Hashtable extensions) throws IOException
{
byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_ec_point_formats);
return extensionData == null ? null : readSupportedPointFormatsExtension(extensionData);
}
public static byte[] createSupportedEllipticCurvesExtension(int[] namedCurves) throws IOException
{
if (namedCurves == null || namedCurves.length < 1)
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
return TlsUtils.encodeUint16ArrayWithUint16Length(namedCurves);
}
public static byte[] createSupportedPointFormatsExtension(short[] ecPointFormats) throws IOException
{
if (ecPointFormats == null || !Arrays.contains(ecPointFormats, ECPointFormat.uncompressed))
{
/*
* RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST
* contain the value 0 (uncompressed) as one of the items in the list of point formats.
*/
// NOTE: We add it at the end (lowest preference)
ecPointFormats = Arrays.append(ecPointFormats, ECPointFormat.uncompressed);
}
return TlsUtils.encodeUint8ArrayWithUint8Length(ecPointFormats);
}
public static int[] readSupportedEllipticCurvesExtension(byte[] extensionData) throws IOException
{
if (extensionData == null)
{
throw new IllegalArgumentException("'extensionData' cannot be null");
}
ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
int length = TlsUtils.readUint16(buf);
if (length < 2 || (length & 1) != 0)
{
throw new TlsFatalAlert(AlertDescription.decode_error);
}
int[] namedCurves = TlsUtils.readUint16Array(length / 2, buf);
TlsProtocol.assertEmpty(buf);
return namedCurves;
}
public static short[] readSupportedPointFormatsExtension(byte[] extensionData) throws IOException
{
if (extensionData == null)
{
throw new IllegalArgumentException("'extensionData' cannot be null");
}
ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);
short length = TlsUtils.readUint8(buf);
if (length < 1)
{
throw new TlsFatalAlert(AlertDescription.decode_error);
}
short[] ecPointFormats = TlsUtils.readUint8Array(length, buf);
TlsProtocol.assertEmpty(buf);
if (!Arrays.contains(ecPointFormats, ECPointFormat.uncompressed))
{
/*
* RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST
* contain the value 0 (uncompressed) as one of the items in the list of point formats.
*/
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
return ecPointFormats;
}
public static boolean containsECCipherSuites(int[] cipherSuites)
{
for (int i = 0; i < cipherSuites.length; ++i)
{
if (isECCipherSuite(cipherSuites[i]))
{
return true;
}
}
return false;
}
public static int getMinimumCurveBits(int cipherSuite)
{
switch (cipherSuite)
{
case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256:
case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256:
case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256:
return 255;
case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_CCM_8_SHA256:
case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_CCM_SHA384:
case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384:
return 384;
default:
{
if (!isECCipherSuite(cipherSuite))
{
return 0;
}
// TODO Is there a de facto rule to require a curve of similar size to the PRF hash?
return 1;
}
}
}
public static boolean isECCipherSuite(int cipherSuite)
{
switch (TlsUtils.getKeyExchangeAlgorithm(cipherSuite))
{
case KeyExchangeAlgorithm.ECDH_anon:
case KeyExchangeAlgorithm.ECDH_ECDSA:
case KeyExchangeAlgorithm.ECDH_RSA:
case KeyExchangeAlgorithm.ECDHE_ECDSA:
case KeyExchangeAlgorithm.ECDHE_PSK:
case KeyExchangeAlgorithm.ECDHE_RSA:
return true;
default:
return false;
}
}
public static short getCompressionFormat(int namedCurve) throws IOException
{
if (NamedCurve.isPrime(namedCurve))
{
return ECPointFormat.ansiX962_compressed_prime;
}
if (NamedCurve.isChar2(namedCurve))
{
return ECPointFormat.ansiX962_compressed_char2;
}
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
public static boolean isCompressionPreferred(short[] peerECPointFormats, int namedCurve) throws IOException
{
return isCompressionPreferred(peerECPointFormats, getCompressionFormat(namedCurve));
}
public static boolean isCompressionPreferred(short[] peerECPointFormats, short compressionFormat)
{
if (peerECPointFormats == null || compressionFormat == ECPointFormat.uncompressed)
{
return false;
}
for (int i = 0; i < peerECPointFormats.length; ++i)
{
short ecPointFormat = peerECPointFormats[i];
if (ecPointFormat == ECPointFormat.uncompressed)
{
return false;
}
if (ecPointFormat == compressionFormat)
{
return true;
}
}
return false;
}
public static void checkPointEncoding(short[] localECPointFormats, int namedCurve, byte[] encoding) throws IOException
{
if (encoding == null || encoding.length < 1)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
short actualFormat = getActualFormat(namedCurve, encoding);
checkActualFormat(localECPointFormats, actualFormat);
}
public static void checkActualFormat(short[] localECPointFormats, short actualFormat) throws IOException
{
if (actualFormat != ECPointFormat.uncompressed
&& (localECPointFormats == null || !Arrays.contains(localECPointFormats, actualFormat)))
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
}
public static short getActualFormat(int namedCurve, byte[] encoding) throws IOException
{
switch (encoding[0])
{
case 0x02: // compressed
case 0x03: // compressed
{
return getCompressionFormat(namedCurve);
}
case 0x04: // uncompressed
{
return ECPointFormat.uncompressed;
}
case 0x00: // infinity
case 0x06: // hybrid
case 0x07: // hybrid
default:
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
}
public static TlsECConfig readECConfig(short[] peerECPointFormats, InputStream input)
throws IOException
{
short curveType = TlsUtils.readUint8(input);
if (curveType != ECCurveType.named_curve)
{
throw new TlsFatalAlert(AlertDescription.handshake_failure);
}
int namedCurve = TlsUtils.readUint16(input);
if (!NamedCurve.refersToASpecificNamedCurve(namedCurve))
{
/*
* RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a
* specific curve. Values of NamedCurve that indicate support for a class of
* explicitly defined curves are not allowed here [...].
*/
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
boolean compressed = isCompressionPreferred(peerECPointFormats, namedCurve);
TlsECConfig result = new TlsECConfig();
result.setNamedCurve(namedCurve);
result.setPointCompression(compressed);
return result;
}
public static TlsECConfig receiveECConfig(TlsECConfigVerifier ecConfigVerifier, short[] peerECPointFormats, InputStream input)
throws IOException
{
TlsECConfig ecConfig = readECConfig(peerECPointFormats, input);
if (!ecConfigVerifier.accept(ecConfig))
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
return ecConfig;
}
public static void writeECConfig(TlsECConfig ecConfig, OutputStream output) throws IOException
{
writeNamedECParameters(ecConfig.getNamedCurve(), output);
}
public static void writeNamedECParameters(int namedCurve, OutputStream output) throws IOException
{
if (!NamedCurve.refersToASpecificNamedCurve(namedCurve))
{
/*
* RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a specific
* curve. Values of NamedCurve that indicate support for a class of explicitly defined
* curves are not allowed here [...].
*/
throw new TlsFatalAlert(AlertDescription.internal_error);
}
TlsUtils.writeUint8(ECCurveType.named_curve, output);
TlsUtils.checkUint16(namedCurve);
TlsUtils.writeUint16(namedCurve, output);
}
}