Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-07-22 08:50:00 +0400
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-07-22 08:50:00 +0400
commitc2188c857cd28a8d2b0b0a121463774c67e96b9d (patch)
tree4afe5fc1601cecbb65da40b4bc74090dddec1236 /core/src
parent1206355fed94bcfec4fd5b0b2904ab4f0b3043fe (diff)
parent410abad648137ef6dc3186547c411ef76ae8bbd0 (diff)
Merge branch 'master' of git.bouncycastle.org:bc-java
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/digests/SHA512tDigest.java2
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java3
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java197
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java4
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java2
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java8
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java2
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java2
-rw-r--r--core/src/main/jdk1.1/java/security/cert/X509CertSelector.java3
-rw-r--r--core/src/main/jdk1.1/java/util/Collections.java3
-rw-r--r--core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java184
-rw-r--r--core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java135
-rw-r--r--core/src/test/jdk1.1/org/bouncycastle/crypto/test/RegressionTest.java149
-rw-r--r--core/src/test/jdk1.2/org/bouncycastle/crypto/test/RegressionTest.java150
14 files changed, 731 insertions, 113 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/digests/SHA512tDigest.java b/core/src/main/java/org/bouncycastle/crypto/digests/SHA512tDigest.java
index 9abf73b4..d5848b17 100644
--- a/core/src/main/java/org/bouncycastle/crypto/digests/SHA512tDigest.java
+++ b/core/src/main/java/org/bouncycastle/crypto/digests/SHA512tDigest.java
@@ -10,7 +10,7 @@ import org.bouncycastle.util.Pack;
public class SHA512tDigest
extends LongDigest
{
- private final int digestLength;
+ private int digestLength; // non-final due to old flow analyser.
private long H1t, H2t, H3t, H4t, H5t, H6t, H7t, H8t;
diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java
index 5fcfff9b..4c0db1b5 100644
--- a/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java
+++ b/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java
@@ -299,10 +299,9 @@ public class CramerShoupCoreEngine
/**
* CS exception for wrong cipher-texts
*/
- public class CramerShoupCiphertextException
+ public static class CramerShoupCiphertextException
extends Exception
{
-
private static final long serialVersionUID = -6360977166495345076L;
public CramerShoupCiphertextException(String msg)
diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java
index 704b1de4..4788a8ca 100644
--- a/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java
+++ b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java
@@ -8,105 +8,116 @@ import org.bouncycastle.crypto.params.CramerShoupParameters;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.util.BigIntegers;
-public class CramerShoupParametersGenerator {
-
- private int size;
- private int certainty;
- private SecureRandom random;
-
- /**
- * Initialise the parameters generator.
- *
- * @param size
- * bit length for the prime p
- * @param certainty
- * a measure of the uncertainty that the caller is willing to tolerate:
- * the probability that the generated modulus is prime exceeds (1 - 1/2^certainty).
- * The execution time of this method is proportional to the value of this parameter.
- * @param random
- * a source of randomness
- */
- public void init(int size, int certainty, SecureRandom random) {
- this.size = size;
- this.certainty = certainty;
- this.random = random;
- }
-
- /**
- * which generates the p and g values from the given parameters, returning
- * the CramerShoupParameters object.
- * <p>
- * Note: can take a while...
- */
- public CramerShoupParameters generateParameters() {
- //
- // find a safe prime p where p = 2*q + 1, where p and q are prime.
- //
- BigInteger[] safePrimes = ParametersHelper.generateSafePrimes(size, certainty, random);
+public class CramerShoupParametersGenerator
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private int size;
+ private int certainty;
+ private SecureRandom random;
+
+ /**
+ * Initialise the parameters generator.
+ *
+ * @param size bit length for the prime p
+ * @param certainty a measure of the uncertainty that the caller is willing to tolerate:
+ * the probability that the generated modulus is prime exceeds (1 - 1/2^certainty).
+ * The execution time of this method is proportional to the value of this parameter.
+ * @param random a source of randomness
+ */
+ public void init(int size, int certainty, SecureRandom random)
+ {
+ this.size = size;
+ this.certainty = certainty;
+ this.random = random;
+ }
+
+ /**
+ * which generates the p and g values from the given parameters, returning
+ * the CramerShoupParameters object.
+ * <p/>
+ * Note: can take a while...
+ */
+ public CramerShoupParameters generateParameters()
+ {
+ //
+ // find a safe prime p where p = 2*q + 1, where p and q are prime.
+ //
+ BigInteger[] safePrimes = ParametersHelper.generateSafePrimes(size, certainty, random);
// BigInteger p = safePrimes[0];
- BigInteger q = safePrimes[1];
- BigInteger g1 = ParametersHelper.selectGenerator(q, random);
- BigInteger g2 = ParametersHelper.selectGenerator(q, random);
- while(g1.equals(g2)){
- g2 = ParametersHelper.selectGenerator(q, random);
- }
-
- return new CramerShoupParameters(q, g1, g2, new SHA256Digest());
- }
-
- public CramerShoupParameters generateParameters(DHParameters dhParams){
- BigInteger p = dhParams.getP();
- BigInteger g1 = dhParams.getG();
-
- // now we just need a second generator
- BigInteger g2 = ParametersHelper.selectGenerator(p, random);
- while(g1.equals(g2)){
- g2 = ParametersHelper.selectGenerator(p, random);
- }
-
- return new CramerShoupParameters(p, g1, g2, new SHA256Digest());
- }
-
- private static class ParametersHelper {
-
- private static final BigInteger TWO = BigInteger.valueOf(2);
-
- /*
- * Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
- *
- * (see: Handbook of Applied Cryptography 4.86)
- */
- static BigInteger[] generateSafePrimes(int size, int certainty, SecureRandom random) {
- BigInteger p, q;
- int qLength = size - 1;
-
- for (;;) {
- q = new BigInteger(qLength, 2, random);
- p = q.shiftLeft(1).add(BigInteger.ONE);
- if (p.isProbablePrime(certainty) && (certainty <= 2 || q.isProbablePrime(certainty))) {
- break;
- }
- }
-
- return new BigInteger[] { p, q };
- }
-
- static BigInteger selectGenerator(BigInteger p, SecureRandom random) {
- BigInteger pMinusTwo = p.subtract(TWO);
- BigInteger g;
+ BigInteger q = safePrimes[1];
+ BigInteger g1 = ParametersHelper.selectGenerator(q, random);
+ BigInteger g2 = ParametersHelper.selectGenerator(q, random);
+ while (g1.equals(g2))
+ {
+ g2 = ParametersHelper.selectGenerator(q, random);
+ }
+
+ return new CramerShoupParameters(q, g1, g2, new SHA256Digest());
+ }
+
+ public CramerShoupParameters generateParameters(DHParameters dhParams)
+ {
+ BigInteger p = dhParams.getP();
+ BigInteger g1 = dhParams.getG();
+
+ // now we just need a second generator
+ BigInteger g2 = ParametersHelper.selectGenerator(p, random);
+ while (g1.equals(g2))
+ {
+ g2 = ParametersHelper.selectGenerator(p, random);
+ }
+
+ return new CramerShoupParameters(p, g1, g2, new SHA256Digest());
+ }
+
+ private static class ParametersHelper
+ {
+
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
+ /*
+ * Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
+ *
+ * (see: Handbook of Applied Cryptography 4.86)
+ */
+ static BigInteger[] generateSafePrimes(int size, int certainty, SecureRandom random)
+ {
+ BigInteger p, q;
+ int qLength = size - 1;
+
+ for (; ; )
+ {
+ q = new BigInteger(qLength, 2, random);
+ p = q.shiftLeft(1).add(ONE);
+ if (p.isProbablePrime(certainty) && (certainty <= 2 || q.isProbablePrime(certainty)))
+ {
+ break;
+ }
+ }
+
+ return new BigInteger[]{p, q};
+ }
+
+ static BigInteger selectGenerator(BigInteger p, SecureRandom random)
+ {
+ BigInteger pMinusTwo = p.subtract(TWO);
+ BigInteger g;
/*
- * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
+ * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
*/
- do {
- BigInteger h = BigIntegers.createRandomInRange(TWO, pMinusTwo, random);
+ do
+ {
+ BigInteger h = BigIntegers.createRandomInRange(TWO, pMinusTwo, random);
- g = h.modPow(TWO, p);
- } while (g.equals(BigInteger.ONE));
+ g = h.modPow(TWO, p);
+ }
+ while (g.equals(ONE));
- return g;
- }
- }
+ return g;
+ }
+ }
}
diff --git a/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java b/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java
index 8d5b99b2..b06d1f53 100644
--- a/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java
+++ b/core/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java
@@ -25,8 +25,8 @@ public class CipherInputStream
{
private static final int INPUT_BUF_SIZE = 2048;
- private final SkippingCipher skippingCipher;
- private final byte[] inBuf;
+ private SkippingCipher skippingCipher;
+ private byte[] inBuf;
private BufferedBlockCipher bufferedBlockCipher;
private StreamCipher streamCipher;
diff --git a/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
index 6350806f..5b694bec 100644
--- a/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
+++ b/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java
@@ -9,7 +9,7 @@ import org.bouncycastle.math.ec.ECPoint;
public class ECNamedDomainParameters
extends ECDomainParameters
{
- private final ASN1ObjectIdentifier name;
+ private ASN1ObjectIdentifier name;
public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n)
{
diff --git a/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java
index 8ff637da..29d8b369 100644
--- a/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java
+++ b/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java
@@ -34,10 +34,10 @@ public final class KDFCounterParameters
implements DerivationParameters
{
- private final byte[] ki;
- private final byte[] fixedInputDataCounterPrefix;
- private final byte[] fixedInputDataCounterSuffix;
- private final int r;
+ private byte[] ki;
+ private byte[] fixedInputDataCounterPrefix;
+ private byte[] fixedInputDataCounterSuffix;
+ private int r;
/**
* Base constructor - suffix fixed input data only.
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java
index d0b893a6..bceb8220 100644
--- a/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java
+++ b/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java
@@ -163,7 +163,7 @@ public class DSTU4145Signer
{
if (x.bitLength() > bitLength)
{
- x = x.mod(BigInteger.ONE.shiftLeft(bitLength));
+ x = x.mod(ONE.shiftLeft(bitLength));
}
return x;
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java b/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java
index 4292da31..4ee2de60 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/tools/DiscoverEndomorphisms.java
@@ -213,7 +213,7 @@ public class DiscoverEndomorphisms
BigInteger s0 = ECConstants.ONE, s1 = ECConstants.ZERO;
BigInteger t0 = ECConstants.ZERO, t1 = ECConstants.ONE;
- while (r1.compareTo(BigInteger.ONE) > 0)
+ while (r1.compareTo(ECConstants.ONE) > 0)
{
BigInteger[] qr = r0.divideAndRemainder(r1);
BigInteger q = qr[0], r2 = qr[1];
diff --git a/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java b/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java
index d5c783a6..0ac127f6 100644
--- a/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java
+++ b/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java
@@ -26,6 +26,7 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.DERGeneralizedTime;
import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.util.ASN1Dump;
@@ -2148,7 +2149,7 @@ public class X509CertSelector implements CertSelector
// TODO fix this, Sequence contains tagged objects
ASN1Sequence derObject = (ASN1Sequence)derInputStream
.readObject();
- DERGeneralizedTime derDate = DERGeneralizedTime
+ ASN1GeneralizedTime derDate = DERGeneralizedTime
.getInstance(derObject.getObjectAt(0));
SimpleDateFormat dateF = new SimpleDateFormat(
"yyyyMMddHHmmssZ");
diff --git a/core/src/main/jdk1.1/java/util/Collections.java b/core/src/main/jdk1.1/java/util/Collections.java
index 1b7f2e93..efde29b3 100644
--- a/core/src/main/jdk1.1/java/util/Collections.java
+++ b/core/src/main/jdk1.1/java/util/Collections.java
@@ -4,7 +4,8 @@ import java.io.Serializable;
public class Collections
{
- public static List EMPTY_LIST = new ArrayList();
+ public static final List EMPTY_LIST = unmodifiableList(new ArrayList());
+ public static final Set EMPTY_SET = unmodifiableSet(new HashSet());
private Collections()
{
diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
index e4a8750f..76051c3f 100644
--- a/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -1,13 +1,13 @@
package org.bouncycastle.crypto.encodings;
+import java.security.SecureRandom;
+
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
-import java.security.SecureRandom;
-
/**
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
* depends on your application - see PKCS1 Version 2 for details.
@@ -32,6 +32,8 @@ public class PKCS1Encoding
private boolean forEncryption;
private boolean forPrivateKey;
private boolean useStrictLength;
+ private int pLen = -1;
+ private byte[] fallback = null;
/**
* Basic constructor.
@@ -44,11 +46,48 @@ public class PKCS1Encoding
this.useStrictLength = useStrict();
}
+ /**
+ * Constructor for decryption with a fixed plaintext length.
+ *
+ * @param cipher The cipher to use for cryptographic operation.
+ * @param pLen Length of the expected plaintext.
+ */
+ public PKCS1Encoding(
+ AsymmetricBlockCipher cipher,
+ int pLen)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ this.pLen = pLen;
+ }
+
+ /**
+ * Constructor for decryption with a fixed plaintext length and a fallback
+ * value that is returned, if the padding is incorrect.
+ *
+ * @param cipher
+ * The cipher to use for cryptographic operation.
+ * @param fallback
+ * The fallback value, we don't to a arraycopy here.
+ */
+ public PKCS1Encoding(
+ AsymmetricBlockCipher cipher,
+ byte[] fallback)
+ {
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ this.fallback = fallback;
+ this.pLen = fallback.length;
+ }
+
+
+
//
// for J2ME compatibility
//
private boolean useStrict()
{
+ // required if security manager has been installed.
String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
return strict == null || strict.equals("true");
@@ -174,6 +213,121 @@ public class PKCS1Encoding
return engine.processBlock(block, 0, block.length);
}
+
+ /**
+ * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
+ * for encryption.
+ *
+ * @param encoded The Plaintext.
+ * @param pLen Expected length of the plaintext.
+ * @return Either 0, if the encoding is correct, or -1, if it is incorrect.
+ */
+ private static int checkPkcs1Encoding(byte[] encoded, int pLen) {
+ int correct = 0;
+ /*
+ * Check if the first two bytes are 0 2
+ */
+ correct |= (encoded[0] ^ 2);
+
+ /*
+ * Now the padding check, check for no 0 byte in the padding
+ */
+ int plen = encoded.length - (
+ pLen /* Lenght of the PMS */
+ + 1 /* Final 0-byte before PMS */
+ );
+
+ for (int i = 1; i < plen; i++) {
+ int tmp = encoded[i];
+ tmp |= tmp >> 1;
+ tmp |= tmp >> 2;
+ tmp |= tmp >> 4;
+ correct |= (tmp & 1) - 1;
+ }
+
+ /*
+ * Make sure the padding ends with a 0 byte.
+ */
+ correct |= encoded[encoded.length - (pLen +1)];
+
+ /*
+ * Return 0 or 1, depending on the result.
+ */
+ correct |= correct >> 1;
+ correct |= correct >> 2;
+ correct |= correct >> 4;
+ return ~((correct & 1) - 1);
+ }
+
+
+ /**
+ * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
+ *
+ * @param in The encrypted block.
+ * @param inOff Offset in the encrypted block.
+ * @param inLen Length of the encrypted block.
+ * //@param pLen Length of the desired output.
+ * @return The plaintext without padding, or a random value if the padding was incorrect.
+ *
+ * @throws InvalidCipherTextException
+ */
+ private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen)
+ throws InvalidCipherTextException
+ {
+ if (!forPrivateKey)
+ {
+ throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
+ }
+
+ byte[] block = engine.processBlock(in, inOff, inLen);
+ byte[] random = null;
+ if (this.fallback == null)
+ {
+ random = new byte[this.pLen];
+ this.random.nextBytes(random);
+ }
+ else
+ {
+ random = fallback;
+ }
+
+ /*
+ * TODO: This is a potential dangerous side channel. However, you can
+ * fix this by changing the RSA engine in a way, that it will always
+ * return blocks of the same length and prepend them with 0 bytes if
+ * needed.
+ */
+ if (block.length < getOutputBlockSize())
+ {
+ throw new InvalidCipherTextException("block truncated");
+ }
+
+ /*
+ * TODO: Potential side channel. Fix it by making the engine always
+ * return blocks of the correct length.
+ */
+ if (useStrictLength && block.length != engine.getOutputBlockSize())
+ {
+ throw new InvalidCipherTextException("block incorrect size");
+ }
+
+ /*
+ * Check the padding.
+ */
+ int correct = PKCS1Encoding.checkPkcs1Encoding(block, this.pLen);
+
+ /*
+ * Now, to a constant time constant memory copy of the decrypted value
+ * or the random value, depending on the validity of the padding.
+ */
+ byte[] result = new byte[this.pLen];
+ for (int i = 0; i < this.pLen; i++)
+ {
+ result[i] = (byte)((block[i + (block.length - pLen)] & (~correct)) | (random[i] & correct));
+ }
+
+ return result;
+ }
/**
* @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format.
@@ -184,7 +338,15 @@ public class PKCS1Encoding
int inLen)
throws InvalidCipherTextException
{
- byte[] block = engine.processBlock(in, inOff, inLen);
+ /*
+ * If the length of the expected plaintext is known, we use a constant-time decryption.
+ * If the decryption fails, we return a random value.
+ */
+ if (this.pLen != -1) {
+ return this.decodeBlockOrRandom(in, inOff, inLen);
+ }
+
+ byte[] block = engine.processBlock(in, inOff, inLen);
if (block.length < getOutputBlockSize())
{
@@ -192,10 +354,20 @@ public class PKCS1Encoding
}
byte type = block[0];
-
- if (type != 1 && type != 2)
+
+ if (forPrivateKey)
{
- throw new InvalidCipherTextException("unknown block type");
+ if (type != 2)
+ {
+ throw new InvalidCipherTextException("unknown block type");
+ }
+ }
+ else
+ {
+ if (type != 1)
+ {
+ throw new InvalidCipherTextException("unknown block type");
+ }
}
if (useStrictLength && block.length != engine.getOutputBlockSize())
diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java
new file mode 100644
index 00000000..b8153b06
--- /dev/null
+++ b/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java
@@ -0,0 +1,135 @@
+package org.bouncycastle.crypto.tls;
+
+import java.security.SecureRandom;
+
+import org.bouncycastle.crypto.prng.DigestRandomGenerator;
+import org.bouncycastle.crypto.prng.RandomGenerator;
+import org.bouncycastle.util.Times;
+
+abstract class AbstractTlsContext
+ implements TlsContext
+{
+ private static long counter = Times.nanoTime();
+
+ private synchronized static long nextCounterValue()
+ {
+ return ++counter;
+ }
+
+ private RandomGenerator nonceRandom;
+ private SecureRandom secureRandom;
+ private SecurityParameters securityParameters;
+
+ private ProtocolVersion clientVersion = null;
+ private ProtocolVersion serverVersion = null;
+ private TlsSession session = null;
+ private Object userObject = null;
+
+ AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters)
+ {
+ secureRandom.setSeed(nextCounterValue());
+ secureRandom.setSeed(Times.nanoTime());
+
+ this.nonceRandom = new DigestRandomGenerator(TlsUtils.createHash(HashAlgorithm.sha256));
+ byte[] nonceSeed = new byte[32];
+ secureRandom.nextBytes(nonceSeed);
+ this.nonceRandom.addSeedMaterial(nonceSeed);
+
+ this.secureRandom = secureRandom;
+ this.securityParameters = securityParameters;
+ }
+
+ public RandomGenerator getNonceRandomGenerator()
+ {
+ return nonceRandom;
+ }
+
+ public SecureRandom getSecureRandom()
+ {
+ return secureRandom;
+ }
+
+ public SecurityParameters getSecurityParameters()
+ {
+ return securityParameters;
+ }
+
+ public ProtocolVersion getClientVersion()
+ {
+ return clientVersion;
+ }
+
+ void setClientVersion(ProtocolVersion clientVersion)
+ {
+ this.clientVersion = clientVersion;
+ }
+
+ public ProtocolVersion getServerVersion()
+ {
+ return serverVersion;
+ }
+
+ void setServerVersion(ProtocolVersion serverVersion)
+ {
+ this.serverVersion = serverVersion;
+ }
+
+ public TlsSession getResumableSession()
+ {
+ return session;
+ }
+
+ void setResumableSession(TlsSession session)
+ {
+ this.session = session;
+ }
+
+ public Object getUserObject()
+ {
+ return userObject;
+ }
+
+ public void setUserObject(Object userObject)
+ {
+ this.userObject = userObject;
+ }
+
+ public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length)
+ {
+ if (context_value != null && !TlsUtils.isValidUint16(context_value.length))
+ {
+ throw new IllegalArgumentException("'context_value' must have length less than 2^16 (or be null)");
+ }
+
+ SecurityParameters sp = getSecurityParameters();
+ byte[] cr = sp.getClientRandom(), sr = sp.getServerRandom();
+
+ int seedLength = cr.length + sr.length;
+ if (context_value != null)
+ {
+ seedLength += (2 + context_value.length);
+ }
+
+ byte[] seed = new byte[seedLength];
+ int seedPos = 0;
+
+ System.arraycopy(cr, 0, seed, seedPos, cr.length);
+ seedPos += cr.length;
+ System.arraycopy(sr, 0, seed, seedPos, sr.length);
+ seedPos += sr.length;
+ if (context_value != null)
+ {
+ TlsUtils.writeUint16(context_value.length, seed, seedPos);
+ seedPos += 2;
+ System.arraycopy(context_value, 0, seed, seedPos, context_value.length);
+ seedPos += context_value.length;
+ }
+
+ if (seedPos != seedLength)
+ {
+ throw new IllegalStateException("error in calculation of seed for export");
+ }
+
+ return TlsUtils.PRF(this, sp.getMasterSecret(), asciiLabel, seed, length);
+ }
+}
diff --git a/core/src/test/jdk1.1/org/bouncycastle/crypto/test/RegressionTest.java b/core/src/test/jdk1.1/org/bouncycastle/crypto/test/RegressionTest.java
new file mode 100644
index 00000000..230145df
--- /dev/null
+++ b/core/src/test/jdk1.1/org/bouncycastle/crypto/test/RegressionTest.java
@@ -0,0 +1,149 @@
+package org.bouncycastle.crypto.test;
+
+import org.bouncycastle.util.test.Test;
+import org.bouncycastle.util.test.TestResult;
+
+public class RegressionTest
+{
+ public static Test[] tests =
+ {
+ new AESTest(),
+ new AESLightTest(),
+ new AESFastTest(),
+ new AESWrapTest(),
+ new DESTest(),
+ new DESedeTest(),
+ new ModeTest(),
+ new PaddingTest(),
+ new DHTest(),
+ new ElGamalTest(),
+ new DSATest(),
+ new ECTest(),
+ new GOST3410Test(),
+ new ECGOST3410Test(),
+ new ECIESTest(),
+ new ECNRTest(),
+ new MacTest(),
+ new GOST28147MacTest(),
+ new RC2Test(),
+ new RC2WrapTest(),
+ new RC4Test(),
+ new RC5Test(),
+ new RC6Test(),
+ new RijndaelTest(),
+ new SerpentTest(),
+ new CamelliaTest(),
+ new CamelliaLightTest(),
+ new DigestRandomNumberTest(),
+ new SkipjackTest(),
+ new BlowfishTest(),
+ new TwofishTest(),
+ new Threefish256Test(),
+ new Threefish512Test(),
+ new Threefish1024Test(),
+ new SkeinDigestTest(),
+ new SkeinMacTest(),
+ new CAST5Test(),
+ new CAST6Test(),
+ new GOST28147Test(),
+ new IDEATest(),
+ new RSATest(),
+ new RSABlindedTest(),
+ new RSADigestSignerTest(),
+ new PSSBlindTest(),
+ new ISO9796Test(),
+ new ISO9797Alg3MacTest(),
+ new MD2DigestTest(),
+ new MD4DigestTest(),
+ new MD5DigestTest(),
+ new SHA1DigestTest(),
+ new SHA224DigestTest(),
+ new SHA256DigestTest(),
+ new SHA384DigestTest(),
+ new SHA512DigestTest(),
+ new SHA512t224DigestTest(),
+ new SHA512t256DigestTest(),
+ new SHA3DigestTest(),
+ new RIPEMD128DigestTest(),
+ new RIPEMD160DigestTest(),
+ new RIPEMD256DigestTest(),
+ new RIPEMD320DigestTest(),
+ new TigerDigestTest(),
+ new GOST3411DigestTest(),
+ new WhirlpoolDigestTest(),
+ new MD5HMacTest(),
+ new SHA1HMacTest(),
+ new SHA224HMacTest(),
+ new SHA256HMacTest(),
+ new SHA384HMacTest(),
+ new SHA512HMacTest(),
+ new RIPEMD128HMacTest(),
+ new RIPEMD160HMacTest(),
+ new OAEPTest(),
+ new PSSTest(),
+ new CTSTest(),
+ new CCMTest(),
+ new PKCS5Test(),
+ new PKCS12Test(),
+ new KDF1GeneratorTest(),
+ new KDF2GeneratorTest(),
+ new MGF1GeneratorTest(),
+ new HKDFGeneratorTest(),
+ new DHKEKGeneratorTest(),
+ new ECDHKEKGeneratorTest(),
+ new ShortenedDigestTest(),
+ new EqualsHashCodeTest(),
+ new TEATest(),
+ new XTEATest(),
+ new RFC3211WrapTest(),
+ new SEEDTest(),
+ new Salsa20Test(),
+ new XSalsa20Test(),
+ new ChaChaTest(),
+ new CMacTest(),
+ new EAXTest(),
+ new GCMTest(),
+ new GMacTest(),
+ new HCFamilyTest(),
+ new HCFamilyVecTest(),
+ new ISAACTest(),
+ new NoekeonTest(),
+ new VMPCKSA3Test(),
+ new VMPCMacTest(),
+ new VMPCTest(),
+ new Grainv1Test(),
+ new Grain128Test(),
+ //new NaccacheSternTest(),
+ new SRP6Test(),
+ new SCryptTest(),
+ new ResetTest(),
+ new NullTest(),
+ new DSTU4145Test(),
+ new Poly1305Test(),
+ new OCBTest(),
+ new NonMemoableDigestTest(),
+ new RSAKeyEncapsulationTest(),
+ new ECIESKeyEncapsulationTest(),
+ new HashCommitmentTest(),
+ new CipherStreamTest(),
+ new BlockCipherResetTest(),
+ new StreamCipherResetTest(),
+ new SM3DigestTest()
+ };
+
+ public static void main(
+ String[] args)
+ {
+ for (int i = 0; i != tests.length; i++)
+ {
+ TestResult result = tests[i].perform();
+
+ if (result.getException() != null)
+ {
+ result.getException().printStackTrace();
+ }
+
+ System.out.println(result);
+ }
+ }
+}
diff --git a/core/src/test/jdk1.2/org/bouncycastle/crypto/test/RegressionTest.java b/core/src/test/jdk1.2/org/bouncycastle/crypto/test/RegressionTest.java
new file mode 100644
index 00000000..b7b6158b
--- /dev/null
+++ b/core/src/test/jdk1.2/org/bouncycastle/crypto/test/RegressionTest.java
@@ -0,0 +1,150 @@
+package org.bouncycastle.crypto.test;
+
+import org.bouncycastle.util.test.Test;
+import org.bouncycastle.util.test.TestResult;
+
+public class RegressionTest
+{
+ public static Test[] tests =
+ {
+ new AESTest(),
+ new AESLightTest(),
+ new AESFastTest(),
+ new AESWrapTest(),
+ new DESTest(),
+ new DESedeTest(),
+ new ModeTest(),
+ new PaddingTest(),
+ new DHTest(),
+ new ElGamalTest(),
+ new DSATest(),
+ new ECTest(),
+ new GOST3410Test(),
+ new ECGOST3410Test(),
+ new ECIESTest(),
+ new ECNRTest(),
+ new MacTest(),
+ new GOST28147MacTest(),
+ new RC2Test(),
+ new RC2WrapTest(),
+ new RC4Test(),
+ new RC5Test(),
+ new RC6Test(),
+ new RijndaelTest(),
+ new SerpentTest(),
+ new CamelliaTest(),
+ new CamelliaLightTest(),
+ new DigestRandomNumberTest(),
+ new SkipjackTest(),
+ new BlowfishTest(),
+ new TwofishTest(),
+ new Threefish256Test(),
+ new Threefish512Test(),
+ new Threefish1024Test(),
+ new SkeinDigestTest(),
+ new SkeinMacTest(),
+ new CAST5Test(),
+ new CAST6Test(),
+ new GOST28147Test(),
+ new IDEATest(),
+ new RSATest(),
+ new RSABlindedTest(),
+ new RSADigestSignerTest(),
+ new PSSBlindTest(),
+ new ISO9796Test(),
+ new ISO9797Alg3MacTest(),
+ new MD2DigestTest(),
+ new MD4DigestTest(),
+ new MD5DigestTest(),
+ new SHA1DigestTest(),
+ new SHA224DigestTest(),
+ new SHA256DigestTest(),
+ new SHA384DigestTest(),
+ new SHA512DigestTest(),
+ new SHA512t224DigestTest(),
+ new SHA512t256DigestTest(),
+ new SHA3DigestTest(),
+ new RIPEMD128DigestTest(),
+ new RIPEMD160DigestTest(),
+ new RIPEMD256DigestTest(),
+ new RIPEMD320DigestTest(),
+ new TigerDigestTest(),
+ new GOST3411DigestTest(),
+ new WhirlpoolDigestTest(),
+ new MD5HMacTest(),
+ new SHA1HMacTest(),
+ new SHA224HMacTest(),
+ new SHA256HMacTest(),
+ new SHA384HMacTest(),
+ new SHA512HMacTest(),
+ new RIPEMD128HMacTest(),
+ new RIPEMD160HMacTest(),
+ new OAEPTest(),
+ new PSSTest(),
+ new CTSTest(),
+ new CCMTest(),
+ new PKCS5Test(),
+ new PKCS12Test(),
+ new KDF1GeneratorTest(),
+ new KDF2GeneratorTest(),
+ new MGF1GeneratorTest(),
+ new HKDFGeneratorTest(),
+ new DHKEKGeneratorTest(),
+ new ECDHKEKGeneratorTest(),
+ new ShortenedDigestTest(),
+ new EqualsHashCodeTest(),
+ new TEATest(),
+ new XTEATest(),
+ new RFC3211WrapTest(),
+ new SEEDTest(),
+ new Salsa20Test(),
+ new XSalsa20Test(),
+ new ChaChaTest(),
+ new CMacTest(),
+ new EAXTest(),
+ new GCMTest(),
+ new GMacTest(),
+ new HCFamilyTest(),
+ new HCFamilyVecTest(),
+ new ISAACTest(),
+ new NoekeonTest(),
+ new VMPCKSA3Test(),
+ new VMPCMacTest(),
+ new VMPCTest(),
+ new Grainv1Test(),
+ new Grain128Test(),
+ //new NaccacheSternTest(),
+ new SRP6Test(),
+ new SCryptTest(),
+ new ResetTest(),
+ new NullTest(),
+ new DSTU4145Test(),
+ new SipHashTest(),
+ new Poly1305Test(),
+ new OCBTest(),
+ new NonMemoableDigestTest(),
+ new RSAKeyEncapsulationTest(),
+ new ECIESKeyEncapsulationTest(),
+ new HashCommitmentTest(),
+ new CipherStreamTest(),
+ new BlockCipherResetTest(),
+ new StreamCipherResetTest(),
+ new SM3DigestTest()
+ };
+
+ public static void main(
+ String[] args)
+ {
+ for (int i = 0; i != tests.length; i++)
+ {
+ TestResult result = tests[i].perform();
+
+ if (result.getException() != null)
+ {
+ result.getException().printStackTrace();
+ }
+
+ System.out.println(result);
+ }
+ }
+}