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
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java117
1 files changed, 117 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java b/core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java
new file mode 100644
index 00000000..1a484911
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/crypto/tls/CombinedHash.java
@@ -0,0 +1,117 @@
+package org.bouncycastle.crypto.tls;
+
+import org.bouncycastle.crypto.Digest;
+
+/**
+ * A combined hash, which implements md5(m) || sha1(m).
+ */
+class CombinedHash
+ implements TlsHandshakeHash
+{
+
+ protected TlsContext context;
+ protected Digest md5;
+ protected Digest sha1;
+
+ CombinedHash()
+ {
+ this.md5 = TlsUtils.createHash(HashAlgorithm.md5);
+ this.sha1 = TlsUtils.createHash(HashAlgorithm.sha1);
+ }
+
+ CombinedHash(CombinedHash t)
+ {
+ this.context = t.context;
+ this.md5 = TlsUtils.cloneHash(HashAlgorithm.md5, t.md5);
+ this.sha1 = TlsUtils.cloneHash(HashAlgorithm.sha1, t.sha1);
+ }
+
+ public void init(TlsContext context)
+ {
+ this.context = context;
+ }
+
+ public TlsHandshakeHash commit()
+ {
+ return this;
+ }
+
+ public TlsHandshakeHash fork()
+ {
+ return new CombinedHash(this);
+ }
+
+ /**
+ * @see org.bouncycastle.crypto.Digest#getAlgorithmName()
+ */
+ public String getAlgorithmName()
+ {
+ return md5.getAlgorithmName() + " and " + sha1.getAlgorithmName();
+ }
+
+ /**
+ * @see org.bouncycastle.crypto.Digest#getDigestSize()
+ */
+ public int getDigestSize()
+ {
+ return md5.getDigestSize() + sha1.getDigestSize();
+ }
+
+ /**
+ * @see org.bouncycastle.crypto.Digest#update(byte)
+ */
+ public void update(byte in)
+ {
+ md5.update(in);
+ sha1.update(in);
+ }
+
+ /**
+ * @see org.bouncycastle.crypto.Digest#update(byte[], int, int)
+ */
+ public void update(byte[] in, int inOff, int len)
+ {
+ md5.update(in, inOff, len);
+ sha1.update(in, inOff, len);
+ }
+
+ /**
+ * @see org.bouncycastle.crypto.Digest#doFinal(byte[], int)
+ */
+ public int doFinal(byte[] out, int outOff)
+ {
+ if (context != null && context.getServerVersion().isSSL())
+ {
+ ssl3Complete(md5, SSL3Mac.IPAD, SSL3Mac.OPAD, 48);
+ ssl3Complete(sha1, SSL3Mac.IPAD, SSL3Mac.OPAD, 40);
+ }
+
+ int i1 = md5.doFinal(out, outOff);
+ int i2 = sha1.doFinal(out, outOff + i1);
+ return i1 + i2;
+ }
+
+ /**
+ * @see org.bouncycastle.crypto.Digest#reset()
+ */
+ public void reset()
+ {
+ md5.reset();
+ sha1.reset();
+ }
+
+ protected void ssl3Complete(Digest d, byte[] ipad, byte[] opad, int padLength)
+ {
+ byte[] secret = context.getSecurityParameters().masterSecret;
+
+ d.update(secret, 0, secret.length);
+ d.update(ipad, 0, padLength);
+
+ byte[] tmp = new byte[d.getDigestSize()];
+ d.doFinal(tmp, 0);
+
+ d.update(secret, 0, secret.length);
+ d.update(opad, 0, padLength);
+ d.update(tmp, 0, tmp.length);
+ }
+}