1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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);
}
}
|