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
118
|
using System;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls
{
/// <summary>
/// A NULL CipherSuite, with optional MAC.
/// </summary>
public class TlsNullCipher
: TlsCipher
{
protected readonly TlsContext context;
protected readonly TlsMac writeMac;
protected readonly TlsMac readMac;
public TlsNullCipher(TlsContext context)
{
this.context = context;
this.writeMac = null;
this.readMac = null;
}
/// <exception cref="IOException"></exception>
public TlsNullCipher(TlsContext context, IDigest clientWriteDigest, IDigest serverWriteDigest)
{
if ((clientWriteDigest == null) != (serverWriteDigest == null))
throw new TlsFatalAlert(AlertDescription.internal_error);
this.context = context;
TlsMac clientWriteMac = null, serverWriteMac = null;
if (clientWriteDigest != null)
{
int key_block_size = clientWriteDigest.GetDigestSize()
+ serverWriteDigest.GetDigestSize();
byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size);
int offset = 0;
clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset,
clientWriteDigest.GetDigestSize());
offset += clientWriteDigest.GetDigestSize();
serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset,
serverWriteDigest.GetDigestSize());
offset += serverWriteDigest.GetDigestSize();
if (offset != key_block_size)
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
if (context.IsServer)
{
writeMac = serverWriteMac;
readMac = clientWriteMac;
}
else
{
writeMac = clientWriteMac;
readMac = serverWriteMac;
}
}
public virtual int GetPlaintextLimit(int ciphertextLimit)
{
int result = ciphertextLimit;
if (writeMac != null)
{
result -= writeMac.Size;
}
return result;
}
/// <exception cref="IOException"></exception>
public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
{
if (writeMac == null)
{
return Arrays.CopyOfRange(plaintext, offset, offset + len);
}
byte[] mac = writeMac.CalculateMac(seqNo, type, plaintext, offset, len);
byte[] ciphertext = new byte[len + mac.Length];
Array.Copy(plaintext, offset, ciphertext, 0, len);
Array.Copy(mac, 0, ciphertext, len, mac.Length);
return ciphertext;
}
/// <exception cref="IOException"></exception>
public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
{
if (readMac == null)
{
return Arrays.CopyOfRange(ciphertext, offset, offset + len);
}
int macSize = readMac.Size;
if (len < macSize)
throw new TlsFatalAlert(AlertDescription.decode_error);
int macInputLen = len - macSize;
byte[] receivedMac = Arrays.CopyOfRange(ciphertext, offset + macInputLen, offset + len);
byte[] computedMac = readMac.CalculateMac(seqNo, type, ciphertext, offset, macInputLen);
if (!Arrays.ConstantTimeAreEqual(receivedMac, computedMac))
throw new TlsFatalAlert(AlertDescription.bad_record_mac);
return Arrays.CopyOfRange(ciphertext, offset, offset + macInputLen);
}
}
}
|