diff --git a/crypto/src/bcpg/S2k.cs b/crypto/src/bcpg/S2k.cs
index de08c016c..f6d306890 100644
--- a/crypto/src/bcpg/S2k.cs
+++ b/crypto/src/bcpg/S2k.cs
@@ -16,6 +16,8 @@ namespace Org.BouncyCastle.Bcpg
public const int Salted = 1;
public const int SaltedAndIterated = 3;
public const int GnuDummyS2K = 101;
+ public const int GnuProtectionModeNoPrivateKey = 1;
+ public const int GnuProtectionModeDivertToCard = 2;
internal int type;
internal HashAlgorithmTag algorithm;
diff --git a/crypto/src/crypto/BufferedAeadBlockCipher.cs b/crypto/src/crypto/BufferedAeadBlockCipher.cs
index 04bcb88ed..7ba41090f 100644
--- a/crypto/src/crypto/BufferedAeadBlockCipher.cs
+++ b/crypto/src/crypto/BufferedAeadBlockCipher.cs
@@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Crypto
}
/**
- * process a single byte, producing an output block if neccessary.
+ * process a single byte, producing an output block if necessary.
*
* @param in the input byte.
* @param out the space for any output that might be produced.
diff --git a/crypto/src/crypto/BufferedBlockCipher.cs b/crypto/src/crypto/BufferedBlockCipher.cs
index 3a98798a2..c87d2daf9 100644
--- a/crypto/src/crypto/BufferedBlockCipher.cs
+++ b/crypto/src/crypto/BufferedBlockCipher.cs
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto
}
/**
- * process a single byte, producing an output block if neccessary.
+ * process a single byte, producing an output block if necessary.
*
* @param in the input byte.
* @param out the space for any output that might be produced.
@@ -223,13 +223,10 @@ namespace Org.BouncyCastle.Crypto
if (outLength > 0)
{
- if ((outOff + outLength) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.OutputLength(output, outOff, outLength, "output buffer too short");
}
- int resultLen = 0;
+ int resultLen = 0;
int gapLen = buf.Length - bufOff;
if (length > gapLen)
{
@@ -339,17 +336,10 @@ namespace Org.BouncyCastle.Crypto
{
if (bufOff != 0)
{
- if (!cipher.IsPartialBlockOkay)
- {
- throw new DataLengthException("data not block size aligned");
- }
-
- if (outOff + bufOff > output.Length)
- {
- throw new DataLengthException("output buffer too short for DoFinal()");
- }
-
- // NB: Can't copy directly, or we may write too much output
+ Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned");
+ Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()");
+
+ // NB: Can't copy directly, or we may write too much output
cipher.ProcessBlock(buf, 0, buf, 0);
Array.Copy(buf, 0, output, outOff, bufOff);
}
diff --git a/crypto/src/crypto/Check.cs b/crypto/src/crypto/Check.cs
new file mode 100644
index 000000000..96a05c64b
--- /dev/null
+++ b/crypto/src/crypto/Check.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Org.BouncyCastle.Crypto
+{
+ internal class Check
+ {
+ internal static void DataLength(bool condition, string msg)
+ {
+ if (condition)
+ throw new DataLengthException(msg);
+ }
+
+ internal static void DataLength(byte[] buf, int off, int len, string msg)
+ {
+ if (off + len > buf.Length)
+ throw new DataLengthException(msg);
+ }
+
+ internal static void OutputLength(byte[] buf, int off, int len, string msg)
+ {
+ if (off + len > buf.Length)
+ throw new OutputLengthException(msg);
+ }
+ }
+}
diff --git a/crypto/src/crypto/OutputLengthException.cs b/crypto/src/crypto/OutputLengthException.cs
new file mode 100644
index 000000000..e1cf44925
--- /dev/null
+++ b/crypto/src/crypto/OutputLengthException.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Org.BouncyCastle.Crypto
+{
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+ [Serializable]
+#endif
+ public class OutputLengthException
+ : DataLengthException
+ {
+ public OutputLengthException()
+ {
+ }
+
+ public OutputLengthException(
+ string message)
+ : base(message)
+ {
+ }
+
+ public OutputLengthException(
+ string message,
+ Exception exception)
+ : base(message, exception)
+ {
+ }
+ }
+}
diff --git a/crypto/src/crypto/agreement/srp/SRP6Client.cs b/crypto/src/crypto/agreement/srp/SRP6Client.cs
index 309736564..f075d7ad1 100644
--- a/crypto/src/crypto/agreement/srp/SRP6Client.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6Client.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
@@ -24,7 +25,11 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
protected BigInteger u;
protected BigInteger S;
- protected IDigest digest;
+ protected BigInteger M1;
+ protected BigInteger M2;
+ protected BigInteger Key;
+
+ protected IDigest digest;
protected SecureRandom random;
public Srp6Client()
@@ -46,6 +51,11 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
this.random = random;
}
+ public virtual void Init(Srp6GroupParameters group, IDigest digest, SecureRandom random)
+ {
+ Init(group.N, group.G, digest, random);
+ }
+
/**
* Generates client's credentials given the client's salt, identity and password
* @param salt The salt used in the client's verifier.
@@ -89,5 +99,66 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
BigInteger tmp = g.ModPow(x, N).Multiply(k).Mod(N);
return B.Subtract(tmp).Mod(N).ModPow(exp, N);
}
+
+ /**
+ * Computes the client evidence message M1 using the previously received values.
+ * To be called after calculating the secret S.
+ * @return M1: the client side generated evidence message
+ * @throws CryptoException
+ */
+ public virtual BigInteger CalculateClientEvidenceMessage()
+ {
+ // Verify pre-requirements
+ if (this.pubA == null || this.B == null || this.S == null)
+ {
+ throw new CryptoException("Impossible to compute M1: " +
+ "some data are missing from the previous operations (A,B,S)");
+ }
+ // compute the client evidence message 'M1'
+ this.M1 = Srp6Utilities.CalculateM1(digest, N, pubA, B, S);
+ return M1;
+ }
+
+ /** Authenticates the server evidence message M2 received and saves it only if correct.
+ * @param M2: the server side generated evidence message
+ * @return A boolean indicating if the server message M2 was the expected one.
+ * @throws CryptoException
+ */
+ public virtual bool VerifyServerEvidenceMessage(BigInteger serverM2)
+ {
+ // Verify pre-requirements
+ if (this.pubA == null || this.M1 == null || this.S == null)
+ {
+ throw new CryptoException("Impossible to compute and verify M2: " +
+ "some data are missing from the previous operations (A,M1,S)");
+ }
+
+ // Compute the own server evidence message 'M2'
+ BigInteger computedM2 = Srp6Utilities.CalculateM2(digest, N, pubA, M1, S);
+ if (computedM2.Equals(serverM2))
+ {
+ this.M2 = serverM2;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Computes the final session key as a result of the SRP successful mutual authentication
+ * To be called after verifying the server evidence message M2.
+ * @return Key: the mutually authenticated symmetric session key
+ * @throws CryptoException
+ */
+ public virtual BigInteger CalculateSessionKey()
+ {
+ // Verify pre-requirements (here we enforce a previous calculation of M1 and M2)
+ if (this.S == null || this.M1 == null || this.M2 == null)
+ {
+ throw new CryptoException("Impossible to compute Key: " +
+ "some data are missing from the previous operations (S,M1,M2)");
+ }
+ this.Key = Srp6Utilities.CalculateKey(digest, N, S);
+ return Key;
+ }
}
}
diff --git a/crypto/src/crypto/agreement/srp/SRP6Server.cs b/crypto/src/crypto/agreement/srp/SRP6Server.cs
index 35b96d488..fd0c9f1cb 100644
--- a/crypto/src/crypto/agreement/srp/SRP6Server.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6Server.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
@@ -26,6 +27,9 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
protected BigInteger u;
protected BigInteger S;
+ protected BigInteger M1;
+ protected BigInteger M2;
+ protected BigInteger Key;
public Srp6Server()
{
@@ -49,6 +53,11 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
this.digest = digest;
}
+ public virtual void Init(Srp6GroupParameters group, BigInteger v, IDigest digest, SecureRandom random)
+ {
+ Init(group.N, group.G, v, digest, random);
+ }
+
/**
* Generates the server's credentials that are to be sent to the client.
* @return The server's public value to the client
@@ -82,9 +91,73 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
return Srp6Utilities.GeneratePrivateValue(digest, N, g, random);
}
- private BigInteger CalculateS()
+ private BigInteger CalculateS()
{
return v.ModPow(u, N).Multiply(A).Mod(N).ModPow(privB, N);
}
+
+ /**
+ * Authenticates the received client evidence message M1 and saves it only if correct.
+ * To be called after calculating the secret S.
+ * @param M1: the client side generated evidence message
+ * @return A boolean indicating if the client message M1 was the expected one.
+ * @throws CryptoException
+ */
+ public virtual bool VerifyClientEvidenceMessage(BigInteger clientM1)
+ {
+ // Verify pre-requirements
+ if (this.A == null || this.pubB == null || this.S == null)
+ {
+ throw new CryptoException("Impossible to compute and verify M1: " +
+ "some data are missing from the previous operations (A,B,S)");
+ }
+
+ // Compute the own client evidence message 'M1'
+ BigInteger computedM1 = Srp6Utilities.CalculateM1(digest, N, A, pubB, S);
+ if (computedM1.Equals(clientM1))
+ {
+ this.M1 = clientM1;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Computes the server evidence message M2 using the previously verified values.
+ * To be called after successfully verifying the client evidence message M1.
+ * @return M2: the server side generated evidence message
+ * @throws CryptoException
+ */
+ public virtual BigInteger CalculateServerEvidenceMessage()
+ {
+ // Verify pre-requirements
+ if (this.A == null || this.M1 == null || this.S == null)
+ {
+ throw new CryptoException("Impossible to compute M2: " +
+ "some data are missing from the previous operations (A,M1,S)");
+ }
+
+ // Compute the server evidence message 'M2'
+ this.M2 = Srp6Utilities.CalculateM2(digest, N, A, M1, S);
+ return M2;
+ }
+
+ /**
+ * Computes the final session key as a result of the SRP successful mutual authentication
+ * To be called after calculating the server evidence message M2.
+ * @return Key: the mutual authenticated symmetric session key
+ * @throws CryptoException
+ */
+ public virtual BigInteger CalculateSessionKey()
+ {
+ // Verify pre-requirements
+ if (this.S == null || this.M1 == null || this.M2 == null)
+ {
+ throw new CryptoException("Impossible to compute Key: " +
+ "some data are missing from the previous operations (S,M1,M2)");
+ }
+ this.Key = Srp6Utilities.CalculateKey(digest, N, S);
+ return Key;
+ }
}
}
diff --git a/crypto/src/crypto/agreement/srp/SRP6StandardGroups.cs b/crypto/src/crypto/agreement/srp/SRP6StandardGroups.cs
new file mode 100644
index 000000000..36f4aba11
--- /dev/null
+++ b/crypto/src/crypto/agreement/srp/SRP6StandardGroups.cs
@@ -0,0 +1,159 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Crypto.Agreement.Srp
+{
+ public class Srp6StandardGroups
+ {
+ private static BigInteger FromHex(string hex)
+ {
+ return new BigInteger(1, Hex.Decode(hex));
+ }
+
+ private static Srp6GroupParameters FromNG(string hexN, string hexG)
+ {
+ return new Srp6GroupParameters(FromHex(hexN), FromHex(hexG));
+ }
+
+ /*
+ * RFC 5054
+ */
+ private const string rfc5054_1024_N = "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
+ + "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
+ + "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
+ + "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" + "FD5138FE8376435B9FC61D2FC0EB06E3";
+ private const string rfc5054_1024_g = "02";
+ public static readonly Srp6GroupParameters rfc5054_1024 = FromNG(rfc5054_1024_N, rfc5054_1024_g);
+
+ private const string rfc5054_1536_N = "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA961"
+ + "4B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F843"
+ + "80B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0B"
+ + "E3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF5"
+ + "6EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734A"
+ + "F7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E"
+ + "8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB";
+ private const string rfc5054_1536_g = "02";
+ public static readonly Srp6GroupParameters rfc5054_1536 = FromNG(rfc5054_1536_N, rfc5054_1536_g);
+
+ private const string rfc5054_2048_N = "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC319294"
+ + "3DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310D"
+ + "CD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FB"
+ + "D5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF74"
+ + "7359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A"
+ + "436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D"
+ + "5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E73"
+ + "03CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB6"
+ + "94B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F" + "9E4AFF73";
+ private const string rfc5054_2048_g = "02";
+ public static readonly Srp6GroupParameters rfc5054_2048 = FromNG(rfc5054_2048_N, rfc5054_2048_g);
+
+ private const string rfc5054_3072_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
+ private const string rfc5054_3072_g = "05";
+ public static readonly Srp6GroupParameters rfc5054_3072 = FromNG(rfc5054_3072_N, rfc5054_3072_g);
+
+ private const string rfc5054_4096_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
+ + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
+ + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
+ + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
+ + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
+ + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF";
+ private const string rfc5054_4096_g = "05";
+ public static readonly Srp6GroupParameters rfc5054_4096 = FromNG(rfc5054_4096_N, rfc5054_4096_g);
+
+ private const string rfc5054_6144_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
+ + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
+ + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
+ + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
+ + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
+ + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
+ + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406"
+ + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918"
+ + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151"
+ + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03"
+ + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F"
+ + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
+ + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B"
+ + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632"
+ + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF";
+ private const string rfc5054_6144_g = "05";
+ public static readonly Srp6GroupParameters rfc5054_6144 = FromNG(rfc5054_6144_N, rfc5054_6144_g);
+
+ private const string rfc5054_8192_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
+ + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
+ + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
+ + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
+ + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
+ + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
+ + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406"
+ + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918"
+ + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151"
+ + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03"
+ + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F"
+ + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
+ + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B"
+ + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632"
+ + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E"
+ + "6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA"
+ + "3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C"
+ + "5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
+ + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC886"
+ + "2F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6"
+ + "6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC5"
+ + "0846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268"
+ + "359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6"
+ + "FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF";
+ private const string rfc5054_8192_g = "13";
+ public static readonly Srp6GroupParameters rfc5054_8192 = FromNG(rfc5054_8192_N, rfc5054_8192_g);
+ }
+}
diff --git a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
index 4e790f572..ef6d8f24c 100644
--- a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
@@ -54,7 +54,75 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
return val;
}
- private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
+ /**
+ * Computes the client evidence message (M1) according to the standard routine:
+ * M1 = H( A | B | S )
+ * @param digest The Digest used as the hashing function H
+ * @param N Modulus used to get the pad length
+ * @param A The public client value
+ * @param B The public server value
+ * @param S The secret calculated by both sides
+ * @return M1 The calculated client evidence message
+ */
+ public static BigInteger CalculateM1(IDigest digest, BigInteger N, BigInteger A, BigInteger B, BigInteger S)
+ {
+ BigInteger M1 = HashPaddedTriplet(digest, N, A, B, S);
+ return M1;
+ }
+
+ /**
+ * Computes the server evidence message (M2) according to the standard routine:
+ * M2 = H( A | M1 | S )
+ * @param digest The Digest used as the hashing function H
+ * @param N Modulus used to get the pad length
+ * @param A The public client value
+ * @param M1 The client evidence message
+ * @param S The secret calculated by both sides
+ * @return M2 The calculated server evidence message
+ */
+ public static BigInteger CalculateM2(IDigest digest, BigInteger N, BigInteger A, BigInteger M1, BigInteger S)
+ {
+ BigInteger M2 = HashPaddedTriplet(digest, N, A, M1, S);
+ return M2;
+ }
+
+ /**
+ * Computes the final Key according to the standard routine: Key = H(S)
+ * @param digest The Digest used as the hashing function H
+ * @param N Modulus used to get the pad length
+ * @param S The secret calculated by both sides
+ * @return
+ */
+ public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
+ {
+ int padLength = (N.BitLength + 7) / 8;
+ byte[] _S = GetPadded(S, padLength);
+ digest.BlockUpdate(_S, 0, _S.Length);
+
+ byte[] output = new byte[digest.GetDigestSize()];
+ digest.DoFinal(output, 0);
+ return new BigInteger(1, output);
+ }
+
+ private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
+ {
+ int padLength = (N.BitLength + 7) / 8;
+
+ byte[] n1_bytes = GetPadded(n1, padLength);
+ byte[] n2_bytes = GetPadded(n2, padLength);
+ byte[] n3_bytes = GetPadded(n3, padLength);
+
+ digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length);
+ digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length);
+ digest.BlockUpdate(n3_bytes, 0, n3_bytes.Length);
+
+ byte[] output = new byte[digest.GetDigestSize()];
+ digest.DoFinal(output, 0);
+
+ return new BigInteger(1, output);
+ }
+
+ private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
{
int padLength = (N.BitLength + 7) / 8;
diff --git a/crypto/src/crypto/agreement/srp/SRP6VerifierGenerator.cs b/crypto/src/crypto/agreement/srp/SRP6VerifierGenerator.cs
index 264833b4d..956973598 100644
--- a/crypto/src/crypto/agreement/srp/SRP6VerifierGenerator.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6VerifierGenerator.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Agreement.Srp
@@ -31,7 +32,12 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
this.digest = digest;
}
- /**
+ public virtual void Init(Srp6GroupParameters group, IDigest digest)
+ {
+ Init(group.N, group.G, digest);
+ }
+
+ /**
* Creates a new SRP verifier
* @param salt The salt to use, generally should be large and random
* @param identity The user's identifying information (eg. username)
diff --git a/crypto/src/crypto/engines/AesEngine.cs b/crypto/src/crypto/engines/AesEngine.cs
index 0cdd868fa..9d7f76c05 100644
--- a/crypto/src/crypto/engines/AesEngine.cs
+++ b/crypto/src/crypto/engines/AesEngine.cs
@@ -363,7 +363,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -377,41 +377,32 @@ namespace Org.BouncyCastle.Crypto.Engines
this.forEncryption = forEncryption;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "AES"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (WorkingKey == null)
- {
throw new InvalidOperationException("AES engine not initialised");
- }
- if ((inOff + (32 / 2)) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + (32 / 2)) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, 16, "input buffer too short");
+ Check.OutputLength(output, outOff, 16, "output buffer too short");
UnPackBlock(input, inOff);
@@ -429,7 +420,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/engines/AesFastEngine.cs b/crypto/src/crypto/engines/AesFastEngine.cs
index 38d3a5841..a1b544568 100644
--- a/crypto/src/crypto/engines/AesFastEngine.cs
+++ b/crypto/src/crypto/engines/AesFastEngine.cs
@@ -695,7 +695,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -709,41 +709,32 @@ namespace Org.BouncyCastle.Crypto.Engines
this.forEncryption = forEncryption;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "AES"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (WorkingKey == null)
- {
throw new InvalidOperationException("AES engine not initialised");
- }
- if ((inOff + (32 / 2)) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + (32 / 2)) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, 16, "input buffer too short");
+ Check.OutputLength(output, outOff, 16, "output buffer too short");
UnPackBlock(input, inOff);
@@ -761,7 +752,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/engines/AesLightEngine.cs b/crypto/src/crypto/engines/AesLightEngine.cs
index 54f2d2e88..a6b9e3bd4 100644
--- a/crypto/src/crypto/engines/AesLightEngine.cs
+++ b/crypto/src/crypto/engines/AesLightEngine.cs
@@ -258,7 +258,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -272,41 +272,32 @@ namespace Org.BouncyCastle.Crypto.Engines
this.forEncryption = forEncryption;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "AES"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (WorkingKey == null)
- {
throw new InvalidOperationException("AES engine not initialised");
- }
- if ((inOff + (32 / 2)) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + (32 / 2)) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, 16, "input buffer too short");
+ Check.OutputLength(output, outOff, 16, "output buffer too short");
UnPackBlock(input, inOff);
@@ -324,7 +315,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/engines/BlowfishEngine.cs b/crypto/src/crypto/engines/BlowfishEngine.cs
index 8f80f712e..7b50e832f 100644
--- a/crypto/src/crypto/engines/BlowfishEngine.cs
+++ b/crypto/src/crypto/engines/BlowfishEngine.cs
@@ -296,7 +296,7 @@ namespace Org.BouncyCastle.Crypto.Engines
//====================================
private static readonly int ROUNDS = 16;
- private const int BLOCK_SIZE = 8; // bytes = 64 bits
+ private const int BLOCK_SIZE = 8; // bytes = 64 bits
private static readonly int SBOX_SK = 256;
private static readonly int P_SZ = ROUNDS+2;
@@ -353,19 +353,10 @@ namespace Org.BouncyCastle.Crypto.Engines
int outOff)
{
if (workingKey == null)
- {
throw new InvalidOperationException("Blowfish not initialised");
- }
- if ((inOff + BLOCK_SIZE) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + BLOCK_SIZE) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
if (encrypting)
{
diff --git a/crypto/src/crypto/engines/CamelliaEngine.cs b/crypto/src/crypto/engines/CamelliaEngine.cs
index 8f4a442e9..71bd1b0dc 100644
--- a/crypto/src/crypto/engines/CamelliaEngine.cs
+++ b/crypto/src/crypto/engines/CamelliaEngine.cs
@@ -611,7 +611,7 @@ namespace Org.BouncyCastle.Crypto.Engines
{
}
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -623,22 +623,22 @@ namespace Org.BouncyCastle.Crypto.Engines
initialised = true;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Camellia"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -646,12 +646,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!initialised)
throw new InvalidOperationException("Camellia engine not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- if (_keyIs128)
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ if (_keyIs128)
{
return processBlock128(input, inOff, output, outOff);
}
@@ -661,7 +660,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public void Reset()
+ public virtual void Reset()
{
// nothing
}
diff --git a/crypto/src/crypto/engines/CamelliaLightEngine.cs b/crypto/src/crypto/engines/CamelliaLightEngine.cs
index a301eb55e..a132227c5 100644
--- a/crypto/src/crypto/engines/CamelliaLightEngine.cs
+++ b/crypto/src/crypto/engines/CamelliaLightEngine.cs
@@ -524,22 +524,22 @@ namespace Org.BouncyCastle.Crypto.Engines
initialised = false;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Camellia"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -551,7 +551,7 @@ namespace Org.BouncyCastle.Crypto.Engines
initialised = true;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -559,12 +559,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!initialised)
throw new InvalidOperationException("Camellia engine not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- if (_keyis128)
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ if (_keyis128)
{
return processBlock128(input, inOff, output, outOff);
}
@@ -574,7 +573,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public void Reset()
+ public virtual void Reset()
{
}
}
diff --git a/crypto/src/crypto/engines/Cast5Engine.cs b/crypto/src/crypto/engines/Cast5Engine.cs
index 4c3f84a55..1af30a335 100644
--- a/crypto/src/crypto/engines/Cast5Engine.cs
+++ b/crypto/src/crypto/engines/Cast5Engine.cs
@@ -329,7 +329,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -360,12 +360,11 @@ namespace Org.BouncyCastle.Crypto.Engines
int blockSize = GetBlockSize();
if (_workingKey == null)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + blockSize) > input.Length)
- throw new DataLengthException("Input buffer too short");
- if ((outOff + blockSize) > output.Length)
- throw new DataLengthException("Output buffer too short");
- if (_encrypting)
+ Check.DataLength(input, inOff, blockSize, "input buffer too short");
+ Check.OutputLength(output, outOff, blockSize, "output buffer too short");
+
+ if (_encrypting)
{
return EncryptBlock(input, inOff, output, outOff);
}
diff --git a/crypto/src/crypto/engines/ChaChaEngine.cs b/crypto/src/crypto/engines/ChaChaEngine.cs
index f4a7b8fe1..46b59ed2e 100644
--- a/crypto/src/crypto/engines/ChaChaEngine.cs
+++ b/crypto/src/crypto/engines/ChaChaEngine.cs
@@ -162,7 +162,6 @@ namespace Org.BouncyCastle.Crypto.Engines
x09 += x14; x04 = R(x04 ^ x09, 12);
x03 += x04; x14 = R(x14 ^ x03, 8);
x09 += x14; x04 = R(x04 ^ x09, 7);
-
}
x[ 0] = x00 + input[ 0];
@@ -182,8 +181,6 @@ namespace Org.BouncyCastle.Crypto.Engines
x[14] = x14 + input[14];
x[15] = x15 + input[15];
}
-
}
-
}
diff --git a/crypto/src/crypto/engines/DesEdeEngine.cs b/crypto/src/crypto/engines/DesEdeEngine.cs
index eec4ec59d..bc40b56a8 100644
--- a/crypto/src/crypto/engines/DesEdeEngine.cs
+++ b/crypto/src/crypto/engines/DesEdeEngine.cs
@@ -70,10 +70,9 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (workingKey1 == null)
throw new InvalidOperationException("DESede engine not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
+
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
byte[] temp = new byte[BLOCK_SIZE];
diff --git a/crypto/src/crypto/engines/DesEdeWrapEngine.cs b/crypto/src/crypto/engines/DesEdeWrapEngine.cs
index fdc71687f..43100a9bd 100644
--- a/crypto/src/crypto/engines/DesEdeWrapEngine.cs
+++ b/crypto/src/crypto/engines/DesEdeWrapEngine.cs
@@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forWrapping
* @param param
*/
- public void Init(
+ public virtual void Init(
bool forWrapping,
ICipherParameters parameters)
{
@@ -103,7 +103,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return
*/
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "DESede"; }
}
@@ -116,7 +116,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param inLen
* @return
*/
- public byte[] Wrap(
+ public virtual byte[] Wrap(
byte[] input,
int inOff,
int length)
@@ -185,7 +185,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return
* @throws InvalidCipherTextException
*/
- public byte[] Unwrap(
+ public virtual byte[] Unwrap(
byte[] input,
int inOff,
int length)
diff --git a/crypto/src/crypto/engines/DesEngine.cs b/crypto/src/crypto/engines/DesEngine.cs
index 067cf45e3..a6d580bb6 100644
--- a/crypto/src/crypto/engines/DesEngine.cs
+++ b/crypto/src/crypto/engines/DesEngine.cs
@@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Crypto.Engines
get { return "DES"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
@@ -59,12 +59,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (workingKey == null)
throw new InvalidOperationException("DES engine not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- DesFunc(workingKey, input, inOff, output, outOff);
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ DesFunc(workingKey, input, inOff, output, outOff);
return BLOCK_SIZE;
}
diff --git a/crypto/src/crypto/engines/ElGamalEngine.cs b/crypto/src/crypto/engines/ElGamalEngine.cs
index 3d256a087..197d7bc15 100644
--- a/crypto/src/crypto/engines/ElGamalEngine.cs
+++ b/crypto/src/crypto/engines/ElGamalEngine.cs
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Crypto.Engines
private bool forEncryption;
private int bitSize;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "ElGamal"; }
}
@@ -28,7 +28,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary ElGamal key parameters.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an input block.
*/
- public int GetInputBlockSize()
+ public virtual int GetInputBlockSize()
{
if (forEncryption)
{
@@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an output block.
*/
- public int GetOutputBlockSize()
+ public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
@@ -107,7 +107,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return the result of the ElGamal process.
* @exception DataLengthException the input block is too large.
*/
- public byte[] ProcessBlock(
+ public virtual byte[] ProcessBlock(
byte[] input,
int inOff,
int length)
diff --git a/crypto/src/crypto/engines/GOST28147Engine.cs b/crypto/src/crypto/engines/GOST28147Engine.cs
index 8eb6f36b5..e37ddaefd 100644
--- a/crypto/src/crypto/engines/GOST28147Engine.cs
+++ b/crypto/src/crypto/engines/GOST28147Engine.cs
@@ -150,7 +150,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -187,48 +187,39 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Gost28147"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BlockSize;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (workingKey == null)
- {
throw new InvalidOperationException("Gost28147 engine not initialised");
- }
- if ((inOff + BlockSize) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + BlockSize) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, BlockSize, "input buffer too short");
+ Check.OutputLength(output, outOff, BlockSize, "output buffer too short");
- Gost28147Func(workingKey, input, inOff, output, outOff);
+ Gost28147Func(workingKey, input, inOff, output, outOff);
return BlockSize;
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/engines/HC128Engine.cs b/crypto/src/crypto/engines/HC128Engine.cs
index a2d099f87..40c7a4e17 100644
--- a/crypto/src/crypto/engines/HC128Engine.cs
+++ b/crypto/src/crypto/engines/HC128Engine.cs
@@ -142,7 +142,7 @@ namespace Org.BouncyCastle.Crypto.Engines
cnt = 0;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "HC-128"; }
}
@@ -156,7 +156,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @throws ArgumentException if the params argument is
* inappropriate (ie. the key is not 128 bit long).
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -201,7 +201,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return ret;
}
- public void ProcessBytes(
+ public virtual void ProcessBytes(
byte[] input,
int inOff,
int len,
@@ -210,24 +210,23 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + len) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + len) > output.Length)
- throw new DataLengthException("output buffer too short");
- for (int i = 0; i < len; i++)
+ Check.DataLength(input, inOff, len, "input buffer too short");
+ Check.OutputLength(output, outOff, len, "output buffer too short");
+
+ for (int i = 0; i < len; i++)
{
output[outOff + i] = (byte)(input[inOff + i] ^ GetByte());
}
}
- public void Reset()
+ public virtual void Reset()
{
idx = 0;
Init();
}
- public byte ReturnByte(byte input)
+ public virtual byte ReturnByte(byte input)
{
return (byte)(input ^ GetByte());
}
diff --git a/crypto/src/crypto/engines/HC256Engine.cs b/crypto/src/crypto/engines/HC256Engine.cs
index da717dab7..6eb360711 100644
--- a/crypto/src/crypto/engines/HC256Engine.cs
+++ b/crypto/src/crypto/engines/HC256Engine.cs
@@ -126,7 +126,7 @@ namespace Org.BouncyCastle.Crypto.Engines
cnt = 0;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "HC-256"; }
}
@@ -140,7 +140,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @throws ArgumentException if the params argument is
* inappropriate (ie. the key is not 256 bit long).
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -185,7 +185,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return ret;
}
- public void ProcessBytes(
+ public virtual void ProcessBytes(
byte[] input,
int inOff,
int len,
@@ -194,24 +194,23 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + len) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + len) > output.Length)
- throw new DataLengthException("output buffer too short");
- for (int i = 0; i < len; i++)
+ Check.DataLength(input, inOff, len, "input buffer too short");
+ Check.OutputLength(output, outOff, len, "output buffer too short");
+
+ for (int i = 0; i < len; i++)
{
output[outOff + i] = (byte)(input[inOff + i] ^ GetByte());
}
}
- public void Reset()
+ public virtual void Reset()
{
idx = 0;
Init();
}
- public byte ReturnByte(byte input)
+ public virtual byte ReturnByte(byte input)
{
return (byte)(input ^ GetByte());
}
diff --git a/crypto/src/crypto/engines/ISAACEngine.cs b/crypto/src/crypto/engines/ISAACEngine.cs
index 9c58678a0..f25577130 100644
--- a/crypto/src/crypto/engines/ISAACEngine.cs
+++ b/crypto/src/crypto/engines/ISAACEngine.cs
@@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the params argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Crypto.Engines
setKey(p.GetKey());
}
- public byte ReturnByte(
+ public virtual byte ReturnByte(
byte input)
{
if (index == 0)
@@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return output;
}
- public void ProcessBytes(
+ public virtual void ProcessBytes(
byte[] input,
int inOff,
int len,
@@ -77,10 +77,9 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + len) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + len) > output.Length)
- throw new DataLengthException("output buffer too short");
+
+ Check.DataLength(input, inOff, len, "input buffer too short");
+ Check.OutputLength(output, outOff, len, "output buffer too short");
for (int i = 0; i < len; i++)
{
@@ -94,12 +93,12 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "ISAAC"; }
}
- public void Reset()
+ public virtual void Reset()
{
setKey(workingKey);
}
diff --git a/crypto/src/crypto/engines/IdeaEngine.cs b/crypto/src/crypto/engines/IdeaEngine.cs
index 46b5a787c..4909510ac 100644
--- a/crypto/src/crypto/engines/IdeaEngine.cs
+++ b/crypto/src/crypto/engines/IdeaEngine.cs
@@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -58,43 +58,37 @@ namespace Org.BouncyCastle.Crypto.Engines
((KeyParameter)parameters).GetKey());
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "IDEA"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (workingKey == null)
- {
throw new InvalidOperationException("IDEA engine not initialised");
- }
- if ((inOff + BLOCK_SIZE) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
- if ((outOff + BLOCK_SIZE) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
IdeaFunc(workingKey, input, inOff, output, outOff);
return BLOCK_SIZE;
}
- public void Reset()
+ public virtual void Reset()
{
}
private static readonly int MASK = 0xffff;
diff --git a/crypto/src/crypto/engines/IesEngine.cs b/crypto/src/crypto/engines/IesEngine.cs
index 70df3077c..a2004a9d6 100644
--- a/crypto/src/crypto/engines/IesEngine.cs
+++ b/crypto/src/crypto/engines/IesEngine.cs
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param pubParam the recipient's/sender's public key parameters
* @param param encoding and derivation parameters.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters privParameters,
ICipherParameters pubParameters,
@@ -213,7 +213,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return buf;
}
- public byte[] ProcessBlock(
+ public virtual byte[] ProcessBlock(
byte[] input,
int inOff,
int inLen)
@@ -224,10 +224,16 @@ namespace Org.BouncyCastle.Crypto.Engines
byte[] zBytes = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), z);
- return forEncryption
- ? EncryptBlock(input, inOff, inLen, zBytes)
- : DecryptBlock(input, inOff, inLen, zBytes);
+ try
+ {
+ return forEncryption
+ ? EncryptBlock(input, inOff, inLen, zBytes)
+ : DecryptBlock(input, inOff, inLen, zBytes);
+ }
+ finally
+ {
+ Array.Clear(zBytes, 0, zBytes.Length);
+ }
}
}
-
}
diff --git a/crypto/src/crypto/engines/NaccacheSternEngine.cs b/crypto/src/crypto/engines/NaccacheSternEngine.cs
index 9ca092351..e547e0caf 100644
--- a/crypto/src/crypto/engines/NaccacheSternEngine.cs
+++ b/crypto/src/crypto/engines/NaccacheSternEngine.cs
@@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool,
* org.bouncycastle.crypto.CipherParameters)
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public bool Debug
+ public virtual bool Debug
{
set { this.debug = value; }
}
@@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetInputBlockSize()
*/
- public int GetInputBlockSize()
+ public virtual int GetInputBlockSize()
{
if (forEncryption)
{
@@ -113,7 +113,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetOutputBlockSize()
*/
- public int GetOutputBlockSize()
+ public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
@@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#ProcessBlock(byte[],
* int, int)
*/
- public byte[] ProcessBlock(
+ public virtual byte[] ProcessBlock(
byte[] inBytes,
int inOff,
int length)
@@ -245,7 +245,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return The byte[] representation of the encrypted BigInteger (i.e.
* crypted.toByteArray())
*/
- public byte[] Encrypt(
+ public virtual byte[] Encrypt(
BigInteger plain)
{
// Always return modulus size values 0-padded at the beginning
@@ -273,7 +273,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return encrypt((block1 + block2) mod sigma)
* @throws InvalidCipherTextException
*/
- public byte[] AddCryptedBlocks(
+ public virtual byte[] AddCryptedBlocks(
byte[] block1,
byte[] block2)
{
@@ -329,7 +329,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return the data after it went through the NaccacheSternEngine.
* @throws InvalidCipherTextException
*/
- public byte[] ProcessData(
+ public virtual byte[] ProcessData(
byte[] data)
{
if (debug)
diff --git a/crypto/src/crypto/engines/NoekeonEngine.cs b/crypto/src/crypto/engines/NoekeonEngine.cs
index b73e696a9..dd78a4ea5 100644
--- a/crypto/src/crypto/engines/NoekeonEngine.cs
+++ b/crypto/src/crypto/engines/NoekeonEngine.cs
@@ -42,17 +42,17 @@ namespace Org.BouncyCastle.Crypto.Engines
_initialised = false;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Noekeon"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return GenericSize;
}
@@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the params argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -80,7 +80,7 @@ namespace Org.BouncyCastle.Crypto.Engines
setKey(p.GetKey());
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -88,17 +88,16 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!_initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + GenericSize) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + GenericSize) > output.Length)
- throw new DataLengthException("output buffer too short");
- return _forEncryption
+ Check.DataLength(input, inOff, GenericSize, "input buffer too short");
+ Check.OutputLength(output, outOff, GenericSize, "output buffer too short");
+
+ return _forEncryption
? encryptBlock(input, inOff, output, outOff)
: decryptBlock(input, inOff, output, outOff);
}
- public void Reset()
+ public virtual void Reset()
{
// TODO This should do something in case the encryption is aborted
}
diff --git a/crypto/src/crypto/engines/NullEngine.cs b/crypto/src/crypto/engines/NullEngine.cs
index 407b8ccc6..f883b7c29 100644
--- a/crypto/src/crypto/engines/NullEngine.cs
+++ b/crypto/src/crypto/engines/NullEngine.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Crypto.Engines
{
}
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -26,22 +26,22 @@ namespace Org.BouncyCastle.Crypto.Engines
initialised = true;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Null"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return true; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BlockSize;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -49,12 +49,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (!initialised)
throw new InvalidOperationException("Null engine not initialised");
- if ((inOff + BlockSize) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BlockSize) > output.Length)
- throw new DataLengthException("output buffer too short");
- for (int i = 0; i < BlockSize; ++i)
+ Check.DataLength(input, inOff, BlockSize, "input buffer too short");
+ Check.OutputLength(output, outOff, BlockSize, "output buffer too short");
+
+ for (int i = 0; i < BlockSize; ++i)
{
output[outOff + i] = input[inOff + i];
}
@@ -62,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BlockSize;
}
- public void Reset()
+ public virtual void Reset()
{
// nothing needs to be done
}
diff --git a/crypto/src/crypto/engines/RC2Engine.cs b/crypto/src/crypto/engines/RC2Engine.cs
index aaf8c714c..b56953de5 100644
--- a/crypto/src/crypto/engines/RC2Engine.cs
+++ b/crypto/src/crypto/engines/RC2Engine.cs
@@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -139,26 +139,26 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public void Reset()
+ public virtual void Reset()
{
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RC2"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -166,12 +166,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (workingKey == null)
throw new InvalidOperationException("RC2 engine not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- if (encrypting)
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
@@ -308,5 +307,4 @@ namespace Org.BouncyCastle.Crypto.Engines
outBytes[outOff + 7] = (byte)(x76 >> 8);
}
}
-
}
diff --git a/crypto/src/crypto/engines/RC2WrapEngine.cs b/crypto/src/crypto/engines/RC2WrapEngine.cs
index 238c9f76a..5742aa8b7 100644
--- a/crypto/src/crypto/engines/RC2WrapEngine.cs
+++ b/crypto/src/crypto/engines/RC2WrapEngine.cs
@@ -51,7 +51,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forWrapping
* @param param
*/
- public void Init(
+ public virtual void Init(
bool forWrapping,
ICipherParameters parameters)
{
@@ -101,7 +101,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return
*/
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RC2"; }
}
@@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param inLen
* @return
*/
- public byte[] Wrap(
+ public virtual byte[] Wrap(
byte[] input,
int inOff,
int length)
@@ -215,7 +215,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return
* @throws InvalidCipherTextException
*/
- public byte[] Unwrap(
+ public virtual byte[] Unwrap(
byte[] input,
int inOff,
int length)
diff --git a/crypto/src/crypto/engines/RC4Engine.cs b/crypto/src/crypto/engines/RC4Engine.cs
index c65468d93..fd84b7d23 100644
--- a/crypto/src/crypto/engines/RC4Engine.cs
+++ b/crypto/src/crypto/engines/RC4Engine.cs
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -47,12 +47,12 @@ namespace Org.BouncyCastle.Crypto.Engines
throw new ArgumentException("invalid parameter passed to RC4 init - " + parameters.GetType().ToString());
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RC4"; }
}
- public byte ReturnByte(
+ public virtual byte ReturnByte(
byte input)
{
x = (x + 1) & 0xff;
@@ -67,23 +67,15 @@ namespace Org.BouncyCastle.Crypto.Engines
return (byte)(input ^ engineState[(engineState[x] + engineState[y]) & 0xff]);
}
- public void ProcessBytes(
+ public virtual void ProcessBytes(
byte[] input,
int inOff,
int length,
byte[] output,
- int outOff
- )
+ int outOff)
{
- if ((inOff + length) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + length) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, length, "input buffer too short");
+ Check.OutputLength(output, outOff, length, "output buffer too short");
for (int i = 0; i < length ; i++)
{
@@ -101,7 +93,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public void Reset()
+ public virtual void Reset()
{
SetKey(workingKey);
}
@@ -143,5 +135,4 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
}
-
}
diff --git a/crypto/src/crypto/engines/RC532Engine.cs b/crypto/src/crypto/engines/RC532Engine.cs
index 1661707ef..169a60b98 100644
--- a/crypto/src/crypto/engines/RC532Engine.cs
+++ b/crypto/src/crypto/engines/RC532Engine.cs
@@ -48,17 +48,17 @@ namespace Org.BouncyCastle.Crypto.Engines
// _S = null;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RC5-32"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return 2 * 4;
}
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Crypto.Engines
this.forEncryption = forEncryption;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Crypto.Engines
: DecryptBlock(input, inOff, output, outOff);
}
- public void Reset()
+ public virtual void Reset()
{
}
@@ -290,5 +290,4 @@ namespace Org.BouncyCastle.Crypto.Engines
dst[dstOff + 3] = (byte)(word >> 24);
}
}
-
}
diff --git a/crypto/src/crypto/engines/RC564Engine.cs b/crypto/src/crypto/engines/RC564Engine.cs
index 5c69d40ff..ddcce0fa8 100644
--- a/crypto/src/crypto/engines/RC564Engine.cs
+++ b/crypto/src/crypto/engines/RC564Engine.cs
@@ -51,17 +51,17 @@ namespace Org.BouncyCastle.Crypto.Engines
// _S = null;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RC5-64"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return 2 * bytesPerWord;
}
@@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Crypto.Engines
SetKey(p.GetKey());
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -102,7 +102,7 @@ namespace Org.BouncyCastle.Crypto.Engines
: DecryptBlock(input, inOff, output, outOff);
}
- public void Reset()
+ public virtual void Reset()
{
}
@@ -291,5 +291,4 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
}
-
}
diff --git a/crypto/src/crypto/engines/RC6Engine.cs b/crypto/src/crypto/engines/RC6Engine.cs
index d72cc2f7b..196bd8394 100644
--- a/crypto/src/crypto/engines/RC6Engine.cs
+++ b/crypto/src/crypto/engines/RC6Engine.cs
@@ -48,17 +48,17 @@ namespace Org.BouncyCastle.Crypto.Engines
// _S = null;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RC6"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return 4 * bytesPerWord;
}
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -84,7 +84,7 @@ namespace Org.BouncyCastle.Crypto.Engines
SetKey(p.GetKey());
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -93,17 +93,16 @@ namespace Org.BouncyCastle.Crypto.Engines
int blockSize = GetBlockSize();
if (_S == null)
throw new InvalidOperationException("RC6 engine not initialised");
- if ((inOff + blockSize) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + blockSize) > output.Length)
- throw new DataLengthException("output buffer too short");
- return (forEncryption)
+ Check.DataLength(input, inOff, blockSize, "input buffer too short");
+ Check.OutputLength(output, outOff, blockSize, "output buffer too short");
+
+ return (forEncryption)
? EncryptBlock(input, inOff, output, outOff)
: DecryptBlock(input, inOff, output, outOff);
}
- public void Reset()
+ public virtual void Reset()
{
}
@@ -358,5 +357,4 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
}
-
}
diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs
index e520075f9..4e3af5227 100644
--- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs
+++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs
@@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Crypto.Engines
this.engine = new CbcBlockCipher(engine);
}
- public void Init(
+ public virtual void Init(
bool forWrapping,
ICipherParameters param)
{
@@ -48,12 +48,12 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap"; }
}
- public byte[] Wrap(
+ public virtual byte[] Wrap(
byte[] inBytes,
int inOff,
int inLen)
@@ -99,7 +99,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return cekBlock;
}
- public byte[] Unwrap(
+ public virtual byte[] Unwrap(
byte[] inBytes,
int inOff,
int inLen)
diff --git a/crypto/src/crypto/engines/RFC3394WrapEngine.cs b/crypto/src/crypto/engines/RFC3394WrapEngine.cs
index 5615a63e5..4bb0e2114 100644
--- a/crypto/src/crypto/engines/RFC3394WrapEngine.cs
+++ b/crypto/src/crypto/engines/RFC3394WrapEngine.cs
@@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Crypto.Engines
this.engine = engine;
}
- public void Init(
+ public virtual void Init(
bool forWrapping,
ICipherParameters parameters)
{
@@ -64,12 +64,12 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return engine.AlgorithmName; }
}
- public byte[] Wrap(
+ public virtual byte[] Wrap(
byte[] input,
int inOff,
int inLen)
@@ -119,7 +119,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return block;
}
- public byte[] Unwrap(
+ public virtual byte[] Unwrap(
byte[] input,
int inOff,
int inLen)
diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs
index cdf69ddda..037abf7e9 100644
--- a/crypto/src/crypto/engines/RSABlindedEngine.cs
+++ b/crypto/src/crypto/engines/RSABlindedEngine.cs
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Crypto.Engines
private RsaKeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RSA"; }
}
@@ -28,7 +28,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters param)
{
@@ -55,7 +55,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an input block.
*/
- public int GetInputBlockSize()
+ public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
@@ -67,7 +67,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an output block.
*/
- public int GetOutputBlockSize()
+ public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
@@ -81,7 +81,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return the result of the RSA process.
* @exception DataLengthException the input block is too large.
*/
- public byte[] ProcessBlock(
+ public virtual byte[] ProcessBlock(
byte[] inBuf,
int inOff,
int inLen)
diff --git a/crypto/src/crypto/engines/RSABlindingEngine.cs b/crypto/src/crypto/engines/RSABlindingEngine.cs
index 76b57a3f7..c636627bf 100644
--- a/crypto/src/crypto/engines/RSABlindingEngine.cs
+++ b/crypto/src/crypto/engines/RSABlindingEngine.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Engines
private bool forEncryption;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RSA"; }
}
@@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forEncryption true if we are encrypting (blinding), false otherwise.
* @param param the necessary RSA key parameters.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters param)
{
@@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an input block.
*/
- public int GetInputBlockSize()
+ public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
@@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an output block.
*/
- public int GetOutputBlockSize()
+ public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
@@ -89,7 +89,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return the result of the RSA process.
* @throws DataLengthException the input block is too large.
*/
- public byte[] ProcessBlock(
+ public virtual byte[] ProcessBlock(
byte[] inBuf,
int inOff,
int inLen)
diff --git a/crypto/src/crypto/engines/RSACoreEngine.cs b/crypto/src/crypto/engines/RSACoreEngine.cs
index 4e64d25d6..38326371f 100644
--- a/crypto/src/crypto/engines/RSACoreEngine.cs
+++ b/crypto/src/crypto/engines/RSACoreEngine.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -45,7 +45,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an input block.
*/
- public int GetInputBlockSize()
+ public virtual int GetInputBlockSize()
{
if (forEncryption)
{
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an output block.
*/
- public int GetOutputBlockSize()
+ public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return (bitSize - 1) / 8;
}
- public BigInteger ConvertInput(
+ public virtual BigInteger ConvertInput(
byte[] inBuf,
int inOff,
int inLen)
@@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return input;
}
- public byte[] ConvertOutput(
+ public virtual byte[] ConvertOutput(
BigInteger result)
{
byte[] output = result.ToByteArrayUnsigned();
@@ -112,7 +112,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return output;
}
- public BigInteger ProcessBlock(
+ public virtual BigInteger ProcessBlock(
BigInteger input)
{
if (key is RsaPrivateCrtKeyParameters)
diff --git a/crypto/src/crypto/engines/RijndaelEngine.cs b/crypto/src/crypto/engines/RijndaelEngine.cs
index df2e5baea..80f522353 100644
--- a/crypto/src/crypto/engines/RijndaelEngine.cs
+++ b/crypto/src/crypto/engines/RijndaelEngine.cs
@@ -571,7 +571,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -585,43 +585,34 @@ namespace Org.BouncyCastle.Crypto.Engines
throw new ArgumentException("invalid parameter passed to Rijndael init - " + parameters.GetType().ToString());
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Rijndael"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BC / 2;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
int outOff)
{
if (workingKey == null)
- {
throw new InvalidOperationException("Rijndael engine not initialised");
- }
-
- if ((inOff + (BC / 2)) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
- if ((outOff + (BC / 2)) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, (BC / 2), "input buffer too short");
+ Check.OutputLength(output, outOff, (BC / 2), "output buffer too short");
- UnPackBlock(input, inOff);
+ UnPackBlock(input, inOff);
if (forEncryption)
{
@@ -637,11 +628,11 @@ namespace Org.BouncyCastle.Crypto.Engines
return BC / 2;
}
- public void Reset()
+ public virtual void Reset()
{
}
- private void UnPackBlock(
+ private void UnPackBlock(
byte[] bytes,
int off)
{
@@ -743,5 +734,4 @@ namespace Org.BouncyCastle.Crypto.Engines
KeyAddition(rk[0]);
}
}
-
}
diff --git a/crypto/src/crypto/engines/RsaEngine.cs b/crypto/src/crypto/engines/RsaEngine.cs
index 7e6dfb163..4399b4409 100644
--- a/crypto/src/crypto/engines/RsaEngine.cs
+++ b/crypto/src/crypto/engines/RsaEngine.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Engines
{
private RsaCoreEngine core;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "RSA"; }
}
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an input block.
*/
- public int GetInputBlockSize()
+ public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
@@ -50,7 +50,7 @@ namespace Org.BouncyCastle.Crypto.Engines
*
* @return maximum size for an output block.
*/
- public int GetOutputBlockSize()
+ public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
@@ -64,7 +64,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @return the result of the RSA process.
* @exception DataLengthException the input block is too large.
*/
- public byte[] ProcessBlock(
+ public virtual byte[] ProcessBlock(
byte[] inBuf,
int inOff,
int inLen)
diff --git a/crypto/src/crypto/engines/SEEDEngine.cs b/crypto/src/crypto/engines/SEEDEngine.cs
index efea0f1fe..f615b8476 100644
--- a/crypto/src/crypto/engines/SEEDEngine.cs
+++ b/crypto/src/crypto/engines/SEEDEngine.cs
@@ -168,7 +168,7 @@ namespace Org.BouncyCastle.Crypto.Engines
private int[] wKey;
private bool forEncryption;
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -176,22 +176,22 @@ namespace Org.BouncyCastle.Crypto.Engines
wKey = createWorkingKey(((KeyParameter)parameters).GetKey());
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "SEED"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BlockSize;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] inBuf,
int inOff,
byte[] outBuf,
@@ -199,12 +199,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (wKey == null)
throw new InvalidOperationException("SEED engine not initialised");
- if (inOff + BlockSize > inBuf.Length)
- throw new DataLengthException("input buffer too short");
- if (outOff + BlockSize > outBuf.Length)
- throw new DataLengthException("output buffer too short");
- long l = bytesToLong(inBuf, inOff + 0);
+ Check.DataLength(inBuf, inOff, BlockSize, "input buffer too short");
+ Check.OutputLength(outBuf, outOff, BlockSize, "output buffer too short");
+
+ long l = bytesToLong(inBuf, inOff + 0);
long r = bytesToLong(inBuf, inOff + 8);
if (forEncryption)
@@ -234,7 +233,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BlockSize;
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/engines/Salsa20Engine.cs b/crypto/src/crypto/engines/Salsa20Engine.cs
index 81884d603..9b27dc7b4 100644
--- a/crypto/src/crypto/engines/Salsa20Engine.cs
+++ b/crypto/src/crypto/engines/Salsa20Engine.cs
@@ -61,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Engines
this.rounds = rounds;
}
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public byte ReturnByte(
+ public virtual byte ReturnByte(
byte input)
{
if (LimitExceeded())
@@ -136,7 +136,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public void ProcessBytes(
+ public virtual void ProcessBytes(
byte[] inBytes,
int inOff,
int len,
@@ -144,26 +144,15 @@ namespace Org.BouncyCastle.Crypto.Engines
int outOff)
{
if (!initialised)
- {
throw new InvalidOperationException(AlgorithmName + " not initialised");
- }
- if ((inOff + len) > inBytes.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
+ Check.DataLength(inBytes, inOff, len, "input buffer too short");
+ Check.OutputLength(outBytes, outOff, len, "output buffer too short");
- if ((outOff + len) > outBytes.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
-
- if (LimitExceeded((uint)len))
- {
+ if (LimitExceeded((uint)len))
throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV");
- }
- for (int i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
if (index == 0)
{
@@ -175,7 +164,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public void Reset()
+ public virtual void Reset()
{
index = 0;
ResetLimitCounter();
diff --git a/crypto/src/crypto/engines/SerpentEngine.cs b/crypto/src/crypto/engines/SerpentEngine.cs
index 92b25acc6..255c204ab 100644
--- a/crypto/src/crypto/engines/SerpentEngine.cs
+++ b/crypto/src/crypto/engines/SerpentEngine.cs
@@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -48,17 +48,17 @@ namespace Org.BouncyCastle.Crypto.Engines
this.wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey());
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Serpent"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
@@ -76,7 +76,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception InvalidOperationException if the cipher isn't initialised.
* @return the number of bytes processed and produced.
*/
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -84,12 +84,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (wKey == null)
throw new InvalidOperationException("Serpent not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- if (encrypting)
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
@@ -101,7 +100,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
- public void Reset()
+ public virtual void Reset()
{
}
@@ -775,5 +774,4 @@ namespace Org.BouncyCastle.Crypto.Engines
X0 = RotateRight(x0, 13);
}
}
-
}
diff --git a/crypto/src/crypto/engines/SkipjackEngine.cs b/crypto/src/crypto/engines/SkipjackEngine.cs
index 3d2a781e6..a45dc9b24 100644
--- a/crypto/src/crypto/engines/SkipjackEngine.cs
+++ b/crypto/src/crypto/engines/SkipjackEngine.cs
@@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -71,22 +71,22 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "SKIPJACK"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] input,
int inOff,
byte[] output,
@@ -94,12 +94,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (key1 == null)
throw new InvalidOperationException("SKIPJACK engine not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- if (encrypting)
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
@@ -111,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
- public void Reset()
+ public virtual void Reset()
{
}
@@ -135,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return ((g5 << 8) + g6);
}
- public int EncryptBlock(
+ public virtual int EncryptBlock(
byte[] input,
int inOff,
byte[] outBytes,
@@ -203,7 +202,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return ((h6 << 8) + h5);
}
- public int DecryptBlock(
+ public virtual int DecryptBlock(
byte[] input,
int inOff,
byte[] outBytes,
@@ -251,5 +250,4 @@ namespace Org.BouncyCastle.Crypto.Engines
return BLOCK_SIZE;
}
}
-
}
diff --git a/crypto/src/crypto/engines/TEAEngine.cs b/crypto/src/crypto/engines/TEAEngine.cs
index 582dd0f73..2e1a7002b 100644
--- a/crypto/src/crypto/engines/TEAEngine.cs
+++ b/crypto/src/crypto/engines/TEAEngine.cs
@@ -36,17 +36,17 @@ namespace Org.BouncyCastle.Crypto.Engines
_initialised = false;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "TEA"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return block_size;
}
@@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the params argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Crypto.Engines
setKey(p.GetKey());
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] inBytes,
int inOff,
byte[] outBytes,
@@ -86,18 +86,15 @@ namespace Org.BouncyCastle.Crypto.Engines
if (!_initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + block_size) > inBytes.Length)
- throw new DataLengthException("input buffer too short");
+ Check.DataLength(inBytes, inOff, block_size, "input buffer too short");
+ Check.OutputLength(outBytes, outOff, block_size, "output buffer too short");
- if ((outOff + block_size) > outBytes.Length)
- throw new DataLengthException("output buffer too short");
-
- return _forEncryption
+ return _forEncryption
? encryptBlock(inBytes, inOff, outBytes, outOff)
: decryptBlock(inBytes, inOff, outBytes, outOff);
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/engines/ThreefishEngine.cs b/crypto/src/crypto/engines/ThreefishEngine.cs
index 954470345..33ff3a421 100644
--- a/crypto/src/crypto/engines/ThreefishEngine.cs
+++ b/crypto/src/crypto/engines/ThreefishEngine.cs
@@ -155,7 +155,7 @@ namespace Org.BouncyCastle.Crypto.Engines
/// <param name="forEncryption">Initialise for encryption if true, for decryption if false.</param>
/// <param name="parameters">an instance of <see cref="TweakableBlockCipherParameters"/> or <see cref="KeyParameter"/> (to
/// use a 0 tweak)</param>
- public void Init(bool forEncryption, ICipherParameters parameters)
+ public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
byte[] keyBytes;
byte[] tweakBytes;
@@ -266,26 +266,26 @@ namespace Org.BouncyCastle.Crypto.Engines
t[4] = t[1];
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Threefish-" + (blocksizeBytes * 8); }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return blocksizeBytes;
}
- public void Reset()
+ public virtual void Reset()
{
}
- public int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
+ public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
if ((outOff + blocksizeBytes) > outBytes.Length)
{
diff --git a/crypto/src/crypto/engines/TwofishEngine.cs b/crypto/src/crypto/engines/TwofishEngine.cs
index b983d9d31..04a579ced 100644
--- a/crypto/src/crypto/engines/TwofishEngine.cs
+++ b/crypto/src/crypto/engines/TwofishEngine.cs
@@ -293,12 +293,11 @@ namespace Org.BouncyCastle.Crypto.Engines
{
if (workingKey == null)
throw new InvalidOperationException("Twofish not initialised");
- if ((inOff + BLOCK_SIZE) > input.Length)
- throw new DataLengthException("input buffer too short");
- if ((outOff + BLOCK_SIZE) > output.Length)
- throw new DataLengthException("output buffer too short");
- if (encrypting)
+ Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
+ Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
+
+ if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
diff --git a/crypto/src/crypto/engines/VMPCEngine.cs b/crypto/src/crypto/engines/VMPCEngine.cs
index 1c2802a80..852901e36 100644
--- a/crypto/src/crypto/engines/VMPCEngine.cs
+++ b/crypto/src/crypto/engines/VMPCEngine.cs
@@ -92,15 +92,8 @@ namespace Org.BouncyCastle.Crypto.Engines
byte[] output,
int outOff)
{
- if ((inOff + len) > input.Length)
- {
- throw new DataLengthException("input buffer too short");
- }
-
- if ((outOff + len) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.DataLength(input, inOff, len, "input buffer too short");
+ Check.OutputLength(output, outOff, len, "output buffer too short");
for (int i = 0; i < len; i++)
{
diff --git a/crypto/src/crypto/engines/XSalsa20Engine.cs b/crypto/src/crypto/engines/XSalsa20Engine.cs
index fc6630905..2898b46c8 100644
--- a/crypto/src/crypto/engines/XSalsa20Engine.cs
+++ b/crypto/src/crypto/engines/XSalsa20Engine.cs
@@ -13,7 +13,6 @@ namespace Org.BouncyCastle.Crypto.Engines
public class XSalsa20Engine
: Salsa20Engine
{
-
public override string AlgorithmName
{
get { return "XSalsa20"; }
@@ -65,7 +64,6 @@ namespace Org.BouncyCastle.Crypto.Engines
// Counter reset
ResetCounter();
}
-
}
}
diff --git a/crypto/src/crypto/engines/XTEAEngine.cs b/crypto/src/crypto/engines/XTEAEngine.cs
index eb9291775..40d81fbe6 100644
--- a/crypto/src/crypto/engines/XTEAEngine.cs
+++ b/crypto/src/crypto/engines/XTEAEngine.cs
@@ -34,17 +34,17 @@ namespace Org.BouncyCastle.Crypto.Engines
_initialised = false;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "XTEA"; }
}
- public bool IsPartialBlockOkay
+ public virtual bool IsPartialBlockOkay
{
get { return false; }
}
- public int GetBlockSize()
+ public virtual int GetBlockSize()
{
return block_size;
}
@@ -57,7 +57,7 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException if the params argument is
* inappropriate.
*/
- public void Init(
+ public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
@@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Engines
setKey(p.GetKey());
}
- public int ProcessBlock(
+ public virtual int ProcessBlock(
byte[] inBytes,
int inOff,
byte[] outBytes,
@@ -84,18 +84,15 @@ namespace Org.BouncyCastle.Crypto.Engines
if (!_initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
- if ((inOff + block_size) > inBytes.Length)
- throw new DataLengthException("input buffer too short");
+ Check.DataLength(inBytes, inOff, block_size, "input buffer too short");
+ Check.OutputLength(outBytes, outOff, block_size, "output buffer too short");
- if ((outOff + block_size) > outBytes.Length)
- throw new DataLengthException("output buffer too short");
-
- return _forEncryption
+ return _forEncryption
? encryptBlock(inBytes, inOff, outBytes, outOff)
: decryptBlock(inBytes, inOff, outBytes, outOff);
}
- public void Reset()
+ public virtual void Reset()
{
}
diff --git a/crypto/src/crypto/generators/RsaKeyPairGenerator.cs b/crypto/src/crypto/generators/RsaKeyPairGenerator.cs
index e870f1c08..2613b902b 100644
--- a/crypto/src/crypto/generators/RsaKeyPairGenerator.cs
+++ b/crypto/src/crypto/generators/RsaKeyPairGenerator.cs
@@ -4,6 +4,7 @@ using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC.Multiplier;
+using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators
{
@@ -11,117 +12,127 @@ namespace Org.BouncyCastle.Crypto.Generators
* an RSA key pair generator.
*/
public class RsaKeyPairGenerator
- : IAsymmetricCipherKeyPairGenerator
+ : IAsymmetricCipherKeyPairGenerator
{
- private static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001);
- private const int DefaultTests = 12;
+ private static readonly int[] SPECIAL_E_VALUES = new int[]{ 3, 5, 17, 257, 65537 };
+ private static readonly int SPECIAL_E_HIGHEST = SPECIAL_E_VALUES[SPECIAL_E_VALUES.Length - 1];
+ private static readonly int SPECIAL_E_BITS = BigInteger.ValueOf(SPECIAL_E_HIGHEST).BitLength;
- private RsaKeyGenerationParameters param;
+ protected static readonly BigInteger One = BigInteger.One;
+ protected static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001);
+ protected const int DefaultTests = 100;
- public void Init(
+ protected RsaKeyGenerationParameters parameters;
+
+ public virtual void Init(
KeyGenerationParameters parameters)
{
if (parameters is RsaKeyGenerationParameters)
{
- this.param = (RsaKeyGenerationParameters)parameters;
+ this.parameters = (RsaKeyGenerationParameters)parameters;
}
else
{
- this.param = new RsaKeyGenerationParameters(
+ this.parameters = new RsaKeyGenerationParameters(
DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests);
}
}
- public AsymmetricCipherKeyPair GenerateKeyPair()
+ public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
- BigInteger p, q, n, d, e, pSub1, qSub1, phi;
-
- //
- // p and q values should have a length of half the strength in bits
- //
- int strength = param.Strength;
- int qBitlength = strength >> 1;
- int pBitlength = strength - qBitlength;
- int mindiffbits = strength / 3;
- int minWeight = strength >> 2;
-
- e = param.PublicExponent;
-
- // TODO Consider generating safe primes for p, q (see DHParametersHelper.GenerateSafePrimes)
- // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
-
- p = ChooseRandomPrime(pBitlength, e);
-
- //
- // Generate a modulus of the required length
- //
for (;;)
{
- q = ChooseRandomPrime(qBitlength, e);
+ //
+ // p and q values should have a length of half the strength in bits
+ //
+ int strength = parameters.Strength;
+ int pBitlength = (strength + 1) / 2;
+ int qBitlength = strength - pBitlength;
+ int mindiffbits = strength / 3;
+ int minWeight = strength >> 2;
- // p and q should not be too close together (or equal!)
- BigInteger diff = q.Subtract(p).Abs();
- if (diff.BitLength < mindiffbits)
- continue;
+ BigInteger e = parameters.PublicExponent;
+
+ // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
+ // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
+
+ BigInteger p = ChooseRandomPrime(pBitlength, e);
+ BigInteger q, n;
//
- // calculate the modulus
+ // generate a modulus of the required length
//
- n = p.Multiply(q);
-
- if (n.BitLength != strength)
+ for (;;)
{
+ q = ChooseRandomPrime(qBitlength, e);
+
+ // p and q should not be too close together (or equal!)
+ BigInteger diff = q.Subtract(p).Abs();
+ if (diff.BitLength < mindiffbits)
+ continue;
+
//
- // if we get here our primes aren't big enough, make the largest
- // of the two p and try again
+ // calculate the modulus
//
- p = p.Max(q);
- continue;
+ n = p.Multiply(q);
+
+ if (n.BitLength != strength)
+ {
+ //
+ // if we get here our primes aren't big enough, make the largest
+ // of the two p and try again
+ //
+ p = p.Max(q);
+ continue;
+ }
+
+ /*
+ * Require a minimum weight of the NAF representation, since low-weight composites may
+ * be weak against a version of the number-field-sieve for factoring.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
+ if (WNafUtilities.GetNafWeight(n) < minWeight)
+ {
+ p = ChooseRandomPrime(pBitlength, e);
+ continue;
+ }
+
+ break;
}
- /*
- * Require a minimum weight of the NAF representation, since low-weight composites may
- * be weak against a version of the number-field-sieve for factoring.
- *
- * See "The number field sieve for integers of low weight", Oliver Schirokauer.
- */
- if (WNafUtilities.GetNafWeight(n) < minWeight)
+ if (p.CompareTo(q) < 0)
{
- p = ChooseRandomPrime(pBitlength, e);
- continue;
+ BigInteger tmp = p;
+ p = q;
+ q = tmp;
}
- break;
- }
-
- if (p.CompareTo(q) < 0)
- {
- phi = p;
- p = q;
- q = phi;
- }
-
- pSub1 = p.Subtract(BigInteger.One);
- qSub1 = q.Subtract(BigInteger.One);
- phi = pSub1.Multiply(qSub1);
+ BigInteger pSub1 = p.Subtract(One);
+ BigInteger qSub1 = q.Subtract(One);
+ //BigInteger phi = pSub1.Multiply(qSub1);
+ BigInteger gcd = pSub1.Gcd(qSub1);
+ BigInteger lcm = pSub1.Divide(gcd).Multiply(qSub1);
- //
- // calculate the private exponent
- //
- d = e.ModInverse(phi);
+ //
+ // calculate the private exponent
+ //
+ BigInteger d = e.ModInverse(lcm);
- //
- // calculate the CRT factors
- //
- BigInteger dP, dQ, qInv;
+ if (d.BitLength <= qBitlength)
+ continue;
- dP = d.Remainder(pSub1);
- dQ = d.Remainder(qSub1);
- qInv = q.ModInverse(p);
+ //
+ // calculate the CRT factors
+ //
+ BigInteger dP = d.Remainder(pSub1);
+ BigInteger dQ = d.Remainder(qSub1);
+ BigInteger qInv = q.ModInverse(p);
- return new AsymmetricCipherKeyPair(
- new RsaKeyParameters(false, n, e),
- new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ return new AsymmetricCipherKeyPair(
+ new RsaKeyParameters(false, n, e),
+ new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ }
}
/// <summary>Choose a random prime value for use with RSA</summary>
@@ -130,17 +141,19 @@ namespace Org.BouncyCastle.Crypto.Generators
/// <returns>a prime p, with (p-1) relatively prime to e</returns>
protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e)
{
+ bool eIsKnownOddPrime = (e.BitLength <= SPECIAL_E_BITS) && Arrays.Contains(SPECIAL_E_VALUES, e.IntValue);
+
for (;;)
{
- BigInteger p = new BigInteger(bitlength, 1, param.Random);
+ BigInteger p = new BigInteger(bitlength, 1, parameters.Random);
- if (p.Mod(e).Equals(BigInteger.One))
+ if (p.Mod(e).Equals(One))
continue;
- if (!p.IsProbablePrime(param.Certainty))
+ if (!p.IsProbablePrime(parameters.Certainty))
continue;
- if (!e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One))
+ if (!eIsKnownOddPrime && !e.Gcd(p.Subtract(One)).Equals(One))
continue;
return p;
diff --git a/crypto/src/crypto/modes/CcmBlockCipher.cs b/crypto/src/crypto/modes/CcmBlockCipher.cs
index 653d75cb9..e0b1e6b54 100644
--- a/crypto/src/crypto/modes/CcmBlockCipher.cs
+++ b/crypto/src/crypto/modes/CcmBlockCipher.cs
@@ -61,6 +61,7 @@ namespace Org.BouncyCastle.Crypto.Modes
{
this.forEncryption = forEncryption;
+ ICipherParameters cipherParameters;
if (parameters is AeadParameters)
{
AeadParameters param = (AeadParameters) parameters;
@@ -68,7 +69,7 @@ namespace Org.BouncyCastle.Crypto.Modes
nonce = param.GetNonce();
initialAssociatedText = param.GetAssociatedText();
macSize = param.MacSize / 8;
- keyParam = param.Key;
+ cipherParameters = param.Key;
}
else if (parameters is ParametersWithIV)
{
@@ -77,17 +78,25 @@ namespace Org.BouncyCastle.Crypto.Modes
nonce = param.GetIV();
initialAssociatedText = null;
macSize = macBlock.Length / 2;
- keyParam = param.Parameters;
+ cipherParameters = param.Parameters;
}
else
{
throw new ArgumentException("invalid parameters passed to CCM");
}
+ // NOTE: Very basic support for key re-use, but no performance gain from it
+ if (cipherParameters != null)
+ {
+ keyParam = cipherParameters;
+ }
+
if (nonce == null || nonce.Length < 7 || nonce.Length > 13)
{
throw new ArgumentException("nonce must have length from 7 to 13 octets");
}
+
+ Reset();
}
public virtual string AlgorithmName
@@ -128,6 +137,8 @@ namespace Org.BouncyCastle.Crypto.Modes
byte[] outBytes,
int outOff)
{
+ Check.DataLength(inBytes, inOff, inLen, "Input buffer too short");
+
data.Write(inBytes, inOff, inLen);
return 0;
@@ -137,13 +148,11 @@ namespace Org.BouncyCastle.Crypto.Modes
byte[] outBytes,
int outOff)
{
- byte[] enc = ProcessPacket(data.GetBuffer(), 0, (int)data.Position);
-
- Array.Copy(enc, 0, outBytes, outOff, enc.Length);
+ int len = ProcessPacket(data.GetBuffer(), 0, (int)data.Position, outBytes, outOff);
Reset();
- return enc.Length;
+ return len;
}
public virtual void Reset()
@@ -161,11 +170,7 @@ namespace Org.BouncyCastle.Crypto.Modes
*/
public virtual byte[] GetMac()
{
- byte[] mac = new byte[macSize];
-
- Array.Copy(macBlock, 0, mac, 0, mac.Length);
-
- return mac;
+ return Arrays.CopyOfRange(macBlock, 0, macSize);
}
public virtual int GetUpdateOutputSize(
@@ -174,7 +179,7 @@ namespace Org.BouncyCastle.Crypto.Modes
return 0;
}
- public int GetOutputSize(
+ public virtual int GetOutputSize(
int len)
{
int totalData = (int)data.Length + len;
@@ -187,10 +192,51 @@ namespace Org.BouncyCastle.Crypto.Modes
return totalData < macSize ? 0 : totalData - macSize;
}
- public byte[] ProcessPacket(
- byte[] input,
- int inOff,
- int inLen)
+ /**
+ * Process a packet of data for either CCM decryption or encryption.
+ *
+ * @param in data for processing.
+ * @param inOff offset at which data starts in the input array.
+ * @param inLen length of the data in the input array.
+ * @return a byte array containing the processed input..
+ * @throws IllegalStateException if the cipher is not appropriately set up.
+ * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
+ */
+ public virtual byte[] ProcessPacket(byte[] input, int inOff, int inLen)
+ {
+ byte[] output;
+
+ if (forEncryption)
+ {
+ output = new byte[inLen + macSize];
+ }
+ else
+ {
+ if (inLen < macSize)
+ throw new InvalidCipherTextException("data too short");
+
+ output = new byte[inLen - macSize];
+ }
+
+ ProcessPacket(input, inOff, inLen, output, 0);
+
+ return output;
+ }
+
+ /**
+ * Process a packet of data for either CCM decryption or encryption.
+ *
+ * @param in data for processing.
+ * @param inOff offset at which data starts in the input array.
+ * @param inLen length of the data in the input array.
+ * @param output output array.
+ * @param outOff offset into output array to start putting processed bytes.
+ * @return the number of bytes added to output.
+ * @throws IllegalStateException if the cipher is not appropriately set up.
+ * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
+ * @throws DataLengthException if output buffer too short.
+ */
+ public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
{
// TODO: handle null keyParam (e.g. via RepeatedKeySpec)
// Need to keep the CTR and CBC Mac parts around and reset
@@ -213,42 +259,45 @@ namespace Org.BouncyCastle.Crypto.Modes
IBlockCipher ctrCipher = new SicBlockCipher(cipher);
ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv));
- int index = inOff;
- int outOff = 0;
- byte[] output;
+ int outputLen;
+ int inIndex = inOff;
+ int outIndex = outOff;
if (forEncryption)
{
- output = new byte[inLen + macSize];
+ outputLen = inLen + macSize;
+ Check.OutputLength(output, outOff, outputLen, "Output buffer too short.");
calculateMac(input, inOff, inLen, macBlock);
ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); // S0
- while (index < inLen - BlockSize) // S1...
+ while (inIndex < (inOff + inLen - BlockSize)) // S1...
{
- ctrCipher.ProcessBlock(input, index, output, outOff);
- outOff += BlockSize;
- index += BlockSize;
+ ctrCipher.ProcessBlock(input, inIndex, output, outIndex);
+ outIndex += BlockSize;
+ inIndex += BlockSize;
}
byte[] block = new byte[BlockSize];
- Array.Copy(input, index, block, 0, inLen - index);
+ Array.Copy(input, inIndex, block, 0, inLen + inOff - inIndex);
ctrCipher.ProcessBlock(block, 0, block, 0);
- Array.Copy(block, 0, output, outOff, inLen - index);
+ Array.Copy(block, 0, output, outIndex, inLen + inOff - inIndex);
- outOff += inLen - index;
-
- Array.Copy(macBlock, 0, output, outOff, output.Length - outOff);
+ Array.Copy(macBlock, 0, output, outOff + inLen, macSize);
}
else
{
- output = new byte[inLen - macSize];
+ if (inLen < macSize)
+ throw new InvalidCipherTextException("data too short");
- Array.Copy(input, inOff + inLen - macSize, macBlock, 0, macSize);
+ outputLen = inLen - macSize;
+ Check.OutputLength(output, outOff, outputLen, "Output buffer too short.");
+
+ Array.Copy(input, inOff + outputLen, macBlock, 0, macSize);
ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);
@@ -257,30 +306,30 @@ namespace Org.BouncyCastle.Crypto.Modes
macBlock[i] = 0;
}
- while (outOff < output.Length - BlockSize)
+ while (inIndex < (inOff + outputLen - BlockSize))
{
- ctrCipher.ProcessBlock(input, index, output, outOff);
- outOff += BlockSize;
- index += BlockSize;
+ ctrCipher.ProcessBlock(input, inIndex, output, outIndex);
+ outIndex += BlockSize;
+ inIndex += BlockSize;
}
byte[] block = new byte[BlockSize];
- Array.Copy(input, index, block, 0, output.Length - outOff);
+ Array.Copy(input, inIndex, block, 0, outputLen - (inIndex - inOff));
ctrCipher.ProcessBlock(block, 0, block, 0);
- Array.Copy(block, 0, output, outOff, output.Length - outOff);
+ Array.Copy(block, 0, output, outIndex, outputLen - (inIndex - inOff));
byte[] calculatedMacBlock = new byte[BlockSize];
- calculateMac(output, 0, output.Length, calculatedMacBlock);
+ calculateMac(output, outOff, outputLen, calculatedMacBlock);
if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
throw new InvalidCipherTextException("mac check in CCM failed");
}
- return output;
+ return outputLen;
}
private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock)
diff --git a/crypto/src/crypto/modes/CtsBlockCipher.cs b/crypto/src/crypto/modes/CtsBlockCipher.cs
index a32b49675..ff37844ab 100644
--- a/crypto/src/crypto/modes/CtsBlockCipher.cs
+++ b/crypto/src/crypto/modes/CtsBlockCipher.cs
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Modes
}
/**
- * process a single byte, producing an output block if neccessary.
+ * process a single byte, producing an output block if necessary.
*
* @param in the input byte.
* @param out the space for any output that might be produced.
diff --git a/crypto/src/crypto/modes/EAXBlockCipher.cs b/crypto/src/crypto/modes/EAXBlockCipher.cs
index 5ccc69b66..624f385b5 100644
--- a/crypto/src/crypto/modes/EAXBlockCipher.cs
+++ b/crypto/src/crypto/modes/EAXBlockCipher.cs
@@ -54,7 +54,6 @@ namespace Org.BouncyCastle.Crypto.Modes
blockSize = cipher.GetBlockSize();
mac = new CMac(cipher);
macBlock = new byte[blockSize];
- bufBlock = new byte[blockSize * 2];
associatedTextMac = new byte[mac.GetMacSize()];
nonceMac = new byte[mac.GetMacSize()];
this.cipher = new SicBlockCipher(cipher);
@@ -65,7 +64,7 @@ namespace Org.BouncyCastle.Crypto.Modes
get { return cipher.GetUnderlyingCipher().AlgorithmName + "/EAX"; }
}
- public IBlockCipher GetUnderlyingCipher()
+ public virtual IBlockCipher GetUnderlyingCipher()
{
return cipher;
}
@@ -107,6 +106,8 @@ namespace Org.BouncyCastle.Crypto.Modes
throw new ArgumentException("invalid parameters passed to EAX");
}
+ bufBlock = new byte[forEncryption ? blockSize : (blockSize + macSize)];
+
byte[] tag = new byte[blockSize];
// Key reuse implemented in CBC mode of underlying CMac
@@ -117,16 +118,10 @@ namespace Org.BouncyCastle.Crypto.Modes
mac.BlockUpdate(nonce, 0, nonce.Length);
mac.DoFinal(nonceMac, 0);
- tag[blockSize - 1] = (byte)Tag.H;
- mac.BlockUpdate(tag, 0, blockSize);
-
- if (initialAssociatedText != null)
- {
- ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length);
- }
-
- // Same BlockCipher underlies this and the mac, so reuse last key on cipher
+ // Same BlockCipher underlies this and the mac, so reuse last key on cipher
cipher.Init(true, new ParametersWithIV(null, nonceMac));
+
+ Reset();
}
private void InitCipher()
@@ -191,16 +186,16 @@ namespace Org.BouncyCastle.Crypto.Modes
{
if (cipherInitialized)
{
- throw new InvalidOperationException("AAD data cannot be added after encryption/decription processing has begun.");
+ throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun.");
}
mac.Update(input);
}
- public void ProcessAadBytes(byte[] inBytes, int inOff, int len)
+ public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len)
{
if (cipherInitialized)
{
- throw new InvalidOperationException("AAD data cannot be added after encryption/decription processing has begun.");
+ throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun.");
}
mac.BlockUpdate(inBytes, inOff, len);
}
@@ -247,10 +242,11 @@ namespace Org.BouncyCastle.Crypto.Modes
if (forEncryption)
{
- cipher.ProcessBlock(bufBlock, 0, tmp, 0);
- cipher.ProcessBlock(bufBlock, blockSize, tmp, blockSize);
+ Check.OutputLength(outBytes, outOff, extra + macSize, "Output buffer too short");
+
+ cipher.ProcessBlock(bufBlock, 0, tmp, 0);
- Array.Copy(tmp, 0, outBytes, outOff, extra);
+ Array.Copy(tmp, 0, outBytes, outOff, extra);
mac.BlockUpdate(tmp, 0, extra);
@@ -264,14 +260,18 @@ namespace Org.BouncyCastle.Crypto.Modes
}
else
{
- if (extra > macSize)
+ if (extra < macSize)
+ throw new InvalidCipherTextException("data too short");
+
+ Check.OutputLength(outBytes, outOff, extra - macSize, "Output buffer too short");
+
+ if (extra > macSize)
{
mac.BlockUpdate(bufBlock, 0, extra - macSize);
cipher.ProcessBlock(bufBlock, 0, tmp, 0);
- cipher.ProcessBlock(bufBlock, blockSize, tmp, blockSize);
- Array.Copy(tmp, 0, outBytes, outOff, extra - macSize);
+ Array.Copy(tmp, 0, outBytes, outOff, extra - macSize);
}
CalculateMac();
@@ -331,6 +331,11 @@ namespace Org.BouncyCastle.Crypto.Modes
if (bufOff == bufBlock.Length)
{
+ Check.OutputLength(outBytes, outOff, blockSize, "Output buffer is too short");
+
+ // TODO Could move the ProcessByte(s) calls to here
+// InitCipher();
+
int size;
if (forEncryption)
@@ -346,10 +351,14 @@ namespace Org.BouncyCastle.Crypto.Modes
size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff);
}
- bufOff = blockSize;
- Array.Copy(bufBlock, blockSize, bufBlock, 0, blockSize);
+ bufOff = 0;
+ if (!forEncryption)
+ {
+ Array.Copy(bufBlock, blockSize, bufBlock, 0, macSize);
+ bufOff = macSize;
+ }
- return size;
+ return size;
}
return 0;
diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs
index 2e2ac2eca..8e6120eef 100644
--- a/crypto/src/crypto/modes/GCMBlockCipher.cs
+++ b/crypto/src/crypto/modes/GCMBlockCipher.cs
@@ -284,6 +284,9 @@ namespace Org.BouncyCastle.Crypto.Modes
byte[] output,
int outOff)
{
+ if (input.Length < (inOff + len))
+ throw new DataLengthException("Input buffer too short");
+
int resultLen = 0;
for (int i = 0; i < len; ++i)
@@ -301,6 +304,7 @@ namespace Org.BouncyCastle.Crypto.Modes
private void OutputBlock(byte[] output, int offset)
{
+ Check.OutputLength(output, offset, BlockSize, "Output buffer too short");
if (totalLength == 0)
{
InitCipher();
@@ -325,12 +329,19 @@ namespace Org.BouncyCastle.Crypto.Modes
}
int extra = bufOff;
- if (!forEncryption)
+
+ if (forEncryption)
+ {
+ Check.OutputLength(output, outOff, extra + macSize, "Output buffer too short");
+ }
+ else
{
if (extra < macSize)
throw new InvalidCipherTextException("data too short");
extra -= macSize;
+
+ Check.OutputLength(output, outOff, extra, "Output buffer too short");
}
if (extra > 0)
diff --git a/crypto/src/crypto/modes/OCBBlockCipher.cs b/crypto/src/crypto/modes/OCBBlockCipher.cs
index 54359dfe8..e7dc466e6 100644
--- a/crypto/src/crypto/modes/OCBBlockCipher.cs
+++ b/crypto/src/crypto/modes/OCBBlockCipher.cs
@@ -355,6 +355,7 @@ namespace Org.BouncyCastle.Crypto.Modes
Xor(mainBlock, Pad);
+ Check.OutputLength(output, outOff, mainBlockPos, "Output buffer too short");
Array.Copy(mainBlock, 0, output, outOff, mainBlockPos);
if (!forEncryption)
@@ -382,6 +383,8 @@ namespace Org.BouncyCastle.Crypto.Modes
if (forEncryption)
{
+ Check.OutputLength(output, outOff, resultLen + macSize, "Output buffer too short");
+
// Append tag to the message
Array.Copy(macBlock, 0, output, outOff + resultLen, macSize);
resultLen += macSize;
@@ -431,6 +434,8 @@ namespace Org.BouncyCastle.Crypto.Modes
protected virtual void ProcessMainBlock(byte[] output, int outOff)
{
+ Check.DataLength(output, outOff, BLOCK_SIZE, "Output buffer too short");
+
/*
* OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks
*/
diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs
index 0f241035f..de41d88f4 100644
--- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs
+++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs
@@ -106,6 +106,29 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm
x[3] = r13;
}
+ internal static void Multiply(ulong[] x, ulong[] y)
+ {
+ ulong r00 = x[0], r01 = x[1], r10 = 0, r11 = 0;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ long bits = (long)y[i];
+ for (int j = 0; j < 64; ++j)
+ {
+ ulong m1 = (ulong)(bits >> 63); bits <<= 1;
+ r10 ^= (r00 & m1);
+ r11 ^= (r01 & m1);
+
+ ulong m2 = (r01 << 63) >> 8;
+ r01 = (r01 >> 1) | (r00 << 63);
+ r00 = (r00 >> 1) ^ (m2 & E1L);
+ }
+ }
+
+ x[0] = r10;
+ x[1] = r11;
+ }
+
// P is the value with only bit i=1 set
internal static void MultiplyP(uint[] x)
{
diff --git a/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs b/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs
index fb8a92ba3..5d2f8cf15 100644
--- a/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs
+++ b/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs
@@ -122,7 +122,7 @@ namespace Org.BouncyCastle.Crypto.Paddings
}
/**
- * process a single byte, producing an output block if neccessary.
+ * process a single byte, producing an output block if necessary.
*
* @param in the input byte.
* @param out the space for any output that might be produced.
@@ -178,10 +178,7 @@ namespace Org.BouncyCastle.Crypto.Paddings
if (outLength > 0)
{
- if ((outOff + outLength) > output.Length)
- {
- throw new DataLengthException("output buffer too short");
- }
+ Check.OutputLength(output, outOff, outLength, "output buffer too short");
}
int resultLen = 0;
@@ -242,7 +239,7 @@ namespace Org.BouncyCastle.Crypto.Paddings
{
Reset();
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
resultLen = cipher.ProcessBlock(buf, 0, output, outOff);
diff --git a/crypto/src/crypto/parameters/Srp6GroupParameters.cs b/crypto/src/crypto/parameters/Srp6GroupParameters.cs
new file mode 100644
index 000000000..6762dd31d
--- /dev/null
+++ b/crypto/src/crypto/parameters/Srp6GroupParameters.cs
@@ -0,0 +1,27 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Parameters
+{
+ public sealed class Srp6GroupParameters
+ {
+ private readonly BigInteger n, g;
+
+ public Srp6GroupParameters(BigInteger N, BigInteger g)
+ {
+ this.n = N;
+ this.g = g;
+ }
+
+ public BigInteger G
+ {
+ get { return g; }
+ }
+
+ public BigInteger N
+ {
+ get { return n; }
+ }
+ }
+}
diff --git a/crypto/src/crypto/signers/DsaDigestSigner.cs b/crypto/src/crypto/signers/DsaDigestSigner.cs
index aee713450..086601481 100644
--- a/crypto/src/crypto/signers/DsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/DsaDigestSigner.cs
@@ -26,12 +26,12 @@ namespace Org.BouncyCastle.Crypto.Signers
this.dsaSigner = signer;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("DSADigestSigner not initialised for signature generation.");
@@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary>Reset the internal state</summary>
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs
index 6027aa9b9..28ab79c1c 100644
--- a/crypto/src/crypto/signers/ECGOST3410Signer.cs
+++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs
@@ -18,12 +18,12 @@ namespace Org.BouncyCastle.Crypto.Signers
private ECKeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "ECGOST3410"; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
*
* @param message the message that will be verified later.
*/
- public BigInteger[] GenerateSignature(
+ public virtual BigInteger[] GenerateSignature(
byte[] message)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
@@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* the passed in message (for standard GOST3410 the message should be
* a GOST3411 hash of the real message to be verified).
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs
index cae15bdbf..bb21a4994 100644
--- a/crypto/src/crypto/signers/ECNRSigner.cs
+++ b/crypto/src/crypto/signers/ECNRSigner.cs
@@ -19,12 +19,12 @@ namespace Org.BouncyCastle.Crypto.Signers
private ECKeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "ECNR"; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param digest the digest to be signed.
* @exception DataLengthException if the digest is longer than the key allows
*/
- public BigInteger[] GenerateSignature(
+ public virtual BigInteger[] GenerateSignature(
byte[] message)
{
if (!this.forSigning)
@@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param s the s value of the signature.
* @exception DataLengthException if the digest is longer than the key allows
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
diff --git a/crypto/src/crypto/signers/GOST3410DigestSigner.cs b/crypto/src/crypto/signers/GOST3410DigestSigner.cs
index 58aefa368..bc32808df 100644
--- a/crypto/src/crypto/signers/GOST3410DigestSigner.cs
+++ b/crypto/src/crypto/signers/GOST3410DigestSigner.cs
@@ -26,12 +26,12 @@ namespace Org.BouncyCastle.Crypto.Signers
this.digest = digest;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
@@ -86,7 +86,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation.");
@@ -113,7 +113,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
@@ -137,7 +137,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary>Reset the internal state</summary>
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/GOST3410Signer.cs b/crypto/src/crypto/signers/GOST3410Signer.cs
index 375eeb5cc..f1832ae37 100644
--- a/crypto/src/crypto/signers/GOST3410Signer.cs
+++ b/crypto/src/crypto/signers/GOST3410Signer.cs
@@ -15,12 +15,12 @@ namespace Org.BouncyCastle.Crypto.Signers
private Gost3410KeyParameters key;
private SecureRandom random;
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "GOST3410"; }
}
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Signers
*
* @param message the message that will be verified later.
*/
- public BigInteger[] GenerateSignature(
+ public virtual BigInteger[] GenerateSignature(
byte[] message)
{
byte[] mRev = new byte[message.Length]; // conversion is little-endian
@@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* the passed in message for standard Gost3410 the message should be a
* Gost3411 hash of the real message to be verified.
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] message,
BigInteger r,
BigInteger s)
diff --git a/crypto/src/crypto/signers/GenericSigner.cs b/crypto/src/crypto/signers/GenericSigner.cs
index 5035b454d..a5512176f 100644
--- a/crypto/src/crypto/signers/GenericSigner.cs
+++ b/crypto/src/crypto/signers/GenericSigner.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Signers
this.digest = digest;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; }
}
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param parameters
* necessary parameters.
*/
- public void Init(bool forSigning, ICipherParameters parameters)
+ public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(byte input)
+ public virtual void Update(byte input)
{
digest.Update(input);
}
@@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(byte[] input, int inOff, int length)
+ public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
digest.BlockUpdate(input, inOff, length);
}
@@ -79,7 +79,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using the key
* we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("GenericSigner not initialised for signature generation.");
@@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* return true if the internal state represents the signature described in
* the passed in array.
*/
- public bool VerifySignature(byte[] signature)
+ public virtual bool VerifySignature(byte[] signature)
{
if (forSigning)
throw new InvalidOperationException("GenericSigner not initialised for verification");
@@ -122,7 +122,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
index d4f6c5522..1486656bd 100644
--- a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
+++ b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
@@ -120,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Signers
{
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + "ISO9796-2S2"; }
}
@@ -365,7 +365,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/// <summary> Generate a signature for the loaded message using the key we were
/// initialised with.
/// </summary>
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
int digSize = digest.GetDigestSize();
byte[] m2Hash = new byte[digSize];
diff --git a/crypto/src/crypto/signers/Iso9796d2Signer.cs b/crypto/src/crypto/signers/Iso9796d2Signer.cs
index cfb8942e6..4bb4d17a6 100644
--- a/crypto/src/crypto/signers/Iso9796d2Signer.cs
+++ b/crypto/src/crypto/signers/Iso9796d2Signer.cs
@@ -105,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Signers
{
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + "ISO9796-2S1"; }
}
@@ -252,7 +252,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary> update the internal digest with the byte b</summary>
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -266,7 +266,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
/// <summary> update the internal digest with the byte array in</summary>
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs
index 6900224f3..03890902b 100644
--- a/crypto/src/crypto/signers/PssSigner.cs
+++ b/crypto/src/crypto/signers/PssSigner.cs
@@ -115,7 +115,7 @@ namespace Org.BouncyCastle.Crypto.Signers
this.trailer = trailer;
}
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; }
}
diff --git a/crypto/src/crypto/signers/RsaDigestSigner.cs b/crypto/src/crypto/signers/RsaDigestSigner.cs
index 9af4e7145..d9b19cf6b 100644
--- a/crypto/src/crypto/signers/RsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/RsaDigestSigner.cs
@@ -64,8 +64,7 @@ namespace Org.BouncyCastle.Crypto.Signers
this.algId = algId;
}
- [Obsolete]
- public string AlgorithmName
+ public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "withRSA"; }
}
@@ -76,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* @param forSigning true if for signing, false otherwise
* @param param necessary parameters.
*/
- public void Init(
+ public virtual void Init(
bool forSigning,
ICipherParameters parameters)
{
@@ -106,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte b
*/
- public void Update(
+ public virtual void Update(
byte input)
{
digest.Update(input);
@@ -115,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Signers
/**
* update the internal digest with the byte array in
*/
- public void BlockUpdate(
+ public virtual void BlockUpdate(
byte[] input,
int inOff,
int length)
@@ -127,7 +126,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
- public byte[] GenerateSignature()
+ public virtual byte[] GenerateSignature()
{
if (!forSigning)
throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation.");
@@ -143,7 +142,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* return true if the internal state represents the signature described
* in the passed in array.
*/
- public bool VerifySignature(
+ public virtual bool VerifySignature(
byte[] signature)
{
if (forSigning)
@@ -197,7 +196,7 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
- public void Reset()
+ public virtual void Reset()
{
digest.Reset();
}
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
new file mode 100644
index 000000000..89f512b78
--- /dev/null
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -0,0 +1,234 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Signers
+{
+ /**
+ * X9.31-1998 - signing using a hash.
+ * <p>
+ * The message digest hash, H, is encapsulated to form a byte string as follows
+ * </p>
+ * <pre>
+ * EB = 06 || PS || 0xBA || H || TRAILER
+ * </pre>
+ * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number†for the digest. The byte string, EB, is converted to an integer value, the message representative, f.
+ */
+ public class X931Signer
+ : ISigner
+ {
+ public const int TRAILER_IMPLICIT = 0xBC;
+ public const int TRAILER_RIPEMD160 = 0x31CC;
+ public const int TRAILER_RIPEMD128 = 0x32CC;
+ public const int TRAILER_SHA1 = 0x33CC;
+ public const int TRAILER_SHA256 = 0x34CC;
+ public const int TRAILER_SHA512 = 0x35CC;
+ public const int TRAILER_SHA384 = 0x36CC;
+ public const int TRAILER_WHIRLPOOL = 0x37CC;
+ public const int TRAILER_SHA224 = 0x38CC;
+
+ private static readonly IDictionary trailerMap = Platform.CreateHashtable();
+
+ static X931Signer()
+ {
+ trailerMap.Add("RIPEMD128", TRAILER_RIPEMD128);
+ trailerMap.Add("RIPEMD160", TRAILER_RIPEMD160);
+
+ trailerMap.Add("SHA-1", TRAILER_SHA1);
+ trailerMap.Add("SHA-224", TRAILER_SHA224);
+ trailerMap.Add("SHA-256", TRAILER_SHA256);
+ trailerMap.Add("SHA-384", TRAILER_SHA384);
+ trailerMap.Add("SHA-512", TRAILER_SHA512);
+
+ trailerMap.Add("Whirlpool", TRAILER_WHIRLPOOL);
+ }
+
+ private IDigest digest;
+ private IAsymmetricBlockCipher cipher;
+ private RsaKeyParameters kParam;
+
+ private int trailer;
+ private int keyBits;
+ private byte[] block;
+
+ /**
+ * Generate a signer for the with either implicit or explicit trailers
+ * for ISO9796-2.
+ *
+ * @param cipher base cipher to use for signature creation/verification
+ * @param digest digest to use.
+ * @param implicit whether or not the trailer is implicit or gives the hash.
+ */
+ public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
+ {
+ this.cipher = cipher;
+ this.digest = digest;
+
+ if (isImplicit)
+ {
+ trailer = TRAILER_IMPLICIT;
+ }
+ else
+ {
+ string name = digest.AlgorithmName;
+ if (!trailerMap.Contains(name))
+ throw new ArgumentException("no valid trailer", "digest");
+
+ trailer = (int)trailerMap[name];
+ }
+ }
+
+ public virtual string AlgorithmName
+ {
+ get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; }
+ }
+
+ /**
+ * Constructor for a signer with an explicit digest trailer.
+ *
+ * @param cipher cipher to use.
+ * @param digest digest to sign with.
+ */
+ public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
+ : this(cipher, digest, false)
+ {
+ }
+
+ public virtual void Init(bool forSigning, ICipherParameters parameters)
+ {
+ kParam = (RsaKeyParameters)parameters;
+
+ cipher.Init(forSigning, kParam);
+
+ keyBits = kParam.Modulus.BitLength;
+
+ block = new byte[(keyBits + 7) / 8];
+
+ Reset();
+ }
+
+ /// <summary> clear possible sensitive data</summary>
+ private void ClearBlock(byte[] block)
+ {
+ Array.Clear(block, 0, block.Length);
+ }
+
+ /**
+ * update the internal digest with the byte b
+ */
+ public virtual void Update(byte b)
+ {
+ digest.Update(b);
+ }
+
+ /**
+ * update the internal digest with the byte array in
+ */
+ public virtual void BlockUpdate(byte[] input, int off, int len)
+ {
+ digest.BlockUpdate(input, off, len);
+ }
+
+ /**
+ * reset the internal state
+ */
+ public virtual void Reset()
+ {
+ digest.Reset();
+ }
+
+ /**
+ * generate a signature for the loaded message using the key we were
+ * initialised with.
+ */
+ public virtual byte[] GenerateSignature()
+ {
+ CreateSignatureBlock();
+
+ BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
+ ClearBlock(block);
+
+ t = t.Min(kParam.Modulus.Subtract(t));
+
+ return BigIntegers.AsUnsignedByteArray((kParam.Modulus.BitLength + 7) / 8, t);
+ }
+
+ private void CreateSignatureBlock()
+ {
+ int digSize = digest.GetDigestSize();
+
+ int delta;
+
+ if (trailer == TRAILER_IMPLICIT)
+ {
+ delta = block.Length - digSize - 1;
+ digest.DoFinal(block, delta);
+ block[block.Length - 1] = (byte)TRAILER_IMPLICIT;
+ }
+ else
+ {
+ delta = block.Length - digSize - 2;
+ digest.DoFinal(block, delta);
+ block[block.Length - 2] = (byte)(trailer >> 8);
+ block[block.Length - 1] = (byte)trailer;
+ }
+
+ block[0] = 0x6b;
+ for (int i = delta - 2; i != 0; i--)
+ {
+ block[i] = (byte)0xbb;
+ }
+ block[delta - 1] = (byte)0xba;
+ }
+
+ /**
+ * return true if the signature represents a ISO9796-2 signature
+ * for the passed in message.
+ */
+ public virtual bool VerifySignature(byte[] signature)
+ {
+ try
+ {
+ block = cipher.ProcessBlock(signature, 0, signature.Length);
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+
+ BigInteger t = new BigInteger(block);
+ BigInteger f;
+
+ if ((t.IntValue & 15) == 12)
+ {
+ f = t;
+ }
+ else
+ {
+ t = kParam.Modulus.Subtract(t);
+ if ((t.IntValue & 15) == 12)
+ {
+ f = t;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ CreateSignatureBlock();
+
+ byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
+
+ bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
+
+ ClearBlock(block);
+ ClearBlock(fBlock);
+
+ return rv;
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/AbstractTlsClient.cs b/crypto/src/crypto/tls/AbstractTlsClient.cs
index 771bc004b..046feb78c 100644
--- a/crypto/src/crypto/tls/AbstractTlsClient.cs
+++ b/crypto/src/crypto/tls/AbstractTlsClient.cs
@@ -117,27 +117,7 @@ namespace Org.BouncyCastle.Crypto.Tls
{
// TODO Provide a way for the user to specify the acceptable hash/signature algorithms.
- byte[] hashAlgorithms = new byte[]{ HashAlgorithm.sha512, HashAlgorithm.sha384, HashAlgorithm.sha256,
- HashAlgorithm.sha224, HashAlgorithm.sha1 };
-
- // TODO Sort out ECDSA signatures and add them as the preferred option here
- byte[] signatureAlgorithms = new byte[]{ SignatureAlgorithm.rsa };
-
- this.mSupportedSignatureAlgorithms = Platform.CreateArrayList();
- for (int i = 0; i < hashAlgorithms.Length; ++i)
- {
- for (int j = 0; j < signatureAlgorithms.Length; ++j)
- {
- this.mSupportedSignatureAlgorithms.Add(new SignatureAndHashAlgorithm(hashAlgorithms[i],
- signatureAlgorithms[j]));
- }
- }
-
- /*
- * RFC 5264 7.4.3. Currently, DSA [DSS] may only be used with SHA-1.
- */
- this.mSupportedSignatureAlgorithms.Add(new SignatureAndHashAlgorithm(HashAlgorithm.sha1,
- SignatureAlgorithm.dsa));
+ this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultSupportedSignatureAlgorithms();
clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(clientExtensions);
@@ -263,6 +243,14 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
+ public override TlsCipher GetCipher()
+ {
+ int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite);
+ int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite);
+
+ return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm);
+ }
+
public virtual void NotifyNewSessionTicket(NewSessionTicket newSessionTicket)
{
}
diff --git a/crypto/src/crypto/tls/AbstractTlsContext.cs b/crypto/src/crypto/tls/AbstractTlsContext.cs
index 83150d37e..e283ee58c 100644
--- a/crypto/src/crypto/tls/AbstractTlsContext.cs
+++ b/crypto/src/crypto/tls/AbstractTlsContext.cs
@@ -96,6 +96,15 @@ namespace Org.BouncyCastle.Crypto.Tls
public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length)
{
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 5.4. If a client or server chooses to continue with a full
+ * handshake without the extended master secret extension, [..] the client or server MUST
+ * NOT export any key material based on the new master secret for any subsequent
+ * application-level authentication. In particular, it MUST disable [RFC5705] [..].
+ */
+
if (context_value != null && !TlsUtilities.IsValidUint16(context_value.Length))
throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value");
diff --git a/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs b/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs
index 155ac94d8..c9ec06107 100644
--- a/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs
+++ b/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Tls
protected readonly int mKeyExchange;
protected IList mSupportedSignatureAlgorithms;
- protected TlsContext context;
+ protected TlsContext mContext;
protected AbstractTlsKeyExchange(int keyExchange, IList supportedSignatureAlgorithms)
{
@@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public virtual void Init(TlsContext context)
{
- this.context = context;
+ this.mContext = context;
ProtocolVersion clientVersion = context.ClientVersion;
diff --git a/crypto/src/crypto/tls/AbstractTlsServer.cs b/crypto/src/crypto/tls/AbstractTlsServer.cs
index b0a5f0d52..7fe3fcbe5 100644
--- a/crypto/src/crypto/tls/AbstractTlsServer.cs
+++ b/crypto/src/crypto/tls/AbstractTlsServer.cs
@@ -320,6 +320,14 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
+ public override TlsCipher GetCipher()
+ {
+ int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite);
+ int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite);
+
+ return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm);
+ }
+
public virtual NewSessionTicket GetNewSessionTicket()
{
/*
diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs
index ec98413b7..ff7e6da85 100644
--- a/crypto/src/crypto/tls/DefaultTlsClient.cs
+++ b/crypto/src/crypto/tls/DefaultTlsClient.cs
@@ -28,9 +28,18 @@ namespace Org.BouncyCastle.Crypto.Tls
{
return new int[]
{
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
@@ -39,395 +48,28 @@ namespace Org.BouncyCastle.Crypto.Tls
public override TlsKeyExchange GetKeyExchange()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
- return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_DSS);
-
- case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
- return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_RSA);
-
- case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
- return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_DSS);
-
- case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
- return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_RSA);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- return CreateECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA);
-
- case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
- return CreateECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA);
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
- return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA);
-
- case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
- return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA);
-
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_NULL_MD5:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
- return CreateRsaKeyExchange();
-
- default:
- /*
- * Note: internal error here; the TlsProtocol implementation verifies that the
- * server-selected cipher suite was in the list of client-offered cipher suites, so if
- * we now can't produce an implementation, we shouldn't have offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
-
- public override TlsCipher GetCipher()
- {
- switch (mSelectedCipherSuite)
+ switch (keyExchangeAlgorithm)
{
- case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AEAD_CHACHA20_POLY1305, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
+ case KeyExchangeAlgorithm.DH_DSS:
+ case KeyExchangeAlgorithm.DH_RSA:
+ return CreateDHKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
+ case KeyExchangeAlgorithm.DHE_DSS:
+ case KeyExchangeAlgorithm.DHE_RSA:
+ return CreateDheKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
+ case KeyExchangeAlgorithm.ECDH_ECDSA:
+ case KeyExchangeAlgorithm.ECDH_RSA:
+ return CreateECDHKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
+ case KeyExchangeAlgorithm.ECDHE_ECDSA:
+ case KeyExchangeAlgorithm.ECDHE_RSA:
+ return CreateECDheKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.ESTREAM_SALSA20, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_RSA_WITH_NULL_MD5:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_md5);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_md5);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SALSA20, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SEED_CBC, MacAlgorithm.hmac_sha1);
+ case KeyExchangeAlgorithm.RSA:
+ return CreateRsaKeyExchange();
default:
/*
diff --git a/crypto/src/crypto/tls/DefaultTlsServer.cs b/crypto/src/crypto/tls/DefaultTlsServer.cs
index 75f6d8d88..b12c43e1c 100644
--- a/crypto/src/crypto/tls/DefaultTlsServer.cs
+++ b/crypto/src/crypto/tls/DefaultTlsServer.cs
@@ -20,6 +20,16 @@ namespace Org.BouncyCastle.Crypto.Tls
{
}
+ protected virtual TlsSignerCredentials GetDsaSignerCredentials()
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ protected virtual TlsSignerCredentials GetECDsaSignerCredentials()
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
protected virtual TlsEncryptionCredentials GetRsaEncryptionCredentials()
{
throw new TlsFatalAlert(AlertDescription.internal_error);
@@ -45,6 +55,12 @@ namespace Org.BouncyCastle.Crypto.Tls
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256,
@@ -56,472 +72,62 @@ namespace Org.BouncyCastle.Crypto.Tls
public override TlsCredentials GetCredentials()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_NULL_MD5:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
- return GetRsaEncryptionCredentials();
-
- case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
- return GetRsaSignerCredentials();
-
- default:
- /*
- * Note: internal error here; selected a key exchange we don't implement!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- public override TlsKeyExchange GetKeyExchange()
- {
- switch (mSelectedCipherSuite)
+ switch (keyExchangeAlgorithm)
{
- case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
- return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_DSS);
-
- case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
- return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_RSA);
-
- case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
- return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_DSS);
+ case KeyExchangeAlgorithm.DH_DSS:
+ case KeyExchangeAlgorithm.DHE_DSS:
+ return GetDsaSignerCredentials();
- case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
- return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_RSA);
+ case KeyExchangeAlgorithm.ECDH_ECDSA:
+ case KeyExchangeAlgorithm.ECDHE_ECDSA:
+ return GetECDsaSignerCredentials();
- case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- return CreateECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA);
+ case KeyExchangeAlgorithm.DHE_RSA:
+ case KeyExchangeAlgorithm.ECDHE_RSA:
+ return GetRsaSignerCredentials();
- case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
- return CreateECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA);
+ case KeyExchangeAlgorithm.RSA:
+ return GetRsaEncryptionCredentials();
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
- return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA);
-
- case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
- return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA);
-
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_NULL_MD5:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
- return createRSAKeyExchange();
-
- default:
- /*
- * Note: internal error here; selected a key exchange we don't implement!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
+ default:
+ /* Note: internal error here; selected a key exchange we don't implement! */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
- public override TlsCipher GetCipher()
+ public override TlsKeyExchange GetKeyExchange()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AEAD_CHACHA20_POLY1305, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.ESTREAM_SALSA20, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_RSA_WITH_NULL_MD5:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_md5);
-
- case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_WITH_NULL_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha256);
+ switch (keyExchangeAlgorithm)
+ {
+ case KeyExchangeAlgorithm.DH_DSS:
+ case KeyExchangeAlgorithm.DH_RSA:
+ return CreateDHKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_md5);
+ case KeyExchangeAlgorithm.DHE_DSS:
+ case KeyExchangeAlgorithm.DHE_RSA:
+ return CreateDheKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
+ case KeyExchangeAlgorithm.ECDH_ECDSA:
+ case KeyExchangeAlgorithm.ECDH_RSA:
+ return CreateECDHKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SALSA20, MacAlgorithm.hmac_sha1);
+ case KeyExchangeAlgorithm.ECDHE_ECDSA:
+ case KeyExchangeAlgorithm.ECDHE_RSA:
+ return CreateECDheKeyExchange(keyExchangeAlgorithm);
- case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SEED_CBC, MacAlgorithm.hmac_sha1);
+ case KeyExchangeAlgorithm.RSA:
+ return CreateRsaKeyExchange();
default:
/*
- * Note: internal error here; selected a cipher suite we don't implement!
- */
+ * Note: internal error here; the TlsProtocol implementation verifies that the
+ * server-selected cipher suite was in the list of client-offered cipher suites, so if
+ * we now can't produce an implementation, we shouldn't have offered it!
+ */
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
@@ -548,7 +154,7 @@ namespace Org.BouncyCastle.Crypto.Tls
mServerECPointFormats);
}
- protected virtual TlsKeyExchange createRSAKeyExchange()
+ protected virtual TlsKeyExchange CreateRsaKeyExchange()
{
return new TlsRsaKeyExchange(mSupportedSignatureAlgorithms);
}
diff --git a/crypto/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs b/crypto/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs
new file mode 100644
index 000000000..cc933bff9
--- /dev/null
+++ b/crypto/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Crypto.Agreement.Srp;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public class DefaultTlsSrpGroupVerifier
+ : TlsSrpGroupVerifier
+ {
+ protected static readonly IList DefaultGroups = Platform.CreateArrayList();
+
+ static DefaultTlsSrpGroupVerifier()
+ {
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_1024);
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_1536);
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_2048);
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_3072);
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_4096);
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_6144);
+ DefaultGroups.Add(Srp6StandardGroups.rfc5054_8192);
+ }
+
+ // Vector is (SRP6GroupParameters)
+ protected readonly IList mGroups;
+
+ /**
+ * Accept only the group parameters specified in RFC 5054 Appendix A.
+ */
+ public DefaultTlsSrpGroupVerifier()
+ : this(DefaultGroups)
+ {
+ }
+
+ /**
+ * Specify a custom set of acceptable group parameters.
+ *
+ * @param groups a {@link Vector} of acceptable {@link SRP6GroupParameters}
+ */
+ public DefaultTlsSrpGroupVerifier(IList groups)
+ {
+ this.mGroups = groups;
+ }
+
+ public virtual bool Accept(Srp6GroupParameters group)
+ {
+ foreach (Srp6GroupParameters entry in mGroups)
+ {
+ if (AreGroupsEqual(group, entry))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected virtual bool AreGroupsEqual(Srp6GroupParameters a, Srp6GroupParameters b)
+ {
+ return a == b || (AreParametersEqual(a.N, b.N) && AreParametersEqual(a.G, b.G));
+ }
+
+ protected virtual bool AreParametersEqual(BigInteger a, BigInteger b)
+ {
+ return a == b || a.Equals(b);
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/DtlsClientProtocol.cs b/crypto/src/crypto/tls/DtlsClientProtocol.cs
index 2aa4df692..76635065c 100644
--- a/crypto/src/crypto/tls/DtlsClientProtocol.cs
+++ b/crypto/src/crypto/tls/DtlsClientProtocol.cs
@@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Tls
DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake);
TlsSession sessionToResume = state.client.GetSessionToResume();
- if (sessionToResume != null)
+ if (sessionToResume != null && sessionToResume.IsResumable)
{
SessionParameters sessionParameters = sessionToResume.ExportSessionParameters();
if (sessionParameters != null)
@@ -143,6 +143,8 @@ namespace Org.BouncyCastle.Crypto.Tls
IDictionary sessionServerExtensions = state.sessionParameters.ReadServerExtensions();
+ // TODO Check encrypt-then-MAC extension and maybe others
+
securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);
securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret);
@@ -317,23 +319,17 @@ namespace Org.BouncyCastle.Crypto.Tls
/*
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
*/
- SignatureAndHashAlgorithm signatureAndHashAlgorithm;
- byte[] hash;
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ state.clientContext, signerCredentials);
- if (TlsUtilities.IsTlsV12(state.clientContext))
+ byte[] hash;
+ if (signatureAndHashAlgorithm == null)
{
- signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm;
- if (signatureAndHashAlgorithm == null)
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
-
- hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
+ hash = securityParameters.SessionHash;
}
else
{
- signatureAndHashAlgorithm = null;
- hash = securityParameters.SessionHash;
+ hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
}
byte[] signature = signerCredentials.GenerateCertificateSignature(hash);
@@ -375,6 +371,7 @@ namespace Org.BouncyCastle.Crypto.Tls
.SetMasterSecret(securityParameters.masterSecret)
.SetPeerCertificate(serverCertificate)
.SetPskIdentity(securityParameters.pskIdentity)
+ .SetSrpIdentity(securityParameters.srpIdentity)
.Build();
state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters);
@@ -435,8 +432,6 @@ namespace Org.BouncyCastle.Crypto.Tls
// Integer -> byte[]
state.clientExtensions = client.GetClientExtensions();
- securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);
-
// Cipher Suites (and SCSV)
{
/*
@@ -651,15 +646,6 @@ namespace Org.BouncyCastle.Crypto.Tls
IDictionary serverExtensions = TlsProtocol.ReadExtensions(buf);
/*
- * draft-ietf-tls-session-hash-01 5.2. If a server receives the "extended_master_secret"
- * extension, it MUST include the "extended_master_secret" extension in its ServerHello
- * message.
- */
- bool serverSentExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(serverExtensions);
- if (serverSentExtendedMasterSecret != securityParameters.extendedMasterSecret)
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
-
- /*
* RFC 3546 2.2 Note that the extended server hello message is only sent in response to an
* extended client hello message. However, see RFC 5746 exception below. We always include
* the SCSV, so an Extended Server Hello is always allowed.
@@ -689,15 +675,6 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.unsupported_extension);
/*
- * draft-ietf-tls-session-hash-01 5.2. Implementation note: if the server decides to
- * proceed with resumption, the extension does not have any effect. Requiring the
- * extension to be included anyway makes the extension negotiation logic easier,
- * because it does not depend on whether resumption is accepted or not.
- */
- if (extType == ExtensionType.extended_master_secret)
- continue;
-
- /*
* RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore
* extensions appearing in the client hello, and send a server hello containing no
* extensions[.]
@@ -748,6 +725,8 @@ namespace Org.BouncyCastle.Crypto.Tls
securityParameters.encryptThenMac = serverSentEncryptThenMAC;
+ securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(serverExtensions);
+
state.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.clientExtensions, serverExtensions,
AlertDescription.illegal_parameter);
@@ -760,6 +739,13 @@ namespace Org.BouncyCastle.Crypto.Tls
ExtensionType.session_ticket, AlertDescription.illegal_parameter);
}
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
+
state.client.NotifySecureRenegotiation(state.secure_renegotiation);
if (state.clientExtensions != null)
diff --git a/crypto/src/crypto/tls/DtlsReliableHandshake.cs b/crypto/src/crypto/tls/DtlsReliableHandshake.cs
index bf9e61d03..8e4439e67 100644
--- a/crypto/src/crypto/tls/DtlsReliableHandshake.cs
+++ b/crypto/src/crypto/tls/DtlsReliableHandshake.cs
@@ -114,17 +114,17 @@ namespace Org.BouncyCastle.Crypto.Tls
{
for (; ; )
{
- int Received = mRecordLayer.Receive(buf, 0, receiveLimit, readTimeoutMillis);
- if (Received < 0)
+ int received = mRecordLayer.Receive(buf, 0, receiveLimit, readTimeoutMillis);
+ if (received < 0)
{
break;
}
- if (Received < 12)
+ if (received < 12)
{
continue;
}
int fragment_length = TlsUtilities.ReadUint24(buf, 9);
- if (Received != (fragment_length + 12))
+ if (received != (fragment_length + 12))
{
continue;
}
diff --git a/crypto/src/crypto/tls/DtlsServerProtocol.cs b/crypto/src/crypto/tls/DtlsServerProtocol.cs
index 3335a9f36..f148eb7d7 100644
--- a/crypto/src/crypto/tls/DtlsServerProtocol.cs
+++ b/crypto/src/crypto/tls/DtlsServerProtocol.cs
@@ -538,6 +538,12 @@ namespace Org.BouncyCastle.Crypto.Tls
TlsServerContextImpl context = state.serverContext;
SecurityParameters securityParameters = context.SecurityParameters;
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);
context.SetClientVersion(client_version);
diff --git a/crypto/src/crypto/tls/ExporterLabel.cs b/crypto/src/crypto/tls/ExporterLabel.cs
index 280321e2a..5970769d7 100644
--- a/crypto/src/crypto/tls/ExporterLabel.cs
+++ b/crypto/src/crypto/tls/ExporterLabel.cs
@@ -30,7 +30,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public const string dtls_srtp = "EXTRACTOR-dtls_srtp";
/*
- * draft-ietf-tls-session-hash-01
+ * draft-ietf-tls-session-hash-04
*/
public static readonly string extended_master_secret = "extended master secret";
}
diff --git a/crypto/src/crypto/tls/ExtensionType.cs b/crypto/src/crypto/tls/ExtensionType.cs
index acee380b6..b4b24f7c3 100644
--- a/crypto/src/crypto/tls/ExtensionType.cs
+++ b/crypto/src/crypto/tls/ExtensionType.cs
@@ -49,7 +49,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public const int encrypt_then_mac = 22;
/*
- * draft-ietf-tls-session-hash-01
+ * draft-ietf-tls-session-hash-04
*
* NOTE: Early code-point assignment
*/
diff --git a/crypto/src/crypto/tls/PskTlsClient.cs b/crypto/src/crypto/tls/PskTlsClient.cs
index 1f4b0865c..2ef80dcfd 100644
--- a/crypto/src/crypto/tls/PskTlsClient.cs
+++ b/crypto/src/crypto/tls/PskTlsClient.cs
@@ -32,87 +32,15 @@ namespace Org.BouncyCastle.Crypto.Tls
public override TlsKeyExchange GetKeyExchange()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.DHE_PSK);
-
- case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.ECDHE_PSK);
-
- case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.PSK);
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.RSA_PSK);
+ switch (keyExchangeAlgorithm)
+ {
+ case KeyExchangeAlgorithm.DHE_PSK:
+ case KeyExchangeAlgorithm.ECDHE_PSK:
+ case KeyExchangeAlgorithm.PSK:
+ case KeyExchangeAlgorithm.RSA_PSK:
+ return CreatePskKeyExchange(keyExchangeAlgorithm);
default:
/*
@@ -133,134 +61,6 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.internal_error);
}
- public override TlsCipher GetCipher()
- {
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.ESTREAM_SALSA20, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SALSA20, MacAlgorithm.hmac_sha1);
-
- default:
- /*
- * Note: internal error here; the TlsProtocol implementation verifies that the
- * server-selected cipher suite was in the list of client-offered cipher suites, so if
- * we now can't produce an implementation, we shouldn't have offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
-
protected virtual TlsKeyExchange CreatePskKeyExchange(int keyExchange)
{
return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mPskIdentity, null, null, mNamedCurves,
diff --git a/crypto/src/crypto/tls/PskTlsServer.cs b/crypto/src/crypto/tls/PskTlsServer.cs
index bdb8b74a5..27d2b8119 100644
--- a/crypto/src/crypto/tls/PskTlsServer.cs
+++ b/crypto/src/crypto/tls/PskTlsServer.cs
@@ -44,301 +44,47 @@ namespace Org.BouncyCastle.Crypto.Tls
public override TlsCredentials GetCredentials()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
-
- case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
- return null;
+ switch (keyExchangeAlgorithm)
+ {
+ case KeyExchangeAlgorithm.DHE_PSK:
+ case KeyExchangeAlgorithm.ECDHE_PSK:
+ case KeyExchangeAlgorithm.PSK:
+ return null;
- case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
- return GetRsaEncryptionCredentials();
+ case KeyExchangeAlgorithm.RSA_PSK:
+ return GetRsaEncryptionCredentials();
- default:
- /* Note: internal error here; selected a key exchange we don't implement! */
- throw new TlsFatalAlert(AlertDescription.internal_error);
+ default:
+ /* Note: internal error here; selected a key exchange we don't implement! */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
public override TlsKeyExchange GetKeyExchange()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.DHE_PSK);
-
- case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.ECDHE_PSK);
-
- case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.PSK);
-
- case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.RSA_PSK);
-
- default:
- /*
- * Note: internal error here; the TlsProtocol implementation verifies that the
- * server-selected cipher suite was in the list of client-offered cipher suites, so if
- * we now can't produce an implementation, we shouldn't have offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- public override TlsCipher GetCipher()
- {
- switch (mSelectedCipherSuite)
+ switch (keyExchangeAlgorithm)
{
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
- case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_GCM, MacAlgorithm.cls_null);
-
- case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.ESTREAM_SALSA20, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha256);
-
- case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
- case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha384);
-
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
- case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SALSA20, MacAlgorithm.hmac_sha1);
-
- default:
- /*
- * Note: internal error here; the TlsProtocol implementation verifies that the
- * server-selected cipher suite was in the list of client-offered cipher suites, so if
- * we now can't produce an implementation, we shouldn't have offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
+ case KeyExchangeAlgorithm.DHE_PSK:
+ case KeyExchangeAlgorithm.ECDHE_PSK:
+ case KeyExchangeAlgorithm.PSK:
+ case KeyExchangeAlgorithm.RSA_PSK:
+ return CreatePskKeyExchange(keyExchangeAlgorithm);
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocol implementation verifies that the
+ * server-selected cipher suite was in the list of client-offered cipher suites, so if
+ * we now can't produce an implementation, we shouldn't have offered it!
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
- protected TlsKeyExchange CreatePskKeyExchange(int keyExchange)
+ protected virtual TlsKeyExchange CreatePskKeyExchange(int keyExchange)
{
return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, mPskIdentityManager,
GetDHParameters(), mNamedCurves, mClientECPointFormats, mServerECPointFormats);
diff --git a/crypto/src/crypto/tls/SecurityParameters.cs b/crypto/src/crypto/tls/SecurityParameters.cs
index 0f48ee23e..3b851587d 100644
--- a/crypto/src/crypto/tls/SecurityParameters.cs
+++ b/crypto/src/crypto/tls/SecurityParameters.cs
@@ -16,6 +16,7 @@ namespace Org.BouncyCastle.Crypto.Tls
internal byte[] serverRandom = null;
internal byte[] sessionHash = null;
internal byte[] pskIdentity = null;
+ internal byte[] srpIdentity = null;
// TODO Keep these internal, since it's maybe not the ideal place for them
internal short maxFragmentLength = -1;
@@ -93,5 +94,10 @@ namespace Org.BouncyCastle.Crypto.Tls
{
get { return pskIdentity; }
}
+
+ public virtual byte[] SrpIdentity
+ {
+ get { return srpIdentity; }
+ }
}
}
diff --git a/crypto/src/crypto/tls/ServerSrpParams.cs b/crypto/src/crypto/tls/ServerSrpParams.cs
new file mode 100644
index 000000000..556ac5310
--- /dev/null
+++ b/crypto/src/crypto/tls/ServerSrpParams.cs
@@ -0,0 +1,75 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public class ServerSrpParams
+ {
+ protected BigInteger m_N, m_g, m_B;
+ protected byte[] m_s;
+
+ public ServerSrpParams(BigInteger N, BigInteger g, byte[] s, BigInteger B)
+ {
+ this.m_N = N;
+ this.m_g = g;
+ this.m_s = Arrays.Clone(s);
+ this.m_B = B;
+ }
+
+ public virtual BigInteger B
+ {
+ get { return m_B; }
+ }
+
+ public virtual BigInteger G
+ {
+ get { return m_g; }
+ }
+
+ public virtual BigInteger N
+ {
+ get { return m_N; }
+ }
+
+ public virtual byte[] S
+ {
+ get { return m_s; }
+ }
+
+ /**
+ * Encode this {@link ServerSRPParams} to an {@link OutputStream}.
+ *
+ * @param output
+ * the {@link OutputStream} to encode to.
+ * @throws IOException
+ */
+ public virtual void Encode(Stream output)
+ {
+ TlsSrpUtilities.WriteSrpParameter(m_N, output);
+ TlsSrpUtilities.WriteSrpParameter(m_g, output);
+ TlsUtilities.WriteOpaque8(m_s, output);
+ TlsSrpUtilities.WriteSrpParameter(m_B, output);
+ }
+
+ /**
+ * Parse a {@link ServerSRPParams} from an {@link InputStream}.
+ *
+ * @param input
+ * the {@link InputStream} to parse from.
+ * @return a {@link ServerSRPParams} object.
+ * @throws IOException
+ */
+ public static ServerSrpParams Parse(Stream input)
+ {
+ BigInteger N = TlsSrpUtilities.ReadSrpParameter(input);
+ BigInteger g = TlsSrpUtilities.ReadSrpParameter(input);
+ byte[] s = TlsUtilities.ReadOpaque8(input);
+ BigInteger B = TlsSrpUtilities.ReadSrpParameter(input);
+
+ return new ServerSrpParams(N, g, s, B);
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/SessionParameters.cs b/crypto/src/crypto/tls/SessionParameters.cs
index b17e931d7..a1eb5f27c 100644
--- a/crypto/src/crypto/tls/SessionParameters.cs
+++ b/crypto/src/crypto/tls/SessionParameters.cs
@@ -15,6 +15,7 @@ namespace Org.BouncyCastle.Crypto.Tls
private byte[] mMasterSecret = null;
private Certificate mPeerCertificate = null;
private byte[] mPskIdentity = null;
+ private byte[] mSrpIdentity = null;
private byte[] mEncodedServerExtensions = null;
public Builder()
@@ -27,7 +28,7 @@ namespace Org.BouncyCastle.Crypto.Tls
Validate(this.mCompressionAlgorithm >= 0, "compressionAlgorithm");
Validate(this.mMasterSecret != null, "masterSecret");
return new SessionParameters(mCipherSuite, (byte)mCompressionAlgorithm, mMasterSecret, mPeerCertificate,
- mPskIdentity, mEncodedServerExtensions);
+ mPskIdentity, mSrpIdentity, mEncodedServerExtensions);
}
public Builder SetCipherSuite(int cipherSuite)
@@ -60,6 +61,12 @@ namespace Org.BouncyCastle.Crypto.Tls
return this;
}
+ public Builder SetSrpIdentity(byte[] srpIdentity)
+ {
+ this.mSrpIdentity = srpIdentity;
+ return this;
+ }
+
public Builder SetServerExtensions(IDictionary serverExtensions)
{
if (serverExtensions == null)
@@ -87,16 +94,18 @@ namespace Org.BouncyCastle.Crypto.Tls
private byte[] mMasterSecret;
private Certificate mPeerCertificate;
private byte[] mPskIdentity;
+ private byte[] mSrpIdentity;
private byte[] mEncodedServerExtensions;
private SessionParameters(int cipherSuite, byte compressionAlgorithm, byte[] masterSecret,
- Certificate peerCertificate, byte[] pskIdentity, byte[] encodedServerExtensions)
+ Certificate peerCertificate, byte[] pskIdentity, byte[] srpIdentity, byte[] encodedServerExtensions)
{
this.mCipherSuite = cipherSuite;
this.mCompressionAlgorithm = compressionAlgorithm;
this.mMasterSecret = Arrays.Clone(masterSecret);
this.mPeerCertificate = peerCertificate;
this.mPskIdentity = Arrays.Clone(pskIdentity);
+ this.mSrpIdentity = Arrays.Clone(srpIdentity);
this.mEncodedServerExtensions = encodedServerExtensions;
}
@@ -111,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public SessionParameters Copy()
{
return new SessionParameters(mCipherSuite, mCompressionAlgorithm, mMasterSecret, mPeerCertificate,
- mPskIdentity, mEncodedServerExtensions);
+ mPskIdentity, mSrpIdentity, mEncodedServerExtensions);
}
public int CipherSuite
@@ -139,6 +148,11 @@ namespace Org.BouncyCastle.Crypto.Tls
get { return mPskIdentity; }
}
+ public byte[] SrpIdentity
+ {
+ get { return mSrpIdentity; }
+ }
+
public IDictionary ReadServerExtensions()
{
if (mEncodedServerExtensions == null)
diff --git a/crypto/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs b/crypto/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs
new file mode 100644
index 000000000..3e9737cd7
--- /dev/null
+++ b/crypto/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs
@@ -0,0 +1,69 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Agreement.Srp;
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ /**
+ * An implementation of {@link TlsSRPIdentityManager} that simulates the existence of "unknown" identities
+ * to obscure the fact that there is no verifier for them.
+ */
+ public class SimulatedTlsSrpIdentityManager
+ : TlsSrpIdentityManager
+ {
+ private static readonly byte[] PREFIX_PASSWORD = Strings.ToByteArray("password");
+ private static readonly byte[] PREFIX_SALT = Strings.ToByteArray("salt");
+
+ /**
+ * Create a {@link SimulatedTlsSRPIdentityManager} that implements the algorithm from RFC 5054 2.5.1.3
+ *
+ * @param group the {@link SRP6GroupParameters} defining the group that SRP is operating in
+ * @param seedKey the secret "seed key" referred to in RFC 5054 2.5.1.3
+ * @return an instance of {@link SimulatedTlsSRPIdentityManager}
+ */
+ public static SimulatedTlsSrpIdentityManager GetRfc5054Default(Srp6GroupParameters group, byte[] seedKey)
+ {
+ Srp6VerifierGenerator verifierGenerator = new Srp6VerifierGenerator();
+ verifierGenerator.Init(group, TlsUtilities.CreateHash(HashAlgorithm.sha1));
+
+ HMac mac = new HMac(TlsUtilities.CreateHash(HashAlgorithm.sha1));
+ mac.Init(new KeyParameter(seedKey));
+
+ return new SimulatedTlsSrpIdentityManager(group, verifierGenerator, mac);
+ }
+
+ protected readonly Srp6GroupParameters mGroup;
+ protected readonly Srp6VerifierGenerator mVerifierGenerator;
+ protected readonly IMac mMac;
+
+ public SimulatedTlsSrpIdentityManager(Srp6GroupParameters group, Srp6VerifierGenerator verifierGenerator, IMac mac)
+ {
+ this.mGroup = group;
+ this.mVerifierGenerator = verifierGenerator;
+ this.mMac = mac;
+ }
+
+ public virtual TlsSrpLoginParameters GetLoginParameters(byte[] identity)
+ {
+ mMac.BlockUpdate(PREFIX_SALT, 0, PREFIX_SALT.Length);
+ mMac.BlockUpdate(identity, 0, identity.Length);
+
+ byte[] salt = new byte[mMac.GetMacSize()];
+ mMac.DoFinal(salt, 0);
+
+ mMac.BlockUpdate(PREFIX_PASSWORD, 0, PREFIX_PASSWORD.Length);
+ mMac.BlockUpdate(identity, 0, identity.Length);
+
+ byte[] password = new byte[mMac.GetMacSize()];
+ mMac.DoFinal(password, 0);
+
+ BigInteger verifier = mVerifierGenerator.GenerateVerifier(salt, identity, password);
+
+ return new TlsSrpLoginParameters(mGroup, verifier, salt);
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/SrpTlsClient.cs b/crypto/src/crypto/tls/SrpTlsClient.cs
index 5d82ed470..df1607751 100644
--- a/crypto/src/crypto/tls/SrpTlsClient.cs
+++ b/crypto/src/crypto/tls/SrpTlsClient.cs
@@ -6,20 +6,29 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls
{
- public abstract class SrpTlsClient
+ public class SrpTlsClient
: AbstractTlsClient
{
+ protected TlsSrpGroupVerifier mGroupVerifier;
+
protected byte[] mIdentity;
protected byte[] mPassword;
public SrpTlsClient(byte[] identity, byte[] password)
- : this(new DefaultTlsCipherFactory(), identity, password)
+ : this(new DefaultTlsCipherFactory(), new DefaultTlsSrpGroupVerifier(), identity, password)
{
}
public SrpTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password)
+ : this(cipherFactory, new DefaultTlsSrpGroupVerifier(), identity, password)
+ {
+ }
+
+ public SrpTlsClient(TlsCipherFactory cipherFactory, TlsSrpGroupVerifier groupVerifier,
+ byte[] identity, byte[] password)
: base(cipherFactory)
{
+ this.mGroupVerifier = groupVerifier;
this.mIdentity = Arrays.Clone(identity);
this.mPassword = Arrays.Clone(password);
}
@@ -59,22 +68,14 @@ namespace Org.BouncyCastle.Crypto.Tls
public override TlsKeyExchange GetKeyExchange()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
- return CreateSrpKeyExchange(KeyExchangeAlgorithm.SRP);
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
- case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
- return CreateSrpKeyExchange(KeyExchangeAlgorithm.SRP_RSA);
-
- case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
- return CreateSrpKeyExchange(KeyExchangeAlgorithm.SRP_DSS);
+ switch (keyExchangeAlgorithm)
+ {
+ case KeyExchangeAlgorithm.SRP:
+ case KeyExchangeAlgorithm.SRP_DSS:
+ case KeyExchangeAlgorithm.SRP_RSA:
+ return CreateSrpKeyExchange(keyExchangeAlgorithm);
default:
/*
@@ -86,38 +87,18 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
- public override TlsCipher GetCipher()
+ public override TlsAuthentication GetAuthentication()
{
- switch (mSelectedCipherSuite)
- {
- case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
-
- case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
-
- default:
- /*
- * Note: internal error here; the TlsProtocol implementation verifies that the
- * server-selected cipher suite was in the list of client-offered cipher suites, so if
- * we now can't produce an implementation, we shouldn't have offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
+ /*
+ * Note: This method is not called unless a server certificate is sent, which may be the
+ * case e.g. for SRP_DSS or SRP_RSA key exchange.
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
protected virtual TlsKeyExchange CreateSrpKeyExchange(int keyExchange)
{
- return new TlsSrpKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mIdentity, mPassword);
+ return new TlsSrpKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mGroupVerifier, mIdentity, mPassword);
}
}
}
diff --git a/crypto/src/crypto/tls/SrpTlsServer.cs b/crypto/src/crypto/tls/SrpTlsServer.cs
new file mode 100644
index 000000000..f97878380
--- /dev/null
+++ b/crypto/src/crypto/tls/SrpTlsServer.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public class SrpTlsServer
+ : AbstractTlsServer
+ {
+ protected TlsSrpIdentityManager mSrpIdentityManager;
+
+ protected byte[] mSrpIdentity = null;
+ protected TlsSrpLoginParameters mLoginParameters = null;
+
+ public SrpTlsServer(TlsSrpIdentityManager srpIdentityManager)
+ : this(new DefaultTlsCipherFactory(), srpIdentityManager)
+ {
+ }
+
+ public SrpTlsServer(TlsCipherFactory cipherFactory, TlsSrpIdentityManager srpIdentityManager)
+ : base(cipherFactory)
+ {
+ this.mSrpIdentityManager = srpIdentityManager;
+ }
+
+ protected virtual TlsSignerCredentials GetDsaSignerCredentials()
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ protected virtual TlsSignerCredentials GetRsaSignerCredentials()
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ protected override int[] GetCipherSuites()
+ {
+ return new int[]
+ {
+ CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA
+ };
+ }
+
+ public override void ProcessClientExtensions(IDictionary clientExtensions)
+ {
+ base.ProcessClientExtensions(clientExtensions);
+
+ this.mSrpIdentity = TlsSrpUtilities.GetSrpExtension(clientExtensions);
+ }
+
+ public override int GetSelectedCipherSuite()
+ {
+ int cipherSuite = base.GetSelectedCipherSuite();
+
+ if (TlsSrpUtilities.IsSrpCipherSuite(cipherSuite))
+ {
+ if (mSrpIdentity != null)
+ {
+ this.mLoginParameters = mSrpIdentityManager.GetLoginParameters(mSrpIdentity);
+ }
+
+ if (mLoginParameters == null)
+ throw new TlsFatalAlert(AlertDescription.unknown_psk_identity);
+ }
+
+ return cipherSuite;
+ }
+
+ public override TlsCredentials GetCredentials()
+ {
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
+
+ switch (keyExchangeAlgorithm)
+ {
+ case KeyExchangeAlgorithm.SRP:
+ return null;
+
+ case KeyExchangeAlgorithm.SRP_DSS:
+ return GetDsaSignerCredentials();
+
+ case KeyExchangeAlgorithm.SRP_RSA:
+ return GetRsaSignerCredentials();
+
+ default:
+ /* Note: internal error here; selected a key exchange we don't implement! */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
+ public override TlsKeyExchange GetKeyExchange()
+ {
+ int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite);
+
+ switch (keyExchangeAlgorithm)
+ {
+ case KeyExchangeAlgorithm.SRP:
+ case KeyExchangeAlgorithm.SRP_DSS:
+ case KeyExchangeAlgorithm.SRP_RSA:
+ return CreateSrpKeyExchange(keyExchangeAlgorithm);
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocol implementation verifies that the
+ * server-selected cipher suite was in the list of client-offered cipher suites, so if
+ * we now can't produce an implementation, we shouldn't have offered it!
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
+ protected virtual TlsKeyExchange CreateSrpKeyExchange(int keyExchange)
+ {
+ return new TlsSrpKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mSrpIdentity, mLoginParameters);
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/TlsClientProtocol.cs b/crypto/src/crypto/tls/TlsClientProtocol.cs
index 19e7d71aa..5b9e81b3f 100644
--- a/crypto/src/crypto/tls/TlsClientProtocol.cs
+++ b/crypto/src/crypto/tls/TlsClientProtocol.cs
@@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mRecordStream.Init(mTlsClientContext);
TlsSession sessionToResume = tlsClient.GetSessionToResume();
- if (sessionToResume != null)
+ if (sessionToResume != null && sessionToResume.IsResumable)
{
SessionParameters sessionParameters = sessionToResume.ExportSessionParameters();
if (sessionParameters != null)
@@ -373,21 +373,17 @@ namespace Org.BouncyCastle.Crypto.Tls
/*
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
*/
- SignatureAndHashAlgorithm signatureAndHashAlgorithm;
- byte[] hash;
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ Context, signerCredentials);
- if (TlsUtilities.IsTlsV12(Context))
+ byte[] hash;
+ if (signatureAndHashAlgorithm == null)
{
- signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm;
- if (signatureAndHashAlgorithm == null)
- throw new TlsFatalAlert(AlertDescription.internal_error);
-
- hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
+ hash = mSecurityParameters.SessionHash;
}
else
{
- signatureAndHashAlgorithm = null;
- hash = mSecurityParameters.SessionHash;
+ hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
}
byte[] signature = signerCredentials.GenerateCertificateSignature(hash);
@@ -529,15 +525,7 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
if (this.mConnectionState == CS_END)
{
- /*
- * RFC 5746 4.5 SSLv3 clients that refuse renegotiation SHOULD use a fatal
- * handshake_failure alert.
- */
- if (TlsUtilities.IsSsl(Context))
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
-
- string message = "Renegotiation not supported";
- RaiseWarning(AlertDescription.no_renegotiation, message);
+ RefuseRenegotiation();
}
break;
}
@@ -636,15 +624,6 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mServerExtensions = ReadExtensions(buf);
/*
- * draft-ietf-tls-session-hash-01 5.2. If a server receives the "extended_master_secret"
- * extension, it MUST include the "extended_master_secret" extension in its ServerHello
- * message.
- */
- bool serverSentExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mServerExtensions);
- if (serverSentExtendedMasterSecret != mSecurityParameters.extendedMasterSecret)
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
-
- /*
* RFC 3546 2.2 Note that the extended server hello message is only sent in response to an
* extended client hello message.
*
@@ -676,15 +655,6 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.unsupported_extension);
/*
- * draft-ietf-tls-session-hash-01 5.2. Implementation note: if the server decides to
- * proceed with resumption, the extension does not have any effect. Requiring the
- * extension to be included anyway makes the extension negotiation logic easier,
- * because it does not depend on whether resumption is accepted or not.
- */
- if (extType == ExtensionType.extended_master_secret)
- continue;
-
- /*
* RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore
* extensions appearing in the client hello, and Send a server hello containing no
* extensions[.]
@@ -737,8 +707,6 @@ namespace Org.BouncyCastle.Crypto.Tls
sessionClientExtensions = null;
sessionServerExtensions = this.mSessionParameters.ReadServerExtensions();
-
- this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);
}
this.mSecurityParameters.cipherSuite = selectedCipherSuite;
@@ -758,6 +726,8 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mSecurityParameters.encryptThenMac = serverSentEncryptThenMAC;
+ this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);
+
this.mSecurityParameters.maxFragmentLength = ProcessMaxFragmentLengthExtension(sessionClientExtensions,
sessionServerExtensions, AlertDescription.illegal_parameter);
@@ -776,6 +746,13 @@ namespace Org.BouncyCastle.Crypto.Tls
AlertDescription.illegal_parameter);
}
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
+
if (sessionClientExtensions != null)
{
this.mTlsClient.ProcessServerExtensions(sessionServerExtensions);
@@ -832,8 +809,6 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mClientExtensions = this.mTlsClient.GetClientExtensions();
- this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mClientExtensions);
-
HandshakeMessage message = new HandshakeMessage(HandshakeType.client_hello);
TlsUtilities.WriteVersion(client_version, message);
diff --git a/crypto/src/crypto/tls/TlsDHKeyExchange.cs b/crypto/src/crypto/tls/TlsDHKeyExchange.cs
index b831249a6..211249fcc 100644
--- a/crypto/src/crypto/tls/TlsDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsDHKeyExchange.cs
@@ -4,6 +4,7 @@ using System.IO;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls
@@ -16,12 +17,10 @@ namespace Org.BouncyCastle.Crypto.Tls
protected DHParameters mDHParameters;
protected AsymmetricKeyParameter mServerPublicKey;
- protected DHPublicKeyParameters mDHAgreeServerPublicKey;
protected TlsAgreementCredentials mAgreementCredentials;
- protected DHPrivateKeyParameters mDHAgreeClientPrivateKey;
- protected DHPrivateKeyParameters mDHAgreeServerPrivateKey;
- protected DHPublicKeyParameters mDHAgreeClientPublicKey;
+ protected DHPrivateKeyParameters mDHAgreePrivateKey;
+ protected DHPublicKeyParameters mDHAgreePublicKey;
public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters)
: base(keyExchange, supportedSignatureAlgorithms)
@@ -81,7 +80,7 @@ namespace Org.BouncyCastle.Crypto.Tls
{
try
{
- this.mDHAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey);
+ this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey);
}
catch (InvalidCastException e)
{
@@ -165,26 +164,40 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
if (mAgreementCredentials == null)
{
- this.mDHAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
- mDHAgreeServerPublicKey.Parameters, output);
+ this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
+ mDHParameters, output);
}
}
- public override byte[] GeneratePremasterSecret()
+ public override void ProcessClientCertificate(Certificate clientCertificate)
{
- if (mAgreementCredentials != null)
+ // TODO Extract the public key
+ // TODO If the certificate is 'fixed', take the public key as dhAgreeClientPublicKey
+ }
+
+ public override void ProcessClientKeyExchange(Stream input)
+ {
+ if (mDHAgreePublicKey != null)
{
- return mAgreementCredentials.GenerateAgreement(mDHAgreeServerPublicKey);
+ // For dss_fixed_dh and rsa_fixed_dh, the key arrived in the client certificate
+ return;
}
- if (mDHAgreeServerPrivateKey != null)
+ BigInteger Yc = TlsDHUtilities.ReadDHParameter(input);
+
+ this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Yc, mDHParameters));
+ }
+
+ public override byte[] GeneratePremasterSecret()
+ {
+ if (mAgreementCredentials != null)
{
- return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreeClientPublicKey, mDHAgreeServerPrivateKey);
+ return mAgreementCredentials.GenerateAgreement(mDHAgreePublicKey);
}
- if (mDHAgreeClientPrivateKey != null)
+ if (mDHAgreePrivateKey != null)
{
- return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreeServerPublicKey, mDHAgreeClientPrivateKey);
+ return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey);
}
throw new TlsFatalAlert(AlertDescription.internal_error);
diff --git a/crypto/src/crypto/tls/TlsDheKeyExchange.cs b/crypto/src/crypto/tls/TlsDheKeyExchange.cs
index 3c05bb6f0..419d4e442 100644
--- a/crypto/src/crypto/tls/TlsDheKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsDheKeyExchange.cs
@@ -36,30 +36,18 @@ namespace Org.BouncyCastle.Crypto.Tls
DigestInputBuffer buf = new DigestInputBuffer();
- this.mDHAgreeServerPrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom,
+ this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
this.mDHParameters, buf);
/*
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
*/
- SignatureAndHashAlgorithm signatureAndHashAlgorithm;
- IDigest d;
-
- if (TlsUtilities.IsTlsV12(context))
- {
- signatureAndHashAlgorithm = mServerCredentials.SignatureAndHashAlgorithm;
- if (signatureAndHashAlgorithm == null)
- throw new TlsFatalAlert(AlertDescription.internal_error);
-
- d = TlsUtilities.CreateHash(signatureAndHashAlgorithm.Hash);
- }
- else
- {
- signatureAndHashAlgorithm = null;
- d = new CombinedHash();
- }
-
- SecurityParameters securityParameters = context.SecurityParameters;
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ mContext, mServerCredentials);
+
+ IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm);
+
+ SecurityParameters securityParameters = mContext.SecurityParameters;
d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
buf.UpdateDigest(d);
@@ -76,21 +64,22 @@ namespace Org.BouncyCastle.Crypto.Tls
public override void ProcessServerKeyExchange(Stream input)
{
- SecurityParameters securityParameters = context.SecurityParameters;
+ SecurityParameters securityParameters = mContext.SecurityParameters;
SignerInputBuffer buf = new SignerInputBuffer();
Stream teeIn = new TeeInputStream(input, buf);
ServerDHParams dhParams = ServerDHParams.Parse(teeIn);
- DigitallySigned signed_params = DigitallySigned.Parse(context, input);
+ DigitallySigned signed_params = DigitallySigned.Parse(mContext, input);
ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
buf.UpdateSigner(signer);
if (!signer.VerifySignature(signed_params.Signature))
throw new TlsFatalAlert(AlertDescription.decrypt_error);
- this.mDHAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey);
+ this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey);
+ this.mDHParameters = mDHAgreePublicKey.Parameters;
}
protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
diff --git a/crypto/src/crypto/tls/TlsDsaSigner.cs b/crypto/src/crypto/tls/TlsDsaSigner.cs
index a5ac55974..f0c1e9451 100644
--- a/crypto/src/crypto/tls/TlsDsaSigner.cs
+++ b/crypto/src/crypto/tls/TlsDsaSigner.cs
@@ -64,8 +64,7 @@ namespace Org.BouncyCastle.Crypto.Tls
if ((algorithm != null) != TlsUtilities.IsTlsV12(mContext))
throw new InvalidOperationException();
- // TODO For TLS 1.2+, lift the SHA-1 restriction here
- if (algorithm != null && (algorithm.Hash != HashAlgorithm.sha1 || algorithm.Signature != SignatureAlgorithm))
+ if (algorithm != null && algorithm.Signature != SignatureAlgorithm)
throw new InvalidOperationException();
byte hashAlgorithm = algorithm == null ? HashAlgorithm.sha1 : algorithm.Hash;
diff --git a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
index 42dc2f2ef..992be4aca 100644
--- a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
@@ -166,7 +166,7 @@ namespace Org.BouncyCastle.Crypto.Tls
{
if (mAgreementCredentials == null)
{
- this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
+ this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
mServerECPointFormats, mECAgreePublicKey.Parameters, output);
}
}
diff --git a/crypto/src/crypto/tls/TlsECDheKeyExchange.cs b/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
index b99db0c18..b681aada3 100644
--- a/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
@@ -36,30 +36,18 @@ namespace Org.BouncyCastle.Crypto.Tls
{
DigestInputBuffer buf = new DigestInputBuffer();
- this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom, mNamedCurves,
+ this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves,
mClientECPointFormats, buf);
/*
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
*/
- SignatureAndHashAlgorithm signatureAndHashAlgorithm;
- IDigest d;
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ mContext, mServerCredentials);
- if (TlsUtilities.IsTlsV12(context))
- {
- signatureAndHashAlgorithm = mServerCredentials.SignatureAndHashAlgorithm;
- if (signatureAndHashAlgorithm == null)
- throw new TlsFatalAlert(AlertDescription.internal_error);
-
- d = TlsUtilities.CreateHash(signatureAndHashAlgorithm.Hash);
- }
- else
- {
- signatureAndHashAlgorithm = null;
- d = new CombinedHash();
- }
+ IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm);
- SecurityParameters securityParameters = context.SecurityParameters;
+ SecurityParameters securityParameters = mContext.SecurityParameters;
d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
buf.UpdateDigest(d);
@@ -76,7 +64,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public override void ProcessServerKeyExchange(Stream input)
{
- SecurityParameters securityParameters = context.SecurityParameters;
+ SecurityParameters securityParameters = mContext.SecurityParameters;
SignerInputBuffer buf = new SignerInputBuffer();
Stream teeIn = new TeeInputStream(input, buf);
@@ -85,7 +73,7 @@ namespace Org.BouncyCastle.Crypto.Tls
byte[] point = TlsUtilities.ReadOpaque8(teeIn);
- DigitallySigned signed_params = DigitallySigned.Parse(context, input);
+ DigitallySigned signed_params = DigitallySigned.Parse(mContext, input);
ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
buf.UpdateSigner(signer);
diff --git a/crypto/src/crypto/tls/TlsEccUtilities.cs b/crypto/src/crypto/tls/TlsEccUtilities.cs
index e938b1685..d0d794d0e 100644
--- a/crypto/src/crypto/tls/TlsEccUtilities.cs
+++ b/crypto/src/crypto/tls/TlsEccUtilities.cs
@@ -427,7 +427,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public static ECPrivateKeyParameters GenerateEphemeralClientKeyExchange(SecureRandom random, byte[] ecPointFormats,
ECDomainParameters ecParams, Stream output)
{
- AsymmetricCipherKeyPair kp = TlsEccUtilities.GenerateECKeyPair(random, ecParams);
+ AsymmetricCipherKeyPair kp = GenerateECKeyPair(random, ecParams);
ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters)kp.Public;
WriteECPoint(ecPointFormats, ecPublicKey.Q, output);
diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs
index 09838a717..4ea72cd57 100644
--- a/crypto/src/crypto/tls/TlsProtocol.cs
+++ b/crypto/src/crypto/tls/TlsProtocol.cs
@@ -99,6 +99,12 @@ namespace Org.BouncyCastle.Crypto.Tls
{
}
+ protected virtual void CheckReceivedChangeCipherSpec(bool expected)
+ {
+ if (expected != mReceivedChangeCipherSpec)
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
protected virtual void CleanupHandshake()
{
if (this.mExpectedVerifyData != null)
@@ -162,6 +168,8 @@ namespace Org.BouncyCastle.Crypto.Tls
.SetCompressionAlgorithm(this.mSecurityParameters.compressionAlgorithm)
.SetMasterSecret(this.mSecurityParameters.masterSecret)
.SetPeerCertificate(this.mPeerCertificate)
+ .SetPskIdentity(this.mSecurityParameters.pskIdentity)
+ .SetSrpIdentity(this.mSecurityParameters.srpIdentity)
// TODO Consider filtering extensions that aren't relevant to resumed sessions
.SetServerExtensions(this.mServerExtensions)
.Build();
@@ -259,6 +267,8 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
byte[] buf = mHandshakeQueue.RemoveData(len, 4);
+ CheckReceivedChangeCipherSpec(mConnectionState == CS_END || type == HandshakeType.finished);
+
/*
* RFC 2246 7.4.9. The value handshake_messages includes all handshake messages
* starting at client hello up to, but not including, this finished message.
@@ -270,15 +280,20 @@ namespace Org.BouncyCastle.Crypto.Tls
break;
case HandshakeType.finished:
default:
- if (type == HandshakeType.finished && this.mExpectedVerifyData == null)
+ {
+ TlsContext ctx = Context;
+ if (type == HandshakeType.finished
+ && this.mExpectedVerifyData == null
+ && ctx.SecurityParameters.MasterSecret != null)
{
- this.mExpectedVerifyData = CreateVerifyData(!Context.IsServer);
+ this.mExpectedVerifyData = CreateVerifyData(!ctx.IsServer);
}
mRecordStream.UpdateHandshakeData(beginning, 0, 4);
mRecordStream.UpdateHandshakeData(buf, 0, len);
break;
}
+ }
/*
* Now, parse the message.
@@ -612,6 +627,9 @@ namespace Org.BouncyCastle.Crypto.Tls
protected virtual void ProcessFinishedMessage(MemoryStream buf)
{
+ if (mExpectedVerifyData == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
byte[] verify_data = TlsUtilities.ReadFully(mExpectedVerifyData.Length, buf);
AssertEmpty(buf);
@@ -751,6 +769,18 @@ namespace Org.BouncyCastle.Crypto.Tls
return maxFragmentLength;
}
+ protected virtual void RefuseRenegotiation()
+ {
+ /*
+ * RFC 5746 4.5 SSLv3 clients that refuse renegotiation SHOULD use a fatal
+ * handshake_failure alert.
+ */
+ if (TlsUtilities.IsSsl(Context))
+ throw new TlsFatalAlert(AlertDescription.handshake_failure);
+
+ RaiseWarning(AlertDescription.no_renegotiation, "Renegotiation not supported");
+ }
+
/**
* Make sure the InputStream 'buf' now empty. Fail otherwise.
*
diff --git a/crypto/src/crypto/tls/TlsPskKeyExchange.cs b/crypto/src/crypto/tls/TlsPskKeyExchange.cs
index a8d0867ef..0af7f7a69 100644
--- a/crypto/src/crypto/tls/TlsPskKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsPskKeyExchange.cs
@@ -99,12 +99,12 @@ namespace Org.BouncyCastle.Crypto.Tls
if (this.mDHParameters == null)
throw new TlsFatalAlert(AlertDescription.internal_error);
- this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom,
+ this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
this.mDHParameters, buf);
}
else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
{
- this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom,
+ this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom,
mNamedCurves, mClientECPointFormats, buf);
}
@@ -165,6 +165,7 @@ namespace Org.BouncyCastle.Crypto.Tls
ServerDHParams serverDHParams = ServerDHParams.Parse(input);
this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(serverDHParams.PublicKey);
+ this.mDHParameters = mDHAgreePublicKey.Parameters;
}
else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
{
@@ -208,21 +209,21 @@ namespace Org.BouncyCastle.Crypto.Tls
TlsUtilities.WriteOpaque16(psk_identity, output);
- context.SecurityParameters.pskIdentity = psk_identity;
+ mContext.SecurityParameters.pskIdentity = psk_identity;
if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
{
- this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
- mDHAgreePublicKey.Parameters, output);
+ this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
+ mDHParameters, output);
}
else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
{
- this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
+ this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom,
mServerECPointFormats, mECAgreePublicKey.Parameters, output);
}
else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
{
- this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(context,
+ this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext,
this.mRsaServerPublicKey, output);
}
}
@@ -235,7 +236,7 @@ namespace Org.BouncyCastle.Crypto.Tls
if (mPsk == null)
throw new TlsFatalAlert(AlertDescription.unknown_psk_identity);
- context.SecurityParameters.pskIdentity = psk_identity;
+ mContext.SecurityParameters.pskIdentity = psk_identity;
if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
{
@@ -255,7 +256,7 @@ namespace Org.BouncyCastle.Crypto.Tls
else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
{
byte[] encryptedPreMasterSecret;
- if (TlsUtilities.IsSsl(context))
+ if (TlsUtilities.IsSsl(mContext))
{
// TODO Do any SSLv3 clients actually include the length?
encryptedPreMasterSecret = Streams.ReadAll(input);
diff --git a/crypto/src/crypto/tls/TlsRsaKeyExchange.cs b/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
index 3a0a49154..b02d56486 100644
--- a/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
@@ -16,13 +16,13 @@ namespace Org.BouncyCastle.Crypto.Tls
public class TlsRsaKeyExchange
: AbstractTlsKeyExchange
{
- protected AsymmetricKeyParameter serverPublicKey = null;
+ protected AsymmetricKeyParameter mServerPublicKey = null;
- protected RsaKeyParameters rsaServerPublicKey = null;
+ protected RsaKeyParameters mRsaServerPublicKey = null;
- protected TlsEncryptionCredentials serverCredentials = null;
+ protected TlsEncryptionCredentials mServerCredentials = null;
- protected byte[] premasterSecret;
+ protected byte[] mPremasterSecret;
public TlsRsaKeyExchange(IList supportedSignatureAlgorithms)
: base(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms)
@@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Crypto.Tls
ProcessServerCertificate(serverCredentials.Certificate);
- this.serverCredentials = (TlsEncryptionCredentials)serverCredentials;
+ this.mServerCredentials = (TlsEncryptionCredentials)serverCredentials;
}
public override void ProcessServerCertificate(Certificate serverCertificate)
@@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Crypto.Tls
SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
{
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
}
catch (Exception e)
{
@@ -62,10 +62,10 @@ namespace Org.BouncyCastle.Crypto.Tls
}
// Sanity check the PublicKeyFactory
- if (this.serverPublicKey.IsPrivate)
+ if (this.mServerPublicKey.IsPrivate)
throw new TlsFatalAlert(AlertDescription.internal_error);
- this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey);
+ this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey);
TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
@@ -97,13 +97,13 @@ namespace Org.BouncyCastle.Crypto.Tls
public override void GenerateClientKeyExchange(Stream output)
{
- this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(context, rsaServerPublicKey, output);
+ this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext, mRsaServerPublicKey, output);
}
public override void ProcessClientKeyExchange(Stream input)
{
byte[] encryptedPreMasterSecret;
- if (TlsUtilities.IsSsl(context))
+ if (TlsUtilities.IsSsl(mContext))
{
// TODO Do any SSLv3 clients actually include the length?
encryptedPreMasterSecret = Streams.ReadAll(input);
@@ -113,16 +113,16 @@ namespace Org.BouncyCastle.Crypto.Tls
encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input);
}
- this.premasterSecret = serverCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret);
+ this.mPremasterSecret = mServerCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret);
}
public override byte[] GeneratePremasterSecret()
{
- if (this.premasterSecret == null)
+ if (this.mPremasterSecret == null)
throw new TlsFatalAlert(AlertDescription.internal_error);
- byte[] tmp = this.premasterSecret;
- this.premasterSecret = null;
+ byte[] tmp = this.mPremasterSecret;
+ this.mPremasterSecret = null;
return tmp;
}
diff --git a/crypto/src/crypto/tls/TlsServerProtocol.cs b/crypto/src/crypto/tls/TlsServerProtocol.cs
index b1fb830b6..fd6808382 100644
--- a/crypto/src/crypto/tls/TlsServerProtocol.cs
+++ b/crypto/src/crypto/tls/TlsServerProtocol.cs
@@ -179,6 +179,11 @@ namespace Org.BouncyCastle.Crypto.Tls
break;
}
+ case CS_END:
+ {
+ RefuseRenegotiation();
+ break;
+ }
default:
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
@@ -496,6 +501,12 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
this.mClientExtensions = ReadExtensions(buf);
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mClientExtensions);
ContextAdmin.SetClientVersion(client_version);
diff --git a/crypto/src/crypto/tls/TlsSrpGroupVerifier.cs b/crypto/src/crypto/tls/TlsSrpGroupVerifier.cs
new file mode 100644
index 000000000..185f2f50a
--- /dev/null
+++ b/crypto/src/crypto/tls/TlsSrpGroupVerifier.cs
@@ -0,0 +1,17 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Parameters;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public interface TlsSrpGroupVerifier
+ {
+ /**
+ * Check whether the given SRP group parameters are acceptable for use.
+ *
+ * @param group the {@link SRP6GroupParameters} to check
+ * @return true if (and only if) the specified group parameters are acceptable
+ */
+ bool Accept(Srp6GroupParameters group);
+ }
+}
diff --git a/crypto/src/crypto/tls/TlsSrpIdentityManager.cs b/crypto/src/crypto/tls/TlsSrpIdentityManager.cs
new file mode 100644
index 000000000..080a0dc16
--- /dev/null
+++ b/crypto/src/crypto/tls/TlsSrpIdentityManager.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public interface TlsSrpIdentityManager
+ {
+ /**
+ * Lookup the {@link TlsSRPLoginParameters} corresponding to the specified identity.
+ *
+ * NOTE: To avoid "identity probing", unknown identities SHOULD be handled as recommended in RFC
+ * 5054 2.5.1.3. {@link SimulatedTlsSRPIdentityManager} is provided for this purpose.
+ *
+ * @param identity
+ * the SRP identity sent by the connecting client
+ * @return the {@link TlsSRPLoginParameters} for the specified identity, or else 'simulated'
+ * parameters if the identity is not recognized. A null value is also allowed, but not
+ * recommended.
+ */
+ TlsSrpLoginParameters GetLoginParameters(byte[] identity);
+ }
+}
diff --git a/crypto/src/crypto/tls/TlsSrpKeyExchange.cs b/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
index f42f7456d..ce8e4834a 100644
--- a/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
@@ -16,36 +16,64 @@ namespace Org.BouncyCastle.Crypto.Tls
public class TlsSrpKeyExchange
: AbstractTlsKeyExchange
{
+ protected static TlsSigner CreateSigner(int keyExchange)
+ {
+ switch (keyExchange)
+ {
+ case KeyExchangeAlgorithm.SRP:
+ return null;
+ case KeyExchangeAlgorithm.SRP_RSA:
+ return new TlsRsaSigner();
+ case KeyExchangeAlgorithm.SRP_DSS:
+ return new TlsDssSigner();
+ default:
+ throw new ArgumentException("unsupported key exchange algorithm");
+ }
+ }
+
protected TlsSigner mTlsSigner;
+ protected TlsSrpGroupVerifier mGroupVerifier;
protected byte[] mIdentity;
protected byte[] mPassword;
protected AsymmetricKeyParameter mServerPublicKey = null;
- protected byte[] mS = null;
- protected BigInteger mB = null;
- protected Srp6Client mSrpClient = new Srp6Client();
+ protected Srp6GroupParameters mSrpGroup = null;
+ protected Srp6Client mSrpClient = null;
+ protected Srp6Server mSrpServer = null;
+ protected BigInteger mSrpPeerCredentials = null;
+ protected BigInteger mSrpVerifier = null;
+ protected byte[] mSrpSalt = null;
+
+ protected TlsSignerCredentials mServerCredentials = null;
+ [Obsolete("Use constructor taking an explicit 'groupVerifier' argument")]
public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity, byte[] password)
- : base(keyExchange, supportedSignatureAlgorithms)
+ : this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsSrpGroupVerifier(), identity, password)
{
- switch (keyExchange)
- {
- case KeyExchangeAlgorithm.SRP:
- this.mTlsSigner = null;
- break;
- case KeyExchangeAlgorithm.SRP_RSA:
- this.mTlsSigner = new TlsRsaSigner();
- break;
- case KeyExchangeAlgorithm.SRP_DSS:
- this.mTlsSigner = new TlsDssSigner();
- break;
- default:
- throw new InvalidOperationException("unsupported key exchange algorithm");
- }
+ }
+ public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsSrpGroupVerifier groupVerifier,
+ byte[] identity, byte[] password)
+ : base(keyExchange, supportedSignatureAlgorithms)
+ {
+ this.mTlsSigner = CreateSigner(keyExchange);
+ this.mGroupVerifier = groupVerifier;
this.mIdentity = identity;
this.mPassword = password;
+ this.mSrpClient = new Srp6Client();
+ }
+
+ public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity,
+ TlsSrpLoginParameters loginParameters)
+ : base(keyExchange, supportedSignatureAlgorithms)
+ {
+ this.mTlsSigner = CreateSigner(keyExchange);
+ this.mIdentity = identity;
+ this.mSrpServer = new Srp6Server();
+ this.mSrpGroup = loginParameters.Group;
+ this.mSrpVerifier = loginParameters.Verifier;
+ this.mSrpSalt = loginParameters.Salt;
}
public override void Init(TlsContext context)
@@ -91,14 +119,62 @@ namespace Org.BouncyCastle.Crypto.Tls
base.ProcessServerCertificate(serverCertificate);
}
+ public override void ProcessServerCredentials(TlsCredentials serverCredentials)
+ {
+ if ((mKeyExchange == KeyExchangeAlgorithm.SRP) || !(serverCredentials is TlsSignerCredentials))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ ProcessServerCertificate(serverCredentials.Certificate);
+
+ this.mServerCredentials = (TlsSignerCredentials)serverCredentials;
+ }
+
public override bool RequiresServerKeyExchange
{
get { return true; }
}
+ public override byte[] GenerateServerKeyExchange()
+ {
+ mSrpServer.Init(mSrpGroup, mSrpVerifier, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom);
+ BigInteger B = mSrpServer.GenerateServerCredentials();
+
+ ServerSrpParams srpParams = new ServerSrpParams(mSrpGroup.N, mSrpGroup.G, mSrpSalt, B);
+
+ DigestInputBuffer buf = new DigestInputBuffer();
+
+ srpParams.Encode(buf);
+
+ if (mServerCredentials != null)
+ {
+ /*
+ * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
+ */
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(
+ mContext, mServerCredentials);
+
+ IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm);
+
+ SecurityParameters securityParameters = mContext.SecurityParameters;
+ d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
+ d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
+ buf.UpdateDigest(d);
+
+ byte[] hash = new byte[d.GetDigestSize()];
+ d.DoFinal(hash, 0);
+
+ byte[] signature = mServerCredentials.GenerateCertificateSignature(hash);
+
+ DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);
+ signed_params.Encode(buf);
+ }
+
+ return buf.ToArray();
+ }
+
public override void ProcessServerKeyExchange(Stream input)
{
- SecurityParameters securityParameters = context.SecurityParameters;
+ SecurityParameters securityParameters = mContext.SecurityParameters;
SignerInputBuffer buf = null;
Stream teeIn = input;
@@ -109,14 +185,11 @@ namespace Org.BouncyCastle.Crypto.Tls
teeIn = new TeeInputStream(input, buf);
}
- byte[] NBytes = TlsUtilities.ReadOpaque16(teeIn);
- byte[] gBytes = TlsUtilities.ReadOpaque16(teeIn);
- byte[] sBytes = TlsUtilities.ReadOpaque8(teeIn);
- byte[] BBytes = TlsUtilities.ReadOpaque16(teeIn);
+ ServerSrpParams srpParams = ServerSrpParams.Parse(teeIn);
if (buf != null)
{
- DigitallySigned signed_params = DigitallySigned.Parse(context, input);
+ DigitallySigned signed_params = DigitallySigned.Parse(mContext, input);
ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
buf.UpdateSigner(signer);
@@ -124,13 +197,12 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.decrypt_error);
}
- BigInteger N = new BigInteger(1, NBytes);
- BigInteger g = new BigInteger(1, gBytes);
+ this.mSrpGroup = new Srp6GroupParameters(srpParams.N, srpParams.G);
- // TODO Validate group parameters (see RFC 5054)
- // throw new TlsFatalAlert(AlertDescription.insufficient_security);
+ if (!mGroupVerifier.Accept(mSrpGroup))
+ throw new TlsFatalAlert(AlertDescription.insufficient_security);
- this.mS = sBytes;
+ this.mSrpSalt = srpParams.S;
/*
* RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if
@@ -138,14 +210,14 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
try
{
- this.mB = Srp6Utilities.ValidatePublicValue(N, new BigInteger(1, BBytes));
+ this.mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, srpParams.B);
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
- this.mSrpClient.Init(N, g, TlsUtilities.CreateHash(HashAlgorithm.sha1), context.SecureRandom);
+ this.mSrpClient.Init(mSrpGroup, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom);
}
public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
@@ -160,16 +232,40 @@ namespace Org.BouncyCastle.Crypto.Tls
public override void GenerateClientKeyExchange(Stream output)
{
- BigInteger A = mSrpClient.GenerateClientCredentials(mS, this.mIdentity, this.mPassword);
- TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(A), output);
+ BigInteger A = mSrpClient.GenerateClientCredentials(mSrpSalt, mIdentity, mPassword);
+ TlsSrpUtilities.WriteSrpParameter(A, output);
+
+ mContext.SecurityParameters.srpIdentity = Arrays.Clone(mIdentity);
+ }
+
+ public override void ProcessClientKeyExchange(Stream input)
+ {
+ /*
+ * RFC 5054 2.5.4: The server MUST abort the handshake with an "illegal_parameter" alert if
+ * A % N = 0.
+ */
+ try
+ {
+ this.mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, TlsSrpUtilities.ReadSrpParameter(input));
+ }
+ catch (CryptoException e)
+ {
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
+ }
+
+ mContext.SecurityParameters.srpIdentity = Arrays.Clone(mIdentity);
}
public override byte[] GeneratePremasterSecret()
{
try
{
+ BigInteger S = mSrpServer != null
+ ? mSrpServer.CalculateSecret(mSrpPeerCredentials)
+ : mSrpClient.CalculateSecret(mSrpPeerCredentials);
+
// TODO Check if this needs to be a fixed size
- return BigIntegers.AsUnsignedByteArray(mSrpClient.CalculateSecret(mB));
+ return BigIntegers.AsUnsignedByteArray(S);
}
catch (CryptoException e)
{
diff --git a/crypto/src/crypto/tls/TlsSrpLoginParameters.cs b/crypto/src/crypto/tls/TlsSrpLoginParameters.cs
new file mode 100644
index 000000000..5ae4641f6
--- /dev/null
+++ b/crypto/src/crypto/tls/TlsSrpLoginParameters.cs
@@ -0,0 +1,36 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public class TlsSrpLoginParameters
+ {
+ protected readonly Srp6GroupParameters mGroup;
+ protected readonly BigInteger mVerifier;
+ protected readonly byte[] mSalt;
+
+ public TlsSrpLoginParameters(Srp6GroupParameters group, BigInteger verifier, byte[] salt)
+ {
+ this.mGroup = group;
+ this.mVerifier = verifier;
+ this.mSalt = salt;
+ }
+
+ public virtual Srp6GroupParameters Group
+ {
+ get { return mGroup; }
+ }
+
+ public virtual byte[] Salt
+ {
+ get { return mSalt; }
+ }
+
+ public virtual BigInteger Verifier
+ {
+ get { return mVerifier; }
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/TlsSrpUtilities.cs b/crypto/src/crypto/tls/TlsSrpUtilities.cs
index bbb6ac280..873189dc6 100644
--- a/crypto/src/crypto/tls/TlsSrpUtilities.cs
+++ b/crypto/src/crypto/tls/TlsSrpUtilities.cs
@@ -2,6 +2,9 @@
using System.Collections;
using System.IO;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
namespace Org.BouncyCastle.Crypto.Tls
{
public abstract class TlsSrpUtilities
@@ -37,5 +40,35 @@ namespace Org.BouncyCastle.Crypto.Tls
return identity;
}
+
+ public static BigInteger ReadSrpParameter(Stream input)
+ {
+ return new BigInteger(1, TlsUtilities.ReadOpaque16(input));
+ }
+
+ public static void WriteSrpParameter(BigInteger x, Stream output)
+ {
+ TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output);
+ }
+
+ public static bool IsSrpCipherSuite(int cipherSuite)
+ {
+ switch (cipherSuite)
+ {
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
+ return true;
+
+ default:
+ return false;
+ }
+ }
}
}
diff --git a/crypto/src/crypto/tls/TlsUtilities.cs b/crypto/src/crypto/tls/TlsUtilities.cs
index 485ecb760..a8c8a2b28 100644
--- a/crypto/src/crypto/tls/TlsUtilities.cs
+++ b/crypto/src/crypto/tls/TlsUtilities.cs
@@ -21,6 +21,9 @@ namespace Org.BouncyCastle.Crypto.Tls
public abstract class TlsUtilities
{
public static readonly byte[] EmptyBytes = new byte[0];
+ public static readonly short[] EmptyShorts = new short[0];
+ public static readonly int[] EmptyInts = new int[0];
+ public static readonly long[] EmptyLongs = new long[0];
public static void CheckUint8(int i)
{
@@ -589,6 +592,37 @@ namespace Org.BouncyCastle.Crypto.Tls
return extensions == null ? null : (byte[])extensions[extensionType];
}
+ public static IList GetDefaultSupportedSignatureAlgorithms()
+ {
+ byte[] hashAlgorithms = new byte[]{ HashAlgorithm.sha1, HashAlgorithm.sha224, HashAlgorithm.sha256,
+ HashAlgorithm.sha384, HashAlgorithm.sha512 };
+ byte[] signatureAlgorithms = new byte[]{ SignatureAlgorithm.rsa, SignatureAlgorithm.dsa,
+ SignatureAlgorithm.ecdsa };
+
+ IList result = Platform.CreateArrayList();
+ for (int i = 0; i < signatureAlgorithms.Length; ++i)
+ {
+ for (int j = 0; j < hashAlgorithms.Length; ++j)
+ {
+ result.Add(new SignatureAndHashAlgorithm(hashAlgorithms[j], signatureAlgorithms[i]));
+ }
+ }
+ return result;
+ }
+
+ public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(TlsContext context,
+ TlsSignerCredentials signerCredentials)
+ {
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm = null;
+ if (IsTlsV12(context))
+ {
+ signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm;
+ if (signatureAndHashAlgorithm == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ return signatureAndHashAlgorithm;
+ }
+
public static bool HasExpectedEmptyExtensionData(IDictionary extensions, int extensionType,
byte alertDescription)
{
@@ -941,6 +975,13 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
+ public static IDigest CreateHash(SignatureAndHashAlgorithm signatureAndHashAlgorithm)
+ {
+ return signatureAndHashAlgorithm == null
+ ? new CombinedHash()
+ : CreateHash(signatureAndHashAlgorithm.Hash);
+ }
+
public static IDigest CloneHash(byte hashAlgorithm, IDigest hash)
{
switch (hashAlgorithm)
@@ -1490,6 +1531,528 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
+ public static int GetKeyExchangeAlgorithm(int ciphersuite)
+ {
+ switch (ciphersuite)
+ {
+ case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
+ return KeyExchangeAlgorithm.DH_DSS;
+
+ case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
+ return KeyExchangeAlgorithm.DH_RSA;
+
+ case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
+ return KeyExchangeAlgorithm.DHE_DSS;
+
+ case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
+ return KeyExchangeAlgorithm.DHE_PSK;
+
+ case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
+ return KeyExchangeAlgorithm.DHE_RSA;
+
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+ return KeyExchangeAlgorithm.ECDH_ECDSA;
+
+ case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
+ return KeyExchangeAlgorithm.ECDH_RSA;
+
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
+ return KeyExchangeAlgorithm.ECDHE_ECDSA;
+
+ case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
+ return KeyExchangeAlgorithm.ECDHE_PSK;
+
+ case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
+ return KeyExchangeAlgorithm.ECDHE_RSA;
+
+ case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
+ return KeyExchangeAlgorithm.PSK;
+
+ case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_NULL_MD5:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
+ return KeyExchangeAlgorithm.RSA;
+
+ case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
+ return KeyExchangeAlgorithm.RSA_PSK;
+
+ case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
+ return KeyExchangeAlgorithm.SRP;
+
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
+ return KeyExchangeAlgorithm.SRP_DSS;
+
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
+ return KeyExchangeAlgorithm.SRP_RSA;
+
+ default:
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
+ public static int GetMacAlgorithm(int ciphersuite)
+ {
+ switch (ciphersuite)
+ {
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ return MacAlgorithm.cls_null;
+
+ case CipherSuite.TLS_RSA_WITH_NULL_MD5:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
+ return MacAlgorithm.hmac_md5;
+
+ case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
+ return MacAlgorithm.hmac_sha1;
+
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
+ return MacAlgorithm.hmac_sha256;
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
+ return MacAlgorithm.hmac_sha384;
+
+ default:
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
public static ProtocolVersion GetMinimumVersion(int ciphersuite)
{
switch (ciphersuite)
diff --git a/crypto/src/pkix/PkixParameters.cs b/crypto/src/pkix/PkixParameters.cs
index 6df1b646f..47d3b5e37 100644
--- a/crypto/src/pkix/PkixParameters.cs
+++ b/crypto/src/pkix/PkixParameters.cs
@@ -745,7 +745,7 @@ namespace Org.BouncyCastle.Pkix
}
/**
- * Returns the neccessary attributes which must be contained in an attribute
+ * Returns the necessary attributes which must be contained in an attribute
* certificate.
* <p>
* The returned <code>ISet</code> is immutable and contains
@@ -760,7 +760,7 @@ namespace Org.BouncyCastle.Pkix
}
/**
- * Sets the neccessary which must be contained in an attribute certificate.
+ * Sets the necessary which must be contained in an attribute certificate.
* <p>
* The <code>ISet</code> must contain <code>String</code>s with the
* OIDs.
diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs
index c1aea50d6..bd1515147 100644
--- a/crypto/src/security/SignerUtilities.cs
+++ b/crypto/src/security/SignerUtilities.cs
@@ -534,6 +534,26 @@ namespace Org.BouncyCastle.Security
return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true);
}
+ if (mechanism.EndsWith("/X9.31"))
+ {
+ string x931 = mechanism.Substring(0, mechanism.Length - "/X9.31".Length);
+ int withPos = x931.IndexOf("WITH");
+ if (withPos > 0)
+ {
+ int endPos = withPos + "WITH".Length;
+
+ string digestName = x931.Substring(0, withPos);
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+
+ string cipherName = x931.Substring(endPos, x931.Length - endPos);
+ if (cipherName.Equals("RSA"))
+ {
+ IAsymmetricBlockCipher cipher = new RsaBlindedEngine();
+ return new X931Signer(cipher, digest);
+ }
+ }
+ }
+
throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
}
|