diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java')
-rw-r--r-- | bcprov/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java new file mode 100644 index 0000000..4205725 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/AbstractTlsContext.java @@ -0,0 +1,137 @@ +package org.bouncycastle.crypto.tls; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.Digest; +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) + { + Digest d = TlsUtils.createHash(HashAlgorithm.sha256); + byte[] seed = new byte[d.getDigestSize()]; + secureRandom.nextBytes(seed); + + this.nonceRandom = new DigestRandomGenerator(d); + nonceRandom.addSeedMaterial(nextCounterValue()); + nonceRandom.addSeedMaterial(Times.nanoTime()); + nonceRandom.addSeedMaterial(seed); + + 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); + } +} |