diff --git a/crypto/src/crypto/tls/AlertDescription.cs b/crypto/src/crypto/tls/AlertDescription.cs
index e1229a4a3..e09da6cab 100644
--- a/crypto/src/crypto/tls/AlertDescription.cs
+++ b/crypto/src/crypto/tls/AlertDescription.cs
@@ -1,47 +1,217 @@
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// RFC 2246 7.2
- /// </summary>
- public enum AlertDescription : byte
- {
- close_notify = 0,
- unexpected_message = 10,
- bad_record_mac = 20,
- decryption_failed = 21,
- record_overflow = 22,
- decompression_failure = 30,
- handshake_failure = 40,
- /* 41 is not defined, for historical reasons */
- bad_certificate = 42,
- unsupported_certificate = 43,
- certificate_revoked = 44,
- certificate_expired = 45,
- certificate_unknown = 46,
- illegal_parameter = 47,
- unknown_ca = 48,
- access_denied = 49,
- decode_error = 50,
- decrypt_error = 51,
- export_restriction = 60,
- protocol_version = 70,
- insufficient_security = 71,
- internal_error = 80,
- user_canceled = 90,
- no_renegotiation = 100,
-
- /*
- * RFC 3546
- */
- unsupported_extension = 110,
- certificate_unobtainable = 111,
- unrecognized_name = 112,
- bad_certificate_status_response = 113,
- bad_certificate_hash_value = 114,
-
- /*
- * RFC 4279
- */
- unknown_psk_identity = 115,
- }
+ /// <summary>
+ /// RFC 5246 7.2
+ /// </summary>
+ public abstract class AlertDescription
+ {
+ /**
+ * This message notifies the recipient that the sender will not send any more messages on this
+ * connection. Note that as of TLS 1.1, failure to properly close a connection no longer
+ * requires that a session not be resumed. This is a change from TLS 1.0 ("The session becomes
+ * unresumable if any connection is terminated without proper close_notify messages with level
+ * equal to warning.") to conform with widespread implementation practice.
+ */
+ public const byte close_notify = 0;
+
+ /**
+ * An inappropriate message was received. This alert is always fatal and should never be
+ * observed in communication between proper implementations.
+ */
+ public const byte unexpected_message = 10;
+
+ /**
+ * This alert is returned if a record is received with an incorrect MAC. This alert also MUST be
+ * returned if an alert is sent because a TLSCiphertext decrypted in an invalid way: either it
+ * wasn't an even multiple of the block length, or its padding values, when checked, weren't
+ * correct. This message is always fatal and should never be observed in communication between
+ * proper implementations (except when messages were corrupted in the network).
+ */
+ public const byte bad_record_mac = 20;
+
+ /**
+ * This alert was used in some earlier versions of TLS, and may have permitted certain attacks
+ * against the CBC mode [CBCATT]. It MUST NOT be sent by compliant implementations.
+ */
+ public const byte decryption_failed = 21;
+
+ /**
+ * A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record
+ * decrypted to a TLSCompressed record with more than 2^14+1024 bytes. This message is always
+ * fatal and should never be observed in communication between proper implementations (except
+ * when messages were corrupted in the network).
+ */
+ public const byte record_overflow = 22;
+
+ /**
+ * The decompression function received improper input (e.g., data that would expand to excessive
+ * length). This message is always fatal and should never be observed in communication between
+ * proper implementations.
+ */
+ public const byte decompression_failure = 30;
+
+ /**
+ * Reception of a handshake_failure alert message indicates that the sender was unable to
+ * negotiate an acceptable set of security parameters given the options available. This is a
+ * fatal error.
+ */
+ public const byte handshake_failure = 40;
+
+ /**
+ * This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant
+ * implementations.
+ */
+ public const byte no_certificate = 41;
+
+ /**
+ * A certificate was corrupt, contained signatures that did not verify correctly, etc.
+ */
+ public const byte bad_certificate = 42;
+
+ /**
+ * A certificate was of an unsupported type.
+ */
+ public const byte unsupported_certificate = 43;
+
+ /**
+ * A certificate was revoked by its signer.
+ */
+ public const byte certificate_revoked = 44;
+
+ /**
+ * A certificate has expired or is not currently valid.
+ */
+ public const byte certificate_expired = 45;
+
+ /**
+ * Some other (unspecified) issue arose in processing the certificate, rendering it
+ * unacceptable.
+ */
+ public const byte certificate_unknown = 46;
+
+ /**
+ * A field in the handshake was out of range or inconsistent with other fields. This message is
+ * always fatal.
+ */
+ public const byte illegal_parameter = 47;
+
+ /**
+ * A valid certificate chain or partial chain was received, but the certificate was not accepted
+ * because the CA certificate could not be located or couldn't be matched with a known, trusted
+ * CA. This message is always fatal.
+ */
+ public const byte unknown_ca = 48;
+
+ /**
+ * A valid certificate was received, but when access control was applied, the sender decided not
+ * to proceed with negotiation. This message is always fatal.
+ */
+ public const byte access_denied = 49;
+
+ /**
+ * A message could not be decoded because some field was out of the specified range or the
+ * length of the message was incorrect. This message is always fatal and should never be
+ * observed in communication between proper implementations (except when messages were corrupted
+ * in the network).
+ */
+ public const byte decode_error = 50;
+
+ /**
+ * A handshake cryptographic operation failed, including being unable to correctly verify a
+ * signature or validate a Finished message. This message is always fatal.
+ */
+ public const byte decrypt_error = 51;
+
+ /**
+ * This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant
+ * implementations.
+ */
+ public const byte export_restriction = 60;
+
+ /**
+ * The protocol version the client has attempted to negotiate is recognized but not supported.
+ * (For example, old protocol versions might be avoided for security reasons.) This message is
+ * always fatal.
+ */
+ public const byte protocol_version = 70;
+
+ /**
+ * Returned instead of handshake_failure when a negotiation has failed specifically because the
+ * server requires ciphers more secure than those supported by the client. This message is
+ * always fatal.
+ */
+ public const byte insufficient_security = 71;
+
+ /**
+ * An internal error unrelated to the peer or the correctness of the protocol (such as a memory
+ * allocation failure) makes it impossible to continue. This message is always fatal.
+ */
+ public const byte internal_error = 80;
+
+ /**
+ * This handshake is being canceled for some reason unrelated to a protocol failure. If the user
+ * cancels an operation after the handshake is complete, just closing the connection by sending
+ * a close_notify is more appropriate. This alert should be followed by a close_notify. This
+ * message is generally a warning.
+ */
+ public const byte user_canceled = 90;
+
+ /**
+ * Sent by the client in response to a hello request or by the server in response to a client
+ * hello after initial handshaking. Either of these would normally lead to renegotiation; when
+ * that is not appropriate, the recipient should respond with this alert. At that point, the
+ * original requester can decide whether to proceed with the connection. One case where this
+ * would be appropriate is where a server has spawned a process to satisfy a request; the
+ * process might receive security parameters (key length, authentication, etc.) at startup, and
+ * it might be difficult to communicate changes to these parameters after that point. This
+ * message is always a warning.
+ */
+ public const byte no_renegotiation = 100;
+
+ /**
+ * Sent by clients that receive an extended server hello containing an extension that they did
+ * not put in the corresponding client hello. This message is always fatal.
+ */
+ public const byte unsupported_extension = 110;
+
+ /*
+ * RFC 3546
+ */
+
+ /**
+ * This alert is sent by servers who are unable to retrieve a certificate chain from the URL
+ * supplied by the client (see Section 3.3). This message MAY be fatal - for example if client
+ * authentication is required by the server for the handshake to continue and the server is
+ * unable to retrieve the certificate chain, it may send a fatal alert.
+ */
+ public const byte certificate_unobtainable = 111;
+
+ /**
+ * This alert is sent by servers that receive a server_name extension request, but do not
+ * recognize the server name. This message MAY be fatal.
+ */
+ public const byte unrecognized_name = 112;
+
+ /**
+ * This alert is sent by clients that receive an invalid certificate status response (see
+ * Section 3.6). This message is always fatal.
+ */
+ public const byte bad_certificate_status_response = 113;
+
+ /**
+ * This alert is sent by servers when a certificate hash does not match a client provided
+ * certificate_hash. This message is always fatal.
+ */
+ public const byte bad_certificate_hash_value = 114;
+
+ /*
+ * RFC 4279
+ */
+
+ /**
+ * If the server does not recognize the PSK identity, it MAY respond with an
+ * "unknown_psk_identity" alert message.
+ */
+ public const byte unknown_psk_identity = 115;
+ }
}
diff --git a/crypto/src/crypto/tls/AlertLevel.cs b/crypto/src/crypto/tls/AlertLevel.cs
index afb04308b..d77251dfb 100644
--- a/crypto/src/crypto/tls/AlertLevel.cs
+++ b/crypto/src/crypto/tls/AlertLevel.cs
@@ -1,11 +1,11 @@
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// RFC 2246 7.2
- /// </summary>
- public enum AlertLevel : byte
- {
- warning = 1,
- fatal = 2,
- }
+ /// <summary>
+ /// RFC 5246 7.2
+ /// </summary>
+ public abstract class AlertLevel
+ {
+ public const byte warning = 1;
+ public const byte fatal = 2;
+ }
}
diff --git a/crypto/src/crypto/tls/ByteQueue.cs b/crypto/src/crypto/tls/ByteQueue.cs
index c3ce91402..f9398bbaf 100644
--- a/crypto/src/crypto/tls/ByteQueue.cs
+++ b/crypto/src/crypto/tls/ByteQueue.cs
@@ -68,13 +68,13 @@ namespace Org.BouncyCastle.Crypto.Tls
int len,
int skip)
{
- if ((available - skip) < len)
+ if ((buf.Length - offset) < len)
{
- throw new TlsException("Not enough data to read");
+ throw new ArgumentException("Buffer size of " + buf.Length + " is too small for a read of " + len + " bytes");
}
- if ((buf.Length - offset) < len)
+ if ((available - skip) < len)
{
- throw new TlsException("Buffer size of " + buf.Length + " is too small for a read of " + len + " bytes");
+ throw new InvalidOperationException("Not enough data to read");
}
Array.Copy(databuf, skipped + skip, buf, offset, len);
}
@@ -115,7 +115,7 @@ namespace Org.BouncyCastle.Crypto.Tls
{
if (i > available)
{
- throw new TlsException("Cannot remove " + i + " bytes, only got " + available);
+ throw new InvalidOperationException("Cannot remove " + i + " bytes, only got " + available);
}
/*
diff --git a/crypto/src/crypto/tls/Certificate.cs b/crypto/src/crypto/tls/Certificate.cs
index e4df041e2..95050abcd 100644
--- a/crypto/src/crypto/tls/Certificate.cs
+++ b/crypto/src/crypto/tls/Certificate.cs
@@ -8,104 +8,136 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls
{
- /**
- * A representation for a certificate chain.
- */
- public class Certificate
- {
- public static readonly Certificate EmptyChain = new Certificate(new X509CertificateStructure[0]);
-
- /**
- * The certificates.
- */
- internal X509CertificateStructure[] certs;
-
- /**
- * Parse the ServerCertificate message.
- *
- * @param inStr The stream where to parse from.
- * @return A Certificate object with the certs, the server has sended.
- * @throws IOException If something goes wrong during parsing.
- */
- internal static Certificate Parse(
- Stream inStr)
- {
- int left = TlsUtilities.ReadUint24(inStr);
- if (left == 0)
- {
- return EmptyChain;
- }
- IList tmp = Platform.CreateArrayList();
- while (left > 0)
- {
- int size = TlsUtilities.ReadUint24(inStr);
- left -= 3 + size;
- byte[] buf = new byte[size];
- TlsUtilities.ReadFully(buf, inStr);
- MemoryStream bis = new MemoryStream(buf, false);
- Asn1Object o = Asn1Object.FromStream(bis);
- tmp.Add(X509CertificateStructure.GetInstance(o));
- if (bis.Position < bis.Length)
- {
- throw new ArgumentException("Sorry, there is garbage data left after the certificate");
- }
- }
- X509CertificateStructure[] certs = new X509CertificateStructure[tmp.Count];
- for (int i = 0; i < tmp.Count; ++i)
+ /**
+ * Parsing and encoding of a <i>Certificate</i> struct from RFC 4346.
+ * <p/>
+ * <pre>
+ * opaque ASN.1Cert<2^24-1>;
+ *
+ * struct {
+ * ASN.1Cert certificate_list<0..2^24-1>;
+ * } Certificate;
+ * </pre>
+ *
+ * @see org.bouncycastle.asn1.x509.Certificate
+ */
+ public class Certificate
+ {
+ public static readonly Certificate EmptyChain = new Certificate(new X509CertificateStructure[0]);
+
+ /**
+ * The certificates.
+ */
+ protected readonly X509CertificateStructure[] mCertificateList;
+
+ public Certificate(X509CertificateStructure[] certificateList)
+ {
+ if (certificateList == null)
+ throw new ArgumentNullException("certificateList");
+
+ this.mCertificateList = certificateList;
+ }
+
+ /// <returns>An array which contains the certs, this chain contains.</returns>
+ [Obsolete("Use 'GetCertificateList' instead")]
+ public virtual X509CertificateStructure[] GetCerts()
+ {
+ return GetCertificateList();
+ }
+
+ /**
+ * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate
+ * chain.
+ */
+ public virtual X509CertificateStructure[] GetCertificateList()
+ {
+ return CloneCertificateList();
+ }
+
+ public virtual X509CertificateStructure GetCertificateAt(int index)
+ {
+ return mCertificateList[index];
+ }
+
+ public virtual int Length
+ {
+ get { return mCertificateList.Length; }
+ }
+
+ /**
+ * @return <code>true</code> if this certificate chain contains no certificates, or
+ * <code>false</code> otherwise.
+ */
+ public virtual bool IsEmpty
+ {
+ get { return mCertificateList.Length == 0; }
+ }
+
+ /**
+ * Encode this {@link Certificate} to a {@link Stream}.
+ *
+ * @param output the {@link Stream} to encode to.
+ * @throws IOException
+ */
+ public virtual void Encode(Stream output)
+ {
+ IList derEncodings = Platform.CreateArrayList(mCertificateList.Length);
+
+ int totalLength = 0;
+ foreach (Asn1Encodable asn1Cert in mCertificateList)
+ {
+ byte[] derEncoding = asn1Cert.GetEncoded(Asn1Encodable.Der);
+ derEncodings.Add(derEncoding);
+ totalLength += derEncoding.Length + 3;
+ }
+
+ TlsUtilities.CheckUint24(totalLength);
+ TlsUtilities.WriteUint24(totalLength, output);
+
+ foreach (byte[] derEncoding in derEncodings)
+ {
+ TlsUtilities.WriteOpaque24(derEncoding, output);
+ }
+ }
+
+ /**
+ * Parse a {@link Certificate} from a {@link Stream}.
+ *
+ * @param input the {@link Stream} to parse from.
+ * @return a {@link Certificate} object.
+ * @throws IOException
+ */
+ public static Certificate Parse(Stream input)
+ {
+ int totalLength = TlsUtilities.ReadUint24(input);
+ if (totalLength == 0)
{
- certs[i] = (X509CertificateStructure)tmp[i];
+ return EmptyChain;
}
- return new Certificate(certs);
- }
-
- /**
- * Encodes version of the ClientCertificate message
- *
- * @param outStr stream to write the message to
- * @throws IOException If something goes wrong
- */
- internal void Encode(
- Stream outStr)
- {
- IList encCerts = Platform.CreateArrayList();
- int totalSize = 0;
- foreach (X509CertificateStructure cert in certs)
- {
- byte[] encCert = cert.GetEncoded(Asn1Encodable.Der);
- encCerts.Add(encCert);
- totalSize += encCert.Length + 3;
- }
-
- TlsUtilities.WriteUint24(totalSize, outStr);
-
- foreach (byte[] encCert in encCerts)
- {
- TlsUtilities.WriteOpaque24(encCert, outStr);
- }
- }
-
- /**
- * Private constructor from a cert array.
- *
- * @param certs The certs the chain should contain.
- */
- public Certificate(X509CertificateStructure[] certs)
- {
- if (certs == null)
- throw new ArgumentNullException("certs");
-
- this.certs = certs;
- }
-
- /// <returns>An array which contains the certs, this chain contains.</returns>
- public X509CertificateStructure[] GetCerts()
- {
- return (X509CertificateStructure[]) certs.Clone();
- }
-
- public bool IsEmpty
- {
- get { return certs.Length == 0; }
- }
- }
+
+ byte[] certListData = TlsUtilities.ReadFully(totalLength, input);
+
+ MemoryStream buf = new MemoryStream(certListData, false);
+
+ IList certificate_list = Platform.CreateArrayList();
+ while (buf.Position < buf.Length)
+ {
+ byte[] derEncoding = TlsUtilities.ReadOpaque24(buf);
+ Asn1Object asn1Cert = TlsUtilities.ReadDerObject(derEncoding);
+ certificate_list.Add(X509CertificateStructure.GetInstance(asn1Cert));
+ }
+
+ X509CertificateStructure[] certificateList = new X509CertificateStructure[certificate_list.Count];
+ for (int i = 0; i < certificate_list.Count; ++i)
+ {
+ certificateList[i] = (X509CertificateStructure)certificate_list[i];
+ }
+ return new Certificate(certificateList);
+ }
+
+ protected virtual X509CertificateStructure[] CloneCertificateList()
+ {
+ return (X509CertificateStructure[])mCertificateList.Clone();
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/CertificateRequest.cs b/crypto/src/crypto/tls/CertificateRequest.cs
index 49d8ba6fb..db72a0fc1 100644
--- a/crypto/src/crypto/tls/CertificateRequest.cs
+++ b/crypto/src/crypto/tls/CertificateRequest.cs
@@ -1,28 +1,158 @@
using System;
using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls
{
- public class CertificateRequest
- {
- private ClientCertificateType[] certificateTypes;
- private IList certificateAuthorities;
-
- public CertificateRequest(ClientCertificateType[] certificateTypes, IList certificateAuthorities)
- {
- this.certificateTypes = certificateTypes;
- this.certificateAuthorities = certificateAuthorities;
- }
-
- public ClientCertificateType[] CertificateTypes
- {
- get { return certificateTypes; }
- }
-
- /// <returns>A <see cref="IList"/> of X509Name</returns>
- public IList CertificateAuthorities
- {
- get { return certificateAuthorities; }
- }
- }
-}
\ No newline at end of file
+ /**
+ * Parsing and encoding of a <i>CertificateRequest</i> struct from RFC 4346.
+ * <p/>
+ * <pre>
+ * struct {
+ * ClientCertificateType certificate_types<1..2^8-1>;
+ * DistinguishedName certificate_authorities<3..2^16-1>;
+ * } CertificateRequest;
+ * </pre>
+ *
+ * @see ClientCertificateType
+ * @see X509Name
+ */
+ public class CertificateRequest
+ {
+ protected readonly byte[] mCertificateTypes;
+ protected readonly IList mSupportedSignatureAlgorithms;
+ protected readonly IList mCertificateAuthorities;
+
+ /**
+ * @param certificateTypes see {@link ClientCertificateType} for valid constants.
+ * @param certificateAuthorities an {@link IList} of {@link X509Name}.
+ */
+ public CertificateRequest(byte[] certificateTypes, IList supportedSignatureAlgorithms,
+ IList certificateAuthorities)
+ {
+ this.mCertificateTypes = certificateTypes;
+ this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms;
+ this.mCertificateAuthorities = certificateAuthorities;
+ }
+
+ /**
+ * @return an array of certificate types
+ * @see {@link ClientCertificateType}
+ */
+ public virtual byte[] CertificateTypes
+ {
+ get { return mCertificateTypes; }
+ }
+
+ /**
+ * @return an {@link IList} of {@link SignatureAndHashAlgorithm} (or null before TLS 1.2).
+ */
+ public virtual IList SupportedSignatureAlgorithms
+ {
+ get { return mSupportedSignatureAlgorithms; }
+ }
+
+ /**
+ * @return an {@link IList} of {@link X509Name}
+ */
+ public virtual IList CertificateAuthorities
+ {
+ get { return mCertificateAuthorities; }
+ }
+
+ /**
+ * Encode this {@link CertificateRequest} to a {@link Stream}.
+ *
+ * @param output the {@link Stream} to encode to.
+ * @throws IOException
+ */
+ public virtual void Encode(Stream output)
+ {
+ if (mCertificateTypes == null || mCertificateTypes.Length == 0)
+ {
+ TlsUtilities.WriteUint8(0, output);
+ }
+ else
+ {
+ TlsUtilities.WriteUint8ArrayWithUint8Length(mCertificateTypes, output);
+ }
+
+ if (mSupportedSignatureAlgorithms != null)
+ {
+ // TODO Check whether SignatureAlgorithm.anonymous is allowed here
+ TlsUtilities.EncodeSupportedSignatureAlgorithms(mSupportedSignatureAlgorithms, false, output);
+ }
+
+ if (mCertificateAuthorities == null || mCertificateAuthorities.Count < 1)
+ {
+ TlsUtilities.WriteUint16(0, output);
+ }
+ else
+ {
+ IList derEncodings = Platform.CreateArrayList(mCertificateAuthorities.Count);
+
+ int totalLength = 0;
+ foreach (Asn1Encodable certificateAuthority in mCertificateAuthorities)
+ {
+ byte[] derEncoding = certificateAuthority.GetEncoded(Asn1Encodable.Der);
+ derEncodings.Add(derEncoding);
+ totalLength += derEncoding.Length;
+ }
+
+ TlsUtilities.CheckUint16(totalLength);
+ TlsUtilities.WriteUint16(totalLength, output);
+
+ foreach (byte[] derEncoding in derEncodings)
+ {
+ output.Write(derEncoding, 0, derEncoding.Length);
+ }
+ }
+ }
+
+ /**
+ * Parse a {@link CertificateRequest} from a {@link Stream}.
+ *
+ * @param context
+ * the {@link TlsContext} of the current connection.
+ * @param input
+ * the {@link Stream} to parse from.
+ * @return a {@link CertificateRequest} object.
+ * @throws IOException
+ */
+ public static CertificateRequest Parse(//TlsContext context,
+ Stream input)
+ {
+ int numTypes = TlsUtilities.ReadUint8(input);
+ byte[] certificateTypes = new byte[numTypes];
+ for (int i = 0; i < numTypes; ++i)
+ {
+ certificateTypes[i] = TlsUtilities.ReadUint8(input);
+ }
+
+ // TODO Add TLS 1.2 support here
+ IList supportedSignatureAlgorithms = null;
+ //if (TlsUtilities.IsTLSv12(context))
+ //{
+ // // TODO Check whether SignatureAlgorithm.anonymous is allowed here
+ // supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(false, input);
+ //}
+
+ IList certificateAuthorities = Platform.CreateArrayList();
+ byte[] certAuthData = TlsUtilities.ReadOpaque16(input);
+ MemoryStream bis = new MemoryStream(certAuthData, false);
+ while (bis.Position < bis.Length)
+ {
+ byte[] derEncoding = TlsUtilities.ReadOpaque16(bis);
+ Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding);
+ // TODO Switch to X500Name when available
+ certificateAuthorities.Add(X509Name.GetInstance(asn1));
+ }
+
+ return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities);
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/ClientCertificateType.cs b/crypto/src/crypto/tls/ClientCertificateType.cs
index 58f5d4276..a291a46e6 100644
--- a/crypto/src/crypto/tls/ClientCertificateType.cs
+++ b/crypto/src/crypto/tls/ClientCertificateType.cs
@@ -1,20 +1,23 @@
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// RFC 2246 7.4.4
- /// </summary>
- public enum ClientCertificateType : byte
- {
- rsa_sign = 1,
- dss_sign = 2,
- rsa_fixed_dh = 3,
- dss_fixed_dh = 4,
+ public abstract class ClientCertificateType
+ {
+ /*
+ * RFC 4346 7.4.4
+ */
+ public const byte rsa_sign = 1;
+ public const byte dss_sign = 2;
+ public const byte rsa_fixed_dh = 3;
+ public const byte dss_fixed_dh = 4;
+ public const byte rsa_ephemeral_dh_RESERVED = 5;
+ public const byte dss_ephemeral_dh_RESERVED = 6;
+ public const byte fortezza_dms_RESERVED = 20;
- /*
- * RFC 4492 5.5
- */
- ecdsa_sign = 64,
- rsa_fixed_ecdh = 65,
- ecdsa_fixed_ecdh = 66,
- }
-}
\ No newline at end of file
+ /*
+ * RFC 4492 5.5
+ */
+ public const byte ecdsa_sign = 64;
+ public const byte rsa_fixed_ecdh = 65;
+ public const byte ecdsa_fixed_ecdh = 66;
+ }
+}
diff --git a/crypto/src/crypto/tls/CompressionMethod.cs b/crypto/src/crypto/tls/CompressionMethod.cs
index 4a127a63e..e4ee9666f 100644
--- a/crypto/src/crypto/tls/CompressionMethod.cs
+++ b/crypto/src/crypto/tls/CompressionMethod.cs
@@ -1,20 +1,22 @@
+using System;
+
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// RFC 2246 6.1
- /// </summary>
- public enum CompressionMethod : byte
- {
- NULL = 0,
+ /// <summary>
+ /// RFC 2246 6.1
+ /// </summary>
+ public abstract class CompressionMethod
+ {
+ public const byte NULL = 0;
- /*
- * RFC 3749 2
- */
- DEFLATE = 1
+ /*
+ * RFC 3749 2
+ */
+ public const byte DEFLATE = 1;
- /*
- * Values from 224 decimal (0xE0) through 255 decimal (0xFF)
- * inclusive are reserved for private use.
- */
- }
+ /*
+ * Values from 224 decimal (0xE0) through 255 decimal (0xFF)
+ * inclusive are reserved for private use.
+ */
+ }
}
diff --git a/crypto/src/crypto/tls/DefaultTlsAgreementCredentials.cs b/crypto/src/crypto/tls/DefaultTlsAgreementCredentials.cs
index 130f4c589..2bd2f40bf 100644
--- a/crypto/src/crypto/tls/DefaultTlsAgreementCredentials.cs
+++ b/crypto/src/crypto/tls/DefaultTlsAgreementCredentials.cs
@@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Crypto.Tls
{
throw new ArgumentNullException("clientCertificate");
}
- if (clientCertificate.certs.Length == 0)
+ if (clientCertificate.Length == 0)
{
throw new ArgumentException("cannot be empty", "clientCertificate");
}
diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs
index 9f30a33f4..2e850e350 100644
--- a/crypto/src/crypto/tls/DefaultTlsClient.cs
+++ b/crypto/src/crypto/tls/DefaultTlsClient.cs
@@ -11,125 +11,125 @@ using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Tls
{
- public abstract class DefaultTlsClient
- : TlsClient
- {
- protected TlsCipherFactory cipherFactory;
+ public abstract class DefaultTlsClient
+ : TlsClient
+ {
+ protected TlsCipherFactory cipherFactory;
- protected TlsClientContext context;
+ protected TlsClientContext context;
- protected CompressionMethod selectedCompressionMethod;
+ protected byte selectedCompressionMethod;
protected CipherSuite selectedCipherSuite;
- public DefaultTlsClient()
- : this(new DefaultTlsCipherFactory())
- {
- }
+ public DefaultTlsClient()
+ : this(new DefaultTlsCipherFactory())
+ {
+ }
- public DefaultTlsClient(TlsCipherFactory cipherFactory)
- {
- this.cipherFactory = cipherFactory;
- }
+ public DefaultTlsClient(TlsCipherFactory cipherFactory)
+ {
+ this.cipherFactory = cipherFactory;
+ }
- public virtual void Init(TlsClientContext context)
- {
- this.context = context;
- }
+ public virtual void Init(TlsClientContext context)
+ {
+ this.context = context;
+ }
public virtual CipherSuite[] GetCipherSuites()
- {
- return new CipherSuite[] {
- CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ {
+ return new CipherSuite[] {
+ CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
CipherSuite.TLS_RSA_WITH_RC4_128_SHA,
- };
- }
+ };
+ }
- public virtual CompressionMethod[] GetCompressionMethods()
+ public virtual byte[] GetCompressionMethods()
{
- /*
- * To offer DEFLATE compression, override this method:
- * return new CompressionMethod[] { CompressionMethod.DEFLATE, CompressionMethod.NULL };
- */
+ /*
+ * To offer DEFLATE compression, override this method:
+ * return new byte[] { CompressionMethod.DEFLATE, CompressionMethod.NULL };
+ */
- return new CompressionMethod[] { CompressionMethod.NULL };
+ return new byte[] { CompressionMethod.NULL };
}
public virtual IDictionary GetClientExtensions()
- {
- return null;
- }
+ {
+ return null;
+ }
public virtual void NotifySessionID(byte[] sessionID)
- {
- // Currently ignored
- }
+ {
+ // Currently ignored
+ }
public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite)
- {
- this.selectedCipherSuite = selectedCipherSuite;
- }
+ {
+ this.selectedCipherSuite = selectedCipherSuite;
+ }
- public virtual void NotifySelectedCompressionMethod(CompressionMethod selectedCompressionMethod)
+ public virtual void NotifySelectedCompressionMethod(byte selectedCompressionMethod)
{
this.selectedCompressionMethod = selectedCompressionMethod;
}
public virtual void NotifySecureRenegotiation(bool secureRenegotiation)
- {
- if (!secureRenegotiation)
- {
- /*
- * RFC 5746 3.4.
- * If the extension is not present, the server does not support
- * secure renegotiation; set secure_renegotiation flag to FALSE.
- * In this case, some clients may want to terminate the handshake
- * instead of continuing; see Section 4.1 for discussion.
- */
+ {
+ if (!secureRenegotiation)
+ {
+ /*
+ * RFC 5746 3.4.
+ * If the extension is not present, the server does not support
+ * secure renegotiation; set secure_renegotiation flag to FALSE.
+ * In this case, some clients may want to terminate the handshake
+ * instead of continuing; see Section 4.1 for discussion.
+ */
// throw new TlsFatalAlert(AlertDescription.handshake_failure);
- }
- }
+ }
+ }
public virtual void ProcessServerExtensions(IDictionary serverExtensions)
- {
- }
+ {
+ }
public virtual TlsKeyExchange GetKeyExchange()
- {
- switch (selectedCipherSuite)
- {
- 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:
+ {
+ switch (selectedCipherSuite)
+ {
+ 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_RC4_128_SHA:
- return CreateRsaKeyExchange();
+ return CreateRsaKeyExchange();
- 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:
- return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_DSS);
+ 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:
+ 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_256_CBC_SHA:
- return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_RSA);
+ 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:
+ 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_256_CBC_SHA:
- return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_DSS);
+ 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:
+ 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_256_CBC_SHA:
- return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_RSA);
+ 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:
+ 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:
@@ -155,54 +155,54 @@ namespace Org.BouncyCastle.Crypto.Tls
case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA);
- default:
- /*
- * Note: internal error here; the TlsProtocolHandler 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 abstract TlsAuthentication GetAuthentication();
-
- public virtual TlsCompression GetCompression()
- {
- switch (selectedCompressionMethod)
- {
- case CompressionMethod.NULL:
- return new TlsNullCompression();
-
- case CompressionMethod.DEFLATE:
- return new TlsDeflateCompression();
-
- default:
- /*
- * Note: internal error here; the TlsProtocolHandler verifies that the
- * server-selected compression method was in the list of client-offered compression
- * methods, so if we now can't produce an implementation, we shouldn't have
- * offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
-
- public virtual TlsCipher GetCipher()
- {
- switch (selectedCipherSuite)
- {
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- 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:
+ default:
+ /*
+ * Note: internal error here; the TlsProtocolHandler 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 abstract TlsAuthentication GetAuthentication();
+
+ public virtual TlsCompression GetCompression()
+ {
+ switch (selectedCompressionMethod)
+ {
+ case CompressionMethod.NULL:
+ return new TlsNullCompression();
+
+ case CompressionMethod.DEFLATE:
+ return new TlsDeflateCompression();
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocolHandler verifies that the
+ * server-selected compression method was in the list of client-offered compression
+ * methods, so if we now can't produce an implementation, we shouldn't have
+ * offered it!
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
+ public virtual TlsCipher GetCipher()
+ {
+ switch (selectedCipherSuite)
+ {
+ case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ 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_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- return cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC, DigestAlgorithm.SHA);
+ return cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC, DigestAlgorithm.SHA);
case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
@@ -212,47 +212,47 @@ namespace Org.BouncyCastle.Crypto.Tls
return cipherFactory.CreateCipher(context, EncryptionAlgorithm.RC4_128, DigestAlgorithm.SHA);
case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- 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_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_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC, DigestAlgorithm.SHA);
+ return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC, DigestAlgorithm.SHA);
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- 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_RSA_WITH_AES_256_CBC_SHA:
+ 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_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC, DigestAlgorithm.SHA);
-
- default:
- /*
- * Note: internal error here; the TlsProtocolHandler 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 CreateDHKeyExchange(KeyExchangeAlgorithm keyExchange)
- {
- return new TlsDHKeyExchange(context, keyExchange);
- }
+ return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC, DigestAlgorithm.SHA);
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocolHandler 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 CreateDHKeyExchange(KeyExchangeAlgorithm keyExchange)
+ {
+ return new TlsDHKeyExchange(context, keyExchange);
+ }
protected virtual TlsKeyExchange CreateDheKeyExchange(KeyExchangeAlgorithm keyExchange)
- {
- return new TlsDheKeyExchange(context, keyExchange);
- }
+ {
+ return new TlsDheKeyExchange(context, keyExchange);
+ }
protected virtual TlsKeyExchange CreateECDHKeyExchange(KeyExchangeAlgorithm keyExchange)
{
@@ -265,8 +265,8 @@ namespace Org.BouncyCastle.Crypto.Tls
}
protected virtual TlsKeyExchange CreateRsaKeyExchange()
- {
- return new TlsRsaKeyExchange(context);
- }
+ {
+ return new TlsRsaKeyExchange(context);
+ }
}
}
diff --git a/crypto/src/crypto/tls/DefaultTlsSignerCredentials.cs b/crypto/src/crypto/tls/DefaultTlsSignerCredentials.cs
index 86c9d1a18..2c5aa3524 100644
--- a/crypto/src/crypto/tls/DefaultTlsSignerCredentials.cs
+++ b/crypto/src/crypto/tls/DefaultTlsSignerCredentials.cs
@@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Crypto.Tls
{
throw new ArgumentNullException("clientCertificate");
}
- if (clientCertificate.certs.Length == 0)
+ if (clientCertificate.Length == 0)
{
throw new ArgumentException("cannot be empty", "clientCertificate");
}
diff --git a/crypto/src/crypto/tls/HashAlgorithm.cs b/crypto/src/crypto/tls/HashAlgorithm.cs
new file mode 100644
index 000000000..41818ca2c
--- /dev/null
+++ b/crypto/src/crypto/tls/HashAlgorithm.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ /**
+ * RFC 5246 7.4.1.4.1
+ */
+ public abstract class HashAlgorithm
+ {
+ public const byte none = 0;
+ public const byte md5 = 1;
+ public const byte sha1 = 2;
+ public const byte sha224 = 3;
+ public const byte sha256 = 4;
+ public const byte sha384 = 5;
+ public const byte sha512 = 6;
+ }
+}
diff --git a/crypto/src/crypto/tls/LegacyTlsAuthentication.cs b/crypto/src/crypto/tls/LegacyTlsAuthentication.cs
index 395f94208..bce31c0b0 100644
--- a/crypto/src/crypto/tls/LegacyTlsAuthentication.cs
+++ b/crypto/src/crypto/tls/LegacyTlsAuthentication.cs
@@ -2,29 +2,29 @@ using System;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// A temporary class to wrap old CertificateVerifyer stuff for new TlsAuthentication.
- /// </summary>
- [Obsolete]
- public class LegacyTlsAuthentication
- : TlsAuthentication
- {
- protected ICertificateVerifyer verifyer;
+ /// <summary>
+ /// A temporary class to wrap old CertificateVerifyer stuff for new TlsAuthentication.
+ /// </summary>
+ [Obsolete]
+ public class LegacyTlsAuthentication
+ : TlsAuthentication
+ {
+ protected ICertificateVerifyer verifyer;
- public LegacyTlsAuthentication(ICertificateVerifyer verifyer)
- {
- this.verifyer = verifyer;
- }
+ public LegacyTlsAuthentication(ICertificateVerifyer verifyer)
+ {
+ this.verifyer = verifyer;
+ }
- public virtual void NotifyServerCertificate(Certificate serverCertificate)
- {
- if (!this.verifyer.IsValid(serverCertificate.GetCerts()))
- throw new TlsFatalAlert(AlertDescription.user_canceled);
- }
+ public virtual void NotifyServerCertificate(Certificate serverCertificate)
+ {
+ if (!this.verifyer.IsValid(serverCertificate.GetCertificateList()))
+ throw new TlsFatalAlert(AlertDescription.user_canceled);
+ }
- public virtual TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
- {
- return null;
- }
- }
+ public virtual TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
+ {
+ return null;
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/PskTlsClient.cs b/crypto/src/crypto/tls/PskTlsClient.cs
index 9db7d7d90..cb42c31d8 100644
--- a/crypto/src/crypto/tls/PskTlsClient.cs
+++ b/crypto/src/crypto/tls/PskTlsClient.cs
@@ -3,168 +3,168 @@ using System.Collections;
namespace Org.BouncyCastle.Crypto.Tls
{
- public abstract class PskTlsClient
- :TlsClient
- {
- protected TlsCipherFactory cipherFactory;
- protected TlsPskIdentity pskIdentity;
+ public abstract class PskTlsClient
+ :TlsClient
+ {
+ protected TlsCipherFactory cipherFactory;
+ protected TlsPskIdentity pskIdentity;
protected TlsClientContext context;
- protected CompressionMethod selectedCompressionMethod;
- protected CipherSuite selectedCipherSuite;
+ protected byte selectedCompressionMethod;
+ protected CipherSuite selectedCipherSuite;
public PskTlsClient(TlsPskIdentity pskIdentity)
- : this(new DefaultTlsCipherFactory(), pskIdentity)
- {
- }
+ : this(new DefaultTlsCipherFactory(), pskIdentity)
+ {
+ }
public PskTlsClient(TlsCipherFactory cipherFactory, TlsPskIdentity pskIdentity)
- {
- this.cipherFactory = cipherFactory;
- this.pskIdentity = pskIdentity;
- }
+ {
+ this.cipherFactory = cipherFactory;
+ this.pskIdentity = pskIdentity;
+ }
public virtual void Init(TlsClientContext context)
- {
- this.context = context;
- }
+ {
+ this.context = context;
+ }
public virtual CipherSuite[] GetCipherSuites()
- {
- return new CipherSuite[] {
- CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA,
- CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_PSK_WITH_RC4_128_SHA,
- };
- }
+ {
+ return new CipherSuite[] {
+ CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+ CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA,
+ CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+ CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA,
+ CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+ CipherSuite.TLS_PSK_WITH_RC4_128_SHA,
+ };
+ }
public virtual IDictionary GetClientExtensions()
- {
- return null;
- }
+ {
+ return null;
+ }
- public virtual CompressionMethod[] GetCompressionMethods()
- {
- return new CompressionMethod[] { CompressionMethod.NULL };
- }
+ public virtual byte[] GetCompressionMethods()
+ {
+ return new byte[] { CompressionMethod.NULL };
+ }
public virtual void NotifySessionID(byte[] sessionID)
- {
- // Currently ignored
- }
+ {
+ // Currently ignored
+ }
public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite)
- {
- this.selectedCipherSuite = selectedCipherSuite;
- }
+ {
+ this.selectedCipherSuite = selectedCipherSuite;
+ }
- public virtual void NotifySelectedCompressionMethod(CompressionMethod selectedCompressionMethod)
- {
- this.selectedCompressionMethod = selectedCompressionMethod;
- }
+ public virtual void NotifySelectedCompressionMethod(byte selectedCompressionMethod)
+ {
+ this.selectedCompressionMethod = selectedCompressionMethod;
+ }
public virtual void NotifySecureRenegotiation(bool secureRenegotiation)
- {
- if (!secureRenegotiation)
- {
- /*
- * RFC 5746 3.4. If the extension is not present, the server does not support
- * secure renegotiation; set secure_renegotiation flag to FALSE. In this case,
- * some clients may want to terminate the handshake instead of continuing; see
- * Section 4.1 for discussion.
- */
+ {
+ if (!secureRenegotiation)
+ {
+ /*
+ * RFC 5746 3.4. If the extension is not present, the server does not support
+ * secure renegotiation; set secure_renegotiation flag to FALSE. In this case,
+ * some clients may want to terminate the handshake instead of continuing; see
+ * Section 4.1 for discussion.
+ */
// throw new TlsFatalAlert(AlertDescription.handshake_failure);
- }
- }
+ }
+ }
public virtual void ProcessServerExtensions(IDictionary serverExtensions)
- {
- }
+ {
+ }
public virtual TlsKeyExchange GetKeyExchange()
- {
- switch (selectedCipherSuite)
- {
- 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:
+ {
+ switch (selectedCipherSuite)
+ {
+ 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_RC4_128_SHA:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.PSK);
+ 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_256_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_RSA_PSK_WITH_RC4_128_SHA:
return CreatePskKeyExchange(KeyExchangeAlgorithm.RSA_PSK);
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_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
return CreatePskKeyExchange(KeyExchangeAlgorithm.DHE_PSK);
default:
- /*
- * Note: internal error here; the TlsProtocolHandler 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: internal error here; the TlsProtocolHandler 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 abstract TlsAuthentication GetAuthentication();
public virtual TlsCompression GetCompression()
- {
- switch (selectedCompressionMethod)
- {
- case CompressionMethod.NULL:
- return new TlsNullCompression();
+ {
+ switch (selectedCompressionMethod)
+ {
+ case CompressionMethod.NULL:
+ return new TlsNullCompression();
default:
- /*
- * Note: internal error here; the TlsProtocolHandler verifies that the
- * server-selected compression method was in the list of client-offered compression
- * methods, so if we now can't produce an implementation, we shouldn't have
- * offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
+ /*
+ * Note: internal error here; the TlsProtocolHandler verifies that the
+ * server-selected compression method was in the list of client-offered compression
+ * methods, so if we now can't produce an implementation, we shouldn't have
+ * offered it!
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
public virtual TlsCipher GetCipher()
- {
- switch (selectedCipherSuite)
- {
- case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- return cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC,
- DigestAlgorithm.SHA);
+ {
+ switch (selectedCipherSuite)
+ {
+ case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ return cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC,
+ DigestAlgorithm.SHA);
case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC,
- DigestAlgorithm.SHA);
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+ return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC,
+ DigestAlgorithm.SHA);
case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC,
- DigestAlgorithm.SHA);
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+ return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC,
+ DigestAlgorithm.SHA);
case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
@@ -173,19 +173,19 @@ namespace Org.BouncyCastle.Crypto.Tls
DigestAlgorithm.SHA);
default:
- /*
- * Note: internal error here; the TlsProtocolHandler 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: internal error here; the TlsProtocolHandler 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(KeyExchangeAlgorithm keyExchange)
- {
- return new TlsPskKeyExchange(context, keyExchange, pskIdentity);
- }
- }
+ {
+ return new TlsPskKeyExchange(context, keyExchange, pskIdentity);
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/SignatureAlgorithm.cs b/crypto/src/crypto/tls/SignatureAlgorithm.cs
new file mode 100644
index 000000000..35b961762
--- /dev/null
+++ b/crypto/src/crypto/tls/SignatureAlgorithm.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ /**
+ * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned)
+ */
+ public abstract class SignatureAlgorithm
+ {
+ public const byte anonymous = 0;
+ public const byte rsa = 1;
+ public const byte dsa = 2;
+ public const byte ecdsa = 3;
+ }
+}
diff --git a/crypto/src/crypto/tls/SignatureAndHashAlgorithm.cs b/crypto/src/crypto/tls/SignatureAndHashAlgorithm.cs
new file mode 100644
index 000000000..f74205b62
--- /dev/null
+++ b/crypto/src/crypto/tls/SignatureAndHashAlgorithm.cs
@@ -0,0 +1,94 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ /**
+ * RFC 5246 7.4.1.4.1
+ */
+ public class SignatureAndHashAlgorithm
+ {
+ protected readonly byte mHash;
+ protected readonly byte mSignature;
+
+ /**
+ * @param hash {@link HashAlgorithm}
+ * @param signature {@link SignatureAlgorithm}
+ */
+ public SignatureAndHashAlgorithm(byte hash, byte signature)
+ {
+ if (!TlsUtilities.IsValidUint8(hash))
+ {
+ throw new ArgumentException("should be a uint8", "hash");
+ }
+ if (!TlsUtilities.IsValidUint8(signature))
+ {
+ throw new ArgumentException("should be a uint8", "signature");
+ }
+ if (signature == SignatureAlgorithm.anonymous)
+ {
+ throw new ArgumentException("MUST NOT be \"anonymous\"", "signature");
+ }
+
+ this.mHash = hash;
+ this.mSignature = signature;
+ }
+
+ /**
+ * @return {@link HashAlgorithm}
+ */
+ public virtual byte Hash
+ {
+ get { return mHash; }
+ }
+
+ /**
+ * @return {@link SignatureAlgorithm}
+ */
+ public virtual byte Signature
+ {
+ get { return mSignature; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is SignatureAndHashAlgorithm))
+ {
+ return false;
+ }
+ SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj;
+ return other.Hash == Hash && other.Signature == Signature;
+ }
+
+ public override int GetHashCode()
+ {
+ return ((int)Hash << 16) | (int)Signature;
+ }
+
+ /**
+ * Encode this {@link SignatureAndHashAlgorithm} to a {@link Stream}.
+ *
+ * @param output the {@link Stream} to encode to.
+ * @throws IOException
+ */
+ public virtual void Encode(Stream output)
+ {
+ TlsUtilities.WriteUint8(Hash, output);
+ TlsUtilities.WriteUint8(Signature, output);
+ }
+
+ /**
+ * Parse a {@link SignatureAndHashAlgorithm} from a {@link Stream}.
+ *
+ * @param input the {@link Stream} to parse from.
+ * @return a {@link SignatureAndHashAlgorithm} object.
+ * @throws IOException
+ */
+ public static SignatureAndHashAlgorithm Parse(Stream input)
+ {
+ byte hash = TlsUtilities.ReadUint8(input);
+ byte signature = TlsUtilities.ReadUint8(input);
+ return new SignatureAndHashAlgorithm(hash, signature);
+ }
+ }
+}
diff --git a/crypto/src/crypto/tls/SrpTlsClient.cs b/crypto/src/crypto/tls/SrpTlsClient.cs
index 6c2638bb3..f487e9b21 100644
--- a/crypto/src/crypto/tls/SrpTlsClient.cs
+++ b/crypto/src/crypto/tls/SrpTlsClient.cs
@@ -6,183 +6,183 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls
{
- public abstract class SrpTlsClient
- : TlsClient
- {
- protected TlsCipherFactory cipherFactory;
- protected byte[] identity;
- protected byte[] password;
+ public abstract class SrpTlsClient
+ : TlsClient
+ {
+ protected TlsCipherFactory cipherFactory;
+ protected byte[] identity;
+ protected byte[] password;
- protected TlsClientContext context;
+ protected TlsClientContext context;
- protected CompressionMethod selectedCompressionMethod;
+ protected byte selectedCompressionMethod;
protected CipherSuite selectedCipherSuite;
- public SrpTlsClient(byte[] identity, byte[] password)
- : this(new DefaultTlsCipherFactory(), identity, password)
- {
- }
-
- public SrpTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password)
- {
- this.cipherFactory = cipherFactory;
- this.identity = Arrays.Clone(identity);
- this.password = Arrays.Clone(password);
- }
-
- public virtual void Init(TlsClientContext context)
- {
- this.context = context;
- }
-
- public virtual CipherSuite[] GetCipherSuites()
- {
- return new CipherSuite[] {
- CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_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_RSA_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
- };
- }
-
- public virtual IDictionary GetClientExtensions()
- {
- IDictionary clientExtensions = Platform.CreateHashtable();
-
- MemoryStream srpData = new MemoryStream();
- TlsUtilities.WriteOpaque8(this.identity, srpData);
- clientExtensions[ExtensionType.srp] = srpData.ToArray();
-
- return clientExtensions;
- }
-
- public virtual CompressionMethod[] GetCompressionMethods()
- {
- return new CompressionMethod[] { CompressionMethod.NULL };
- }
-
- public virtual void NotifySessionID(byte[] sessionID)
- {
- // Currently ignored
- }
-
- public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite)
- {
- this.selectedCipherSuite = selectedCipherSuite;
- }
-
- public virtual void NotifySelectedCompressionMethod(CompressionMethod selectedCompressionMethod)
- {
+ public SrpTlsClient(byte[] identity, byte[] password)
+ : this(new DefaultTlsCipherFactory(), identity, password)
+ {
+ }
+
+ public SrpTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password)
+ {
+ this.cipherFactory = cipherFactory;
+ this.identity = Arrays.Clone(identity);
+ this.password = Arrays.Clone(password);
+ }
+
+ public virtual void Init(TlsClientContext context)
+ {
+ this.context = context;
+ }
+
+ public virtual CipherSuite[] GetCipherSuites()
+ {
+ return new CipherSuite[] {
+ CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_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_RSA_WITH_3DES_EDE_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+ };
+ }
+
+ public virtual IDictionary GetClientExtensions()
+ {
+ IDictionary clientExtensions = Platform.CreateHashtable();
+
+ MemoryStream srpData = new MemoryStream();
+ TlsUtilities.WriteOpaque8(this.identity, srpData);
+ clientExtensions[ExtensionType.srp] = srpData.ToArray();
+
+ return clientExtensions;
+ }
+
+ public virtual byte[] GetCompressionMethods()
+ {
+ return new byte[] { CompressionMethod.NULL };
+ }
+
+ public virtual void NotifySessionID(byte[] sessionID)
+ {
+ // Currently ignored
+ }
+
+ public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite)
+ {
+ this.selectedCipherSuite = selectedCipherSuite;
+ }
+
+ public virtual void NotifySelectedCompressionMethod(byte selectedCompressionMethod)
+ {
this.selectedCompressionMethod = selectedCompressionMethod;
}
- public virtual void NotifySecureRenegotiation(bool secureRenegotiation)
- {
- if (!secureRenegotiation)
- {
- /*
- * RFC 5746 3.4. If the extension is not present, the server does not support
- * secure renegotiation; set secure_renegotiation flag to FALSE. In this case,
- * some clients may want to terminate the handshake instead of continuing; see
- * Section 4.1 for discussion.
- */
+ public virtual void NotifySecureRenegotiation(bool secureRenegotiation)
+ {
+ if (!secureRenegotiation)
+ {
+ /*
+ * RFC 5746 3.4. If the extension is not present, the server does not support
+ * secure renegotiation; set secure_renegotiation flag to FALSE. In this case,
+ * some clients may want to terminate the handshake instead of continuing; see
+ * Section 4.1 for discussion.
+ */
// throw new TlsFatalAlert(AlertDescription.handshake_failure);
- }
- }
-
- public virtual void ProcessServerExtensions(IDictionary serverExtensions)
- {
- // There is no server response for the SRP extension
- }
-
- public virtual TlsKeyExchange GetKeyExchange()
- {
- switch (selectedCipherSuite)
- {
- 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);
-
- 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);
-
- default:
- /*
- * Note: internal error here; the TlsProtocolHandler 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 abstract TlsAuthentication GetAuthentication();
-
- public virtual TlsCompression GetCompression()
- {
- switch (selectedCompressionMethod)
- {
- case CompressionMethod.NULL:
- return new TlsNullCompression();
-
- default:
- /*
- * Note: internal error here; the TlsProtocolHandler verifies that the
- * server-selected compression method was in the list of client-offered compression
- * methods, so if we now can't produce an implementation, we shouldn't have
- * offered it!
- */
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
-
- public virtual TlsCipher GetCipher()
- {
- switch (selectedCipherSuite)
- {
- 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 cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC, DigestAlgorithm.SHA);
-
- 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 cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC, DigestAlgorithm.SHA);
-
- 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 cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC, DigestAlgorithm.SHA);
-
- default:
- /*
- * Note: internal error here; the TlsProtocolHandler 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(KeyExchangeAlgorithm keyExchange)
- {
- return new TlsSrpKeyExchange(context, keyExchange, identity, password);
- }
- }
+ }
+ }
+
+ public virtual void ProcessServerExtensions(IDictionary serverExtensions)
+ {
+ // There is no server response for the SRP extension
+ }
+
+ public virtual TlsKeyExchange GetKeyExchange()
+ {
+ switch (selectedCipherSuite)
+ {
+ 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);
+
+ 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);
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocolHandler 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 abstract TlsAuthentication GetAuthentication();
+
+ public virtual TlsCompression GetCompression()
+ {
+ switch (selectedCompressionMethod)
+ {
+ case CompressionMethod.NULL:
+ return new TlsNullCompression();
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocolHandler verifies that the
+ * server-selected compression method was in the list of client-offered compression
+ * methods, so if we now can't produce an implementation, we shouldn't have
+ * offered it!
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
+ public virtual TlsCipher GetCipher()
+ {
+ switch (selectedCipherSuite)
+ {
+ 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 cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC, DigestAlgorithm.SHA);
+
+ 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 cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC, DigestAlgorithm.SHA);
+
+ 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 cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC, DigestAlgorithm.SHA);
+
+ default:
+ /*
+ * Note: internal error here; the TlsProtocolHandler 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(KeyExchangeAlgorithm keyExchange)
+ {
+ return new TlsSrpKeyExchange(context, keyExchange, identity, password);
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/TlsClient.cs b/crypto/src/crypto/tls/TlsClient.cs
index eceaa3cd3..d32ac1547 100644
--- a/crypto/src/crypto/tls/TlsClient.cs
+++ b/crypto/src/crypto/tls/TlsClient.cs
@@ -28,9 +28,9 @@ namespace Org.BouncyCastle.Crypto.Tls
/// <returns>
/// An array of <see cref="CompressionMethod"/>, each specifying a supported compression method.
/// </returns>
- CompressionMethod[] GetCompressionMethods();
+ byte[] GetCompressionMethods();
- /// <summary>
+ /// <summary>
/// Get the (optional) table of client extensions to be included in (extended) client hello.
/// </summary>
/// <returns>
@@ -69,7 +69,7 @@ namespace Org.BouncyCastle.Crypto.Tls
/// <param name="selectedCompressionMethod">
/// A <see cref="CompressionMethod"/>
/// </param>
- void NotifySelectedCompressionMethod(CompressionMethod selectedCompressionMethod);
+ void NotifySelectedCompressionMethod(byte selectedCompressionMethod);
/// <summary>
/// Report whether the server supports secure renegotiation
diff --git a/crypto/src/crypto/tls/TlsDHKeyExchange.cs b/crypto/src/crypto/tls/TlsDHKeyExchange.cs
index 40ac416e0..465d8c0b2 100644
--- a/crypto/src/crypto/tls/TlsDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsDHKeyExchange.cs
@@ -9,193 +9,193 @@ using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// TLS 1.0 DH key exchange.
- /// </summary>
- internal class TlsDHKeyExchange
- : TlsKeyExchange
- {
- protected TlsClientContext context;
- protected KeyExchangeAlgorithm keyExchange;
- protected TlsSigner tlsSigner;
-
- protected AsymmetricKeyParameter serverPublicKey = null;
- protected DHPublicKeyParameters dhAgreeServerPublicKey = null;
- protected TlsAgreementCredentials agreementCredentials;
- protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null;
-
- internal TlsDHKeyExchange(TlsClientContext context, KeyExchangeAlgorithm keyExchange)
- {
- switch (keyExchange)
- {
- case KeyExchangeAlgorithm.DH_RSA:
- case KeyExchangeAlgorithm.DH_DSS:
- this.tlsSigner = null;
- break;
- case KeyExchangeAlgorithm.DHE_RSA:
- this.tlsSigner = new TlsRsaSigner();
- break;
- case KeyExchangeAlgorithm.DHE_DSS:
- this.tlsSigner = new TlsDssSigner();
- break;
- default:
- throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
- }
-
- this.context = context;
- this.keyExchange = keyExchange;
- }
-
- public virtual void SkipServerCertificate()
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
- {
- X509CertificateStructure x509Cert = serverCertificate.certs[0];
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
-
- try
- {
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
- }
- catch (Exception)
- {
- throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
- }
-
- if (tlsSigner == null)
- {
- try
- {
- this.dhAgreeServerPublicKey = ValidateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey);
- }
- catch (InvalidCastException)
- {
- throw new TlsFatalAlert(AlertDescription.certificate_unknown);
- }
-
- TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement);
- }
- else
- {
- if (!tlsSigner.IsValidPublicKey(this.serverPublicKey))
- {
- throw new TlsFatalAlert(AlertDescription.certificate_unknown);
- }
-
- TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
- }
-
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
- }
-
- public virtual void SkipServerKeyExchange()
- {
- // OK
- }
-
- public virtual void ProcessServerKeyExchange(Stream input)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
- {
- ClientCertificateType[] types = certificateRequest.CertificateTypes;
- foreach (ClientCertificateType type in types)
- {
- switch (type)
- {
- case ClientCertificateType.rsa_sign:
- case ClientCertificateType.dss_sign:
- case ClientCertificateType.rsa_fixed_dh:
- case ClientCertificateType.dss_fixed_dh:
- case ClientCertificateType.ecdsa_sign:
- break;
- default:
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
- }
- }
-
- public virtual void SkipClientCredentials()
- {
- this.agreementCredentials = null;
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
- {
- if (clientCredentials is TlsAgreementCredentials)
- {
- // TODO Validate client cert has matching parameters (see 'areCompatibleParameters')?
-
- this.agreementCredentials = (TlsAgreementCredentials)clientCredentials;
- }
- else if (clientCredentials is TlsSignerCredentials)
- {
- // OK
- }
- else
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
-
- public virtual void GenerateClientKeyExchange(Stream output)
- {
- /*
- * RFC 2246 7.4.7.2 If the client certificate already contains a suitable
- * Diffie-Hellman key, then Yc is implicit and does not need to be sent again. In
- * this case, the Client Key Exchange message will be sent, but will be empty.
- */
- if (agreementCredentials == null)
- {
- GenerateEphemeralClientKeyExchange(dhAgreeServerPublicKey.Parameters, output);
- }
- }
+ /// <summary>
+ /// TLS 1.0 DH key exchange.
+ /// </summary>
+ internal class TlsDHKeyExchange
+ : TlsKeyExchange
+ {
+ protected TlsClientContext context;
+ protected KeyExchangeAlgorithm keyExchange;
+ protected TlsSigner tlsSigner;
+
+ protected AsymmetricKeyParameter serverPublicKey = null;
+ protected DHPublicKeyParameters dhAgreeServerPublicKey = null;
+ protected TlsAgreementCredentials agreementCredentials;
+ protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null;
+
+ internal TlsDHKeyExchange(TlsClientContext context, KeyExchangeAlgorithm keyExchange)
+ {
+ switch (keyExchange)
+ {
+ case KeyExchangeAlgorithm.DH_RSA:
+ case KeyExchangeAlgorithm.DH_DSS:
+ this.tlsSigner = null;
+ break;
+ case KeyExchangeAlgorithm.DHE_RSA:
+ this.tlsSigner = new TlsRsaSigner();
+ break;
+ case KeyExchangeAlgorithm.DHE_DSS:
+ this.tlsSigner = new TlsDssSigner();
+ break;
+ default:
+ throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
+ }
+
+ this.context = context;
+ this.keyExchange = keyExchange;
+ }
+
+ public virtual void SkipServerCertificate()
+ {
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
+ public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ {
+ X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+
+ try
+ {
+ this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ }
+ catch (Exception)
+ {
+ throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
+ }
+
+ if (tlsSigner == null)
+ {
+ try
+ {
+ this.dhAgreeServerPublicKey = ValidateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey);
+ }
+ catch (InvalidCastException)
+ {
+ throw new TlsFatalAlert(AlertDescription.certificate_unknown);
+ }
+
+ TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement);
+ }
+ else
+ {
+ if (!tlsSigner.IsValidPublicKey(this.serverPublicKey))
+ {
+ throw new TlsFatalAlert(AlertDescription.certificate_unknown);
+ }
+
+ TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
+ }
+
+ // TODO
+ /*
+ * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
+ * signing algorithm for the certificate must be the same as the algorithm for the
+ * certificate key."
+ */
+ }
+
+ public virtual void SkipServerKeyExchange()
+ {
+ // OK
+ }
+
+ public virtual void ProcessServerKeyExchange(Stream input)
+ {
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
+ public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ {
+ byte[] types = certificateRequest.CertificateTypes;
+ foreach (byte type in types)
+ {
+ switch (type)
+ {
+ case ClientCertificateType.rsa_sign:
+ case ClientCertificateType.dss_sign:
+ case ClientCertificateType.rsa_fixed_dh:
+ case ClientCertificateType.dss_fixed_dh:
+ case ClientCertificateType.ecdsa_sign:
+ break;
+ default:
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ }
+ }
+ }
+
+ public virtual void SkipClientCredentials()
+ {
+ this.agreementCredentials = null;
+ }
+
+ public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ {
+ if (clientCredentials is TlsAgreementCredentials)
+ {
+ // TODO Validate client cert has matching parameters (see 'areCompatibleParameters')?
+
+ this.agreementCredentials = (TlsAgreementCredentials)clientCredentials;
+ }
+ else if (clientCredentials is TlsSignerCredentials)
+ {
+ // OK
+ }
+ else
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
+ public virtual void GenerateClientKeyExchange(Stream output)
+ {
+ /*
+ * RFC 2246 7.4.7.2 If the client certificate already contains a suitable
+ * Diffie-Hellman key, then Yc is implicit and does not need to be sent again. In
+ * this case, the Client Key Exchange message will be sent, but will be empty.
+ */
+ if (agreementCredentials == null)
+ {
+ GenerateEphemeralClientKeyExchange(dhAgreeServerPublicKey.Parameters, output);
+ }
+ }
public virtual byte[] GeneratePremasterSecret()
- {
- if (agreementCredentials != null)
- {
- return agreementCredentials.GenerateAgreement(dhAgreeServerPublicKey);
- }
-
- return CalculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey);
- }
-
- protected virtual bool AreCompatibleParameters(DHParameters a, DHParameters b)
- {
- return a.P.Equals(b.P) && a.G.Equals(b.G);
- }
-
- protected virtual byte[] CalculateDHBasicAgreement(DHPublicKeyParameters publicKey,
- DHPrivateKeyParameters privateKey)
- {
- return TlsDHUtilities.CalculateDHBasicAgreement(publicKey, privateKey);
- }
-
- protected virtual AsymmetricCipherKeyPair GenerateDHKeyPair(DHParameters dhParams)
- {
- return TlsDHUtilities.GenerateDHKeyPair(context.SecureRandom, dhParams);
- }
-
- protected virtual void GenerateEphemeralClientKeyExchange(DHParameters dhParams, Stream output)
- {
- this.dhAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(
- context.SecureRandom, dhParams, output);
- }
-
- protected virtual DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key)
- {
- return TlsDHUtilities.ValidateDHPublicKey(key);
- }
- }
+ {
+ if (agreementCredentials != null)
+ {
+ return agreementCredentials.GenerateAgreement(dhAgreeServerPublicKey);
+ }
+
+ return CalculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey);
+ }
+
+ protected virtual bool AreCompatibleParameters(DHParameters a, DHParameters b)
+ {
+ return a.P.Equals(b.P) && a.G.Equals(b.G);
+ }
+
+ protected virtual byte[] CalculateDHBasicAgreement(DHPublicKeyParameters publicKey,
+ DHPrivateKeyParameters privateKey)
+ {
+ return TlsDHUtilities.CalculateDHBasicAgreement(publicKey, privateKey);
+ }
+
+ protected virtual AsymmetricCipherKeyPair GenerateDHKeyPair(DHParameters dhParams)
+ {
+ return TlsDHUtilities.GenerateDHKeyPair(context.SecureRandom, dhParams);
+ }
+
+ protected virtual void GenerateEphemeralClientKeyExchange(DHParameters dhParams, Stream output)
+ {
+ this.dhAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(
+ context.SecureRandom, dhParams, output);
+ }
+
+ protected virtual DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key)
+ {
+ return TlsDHUtilities.ValidateDHPublicKey(key);
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
index 36155346a..4c5576fca 100644
--- a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
@@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public virtual void ProcessServerCertificate(Certificate serverCertificate)
{
- X509CertificateStructure x509Cert = serverCertificate.certs[0];
+ X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
@@ -117,8 +117,8 @@ namespace Org.BouncyCastle.Crypto.Tls
* prohibited because the use of a long-term ECDH client key would jeopardize the
* forward secrecy property of these algorithms.
*/
- ClientCertificateType[] types = certificateRequest.CertificateTypes;
- foreach (ClientCertificateType type in types)
+ byte[] types = certificateRequest.CertificateTypes;
+ foreach (byte type in types)
{
switch (type)
{
diff --git a/crypto/src/crypto/tls/TlsECDheKeyExchange.cs b/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
index 071d06b91..2dd284f12 100644
--- a/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
@@ -72,8 +72,8 @@ namespace Org.BouncyCastle.Crypto.Tls
* prohibited because the use of a long-term ECDH client key would jeopardize the
* forward secrecy property of these algorithms.
*/
- ClientCertificateType[] types = certificateRequest.CertificateTypes;
- foreach (ClientCertificateType type in types)
+ byte[] types = certificateRequest.CertificateTypes;
+ foreach (byte type in types)
{
switch (type)
{
diff --git a/crypto/src/crypto/tls/TlsException.cs b/crypto/src/crypto/tls/TlsException.cs
deleted file mode 100644
index 59c129105..000000000
--- a/crypto/src/crypto/tls/TlsException.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace Org.BouncyCastle.Crypto.Tls
-{
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
- [Serializable]
-#endif
- public class TlsException : Exception
- {
- public TlsException() : base() { }
- public TlsException(string message) : base(message) { }
- public TlsException(string message, Exception exception) : base(message, exception) { }
- }
-}
diff --git a/crypto/src/crypto/tls/TlsFatalAlert.cs b/crypto/src/crypto/tls/TlsFatalAlert.cs
index 0a9cc6f3a..4fb2a41bd 100644
--- a/crypto/src/crypto/tls/TlsFatalAlert.cs
+++ b/crypto/src/crypto/tls/TlsFatalAlert.cs
@@ -3,19 +3,19 @@ using System.IO;
namespace Org.BouncyCastle.Crypto.Tls
{
- public class TlsFatalAlert
- : IOException
- {
- private readonly AlertDescription alertDescription;
+ public class TlsFatalAlert
+ : IOException
+ {
+ private readonly byte alertDescription;
- public TlsFatalAlert(AlertDescription alertDescription)
- {
- this.alertDescription = alertDescription;
- }
+ public TlsFatalAlert(byte alertDescription)
+ {
+ this.alertDescription = alertDescription;
+ }
- public AlertDescription AlertDescription
- {
- get { return alertDescription; }
- }
- }
+ public virtual byte AlertDescription
+ {
+ get { return alertDescription; }
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/TlsProtocolHandler.cs b/crypto/src/crypto/tls/TlsProtocolHandler.cs
index 1960d3ccd..5ba42ef66 100644
--- a/crypto/src/crypto/tls/TlsProtocolHandler.cs
+++ b/crypto/src/crypto/tls/TlsProtocolHandler.cs
@@ -40,8 +40,6 @@ namespace Org.BouncyCastle.Crypto.Tls
private const short CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED = 11;
private const short CS_DONE = 12;
- private static readonly byte[] emptybuf = new byte[0];
-
private static readonly string TLS_ERROR_MESSAGE = "Internal TLS error, this could be an attack";
/*
@@ -70,7 +68,7 @@ namespace Org.BouncyCastle.Crypto.Tls
private TlsClientContextImpl tlsClientContext = null;
private TlsClient tlsClient = null;
private CipherSuite[] offeredCipherSuites = null;
- private CompressionMethod[] offeredCompressionMethods = null;
+ private byte[] offeredCompressionMethods = null;
private TlsKeyExchange keyExchange = null;
private TlsAuthentication authentication = null;
private CertificateRequest certificateRequest = null;
@@ -337,7 +335,7 @@ namespace Org.BouncyCastle.Crypto.Tls
* Find out which CompressionMethod the server has chosen and check that
* it was one of the offered ones.
*/
- CompressionMethod selectedCompressionMethod = (CompressionMethod)TlsUtilities.ReadUint8(inStr);
+ byte selectedCompressionMethod = TlsUtilities.ReadUint8(inStr);
if (!ArrayContains(offeredCompressionMethods, selectedCompressionMethod))
{
this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter);
@@ -431,7 +429,7 @@ namespace Org.BouncyCastle.Crypto.Tls
byte[] renegExtValue = (byte[])serverExtensions[ExtensionType.renegotiation_info];
if (!Arrays.ConstantTimeAreEqual(renegExtValue,
- CreateRenegotiationInfo(emptybuf)))
+ CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
{
this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure);
}
@@ -626,29 +624,11 @@ namespace Org.BouncyCastle.Crypto.Tls
this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure);
}
- int numTypes = TlsUtilities.ReadUint8(inStr);
- ClientCertificateType[] certificateTypes = new ClientCertificateType[numTypes];
- for (int i = 0; i < numTypes; ++i)
- {
- certificateTypes[i] = (ClientCertificateType)TlsUtilities.ReadUint8(inStr);
- }
-
- byte[] authorities = TlsUtilities.ReadOpaque16(inStr);
+ this.certificateRequest = CertificateRequest.Parse(//getContext(),
+ inStr);
AssertEmpty(inStr);
- IList authorityDNs = Platform.CreateArrayList();
-
- MemoryStream bis = new MemoryStream(authorities, false);
- while (bis.Position < bis.Length)
- {
- byte[] dnBytes = TlsUtilities.ReadOpaque16(bis);
- // TODO Switch to X500Name when available
- authorityDNs.Add(X509Name.GetInstance(Asn1Object.FromByteArray(dnBytes)));
- }
-
- this.certificateRequest = new CertificateRequest(certificateTypes,
- authorityDNs);
this.keyExchange.ValidateCertificateRequest(this.certificateRequest);
break;
@@ -899,7 +879,7 @@ namespace Org.BouncyCastle.Crypto.Tls
TlsUtilities.WriteUint8((byte)offeredCompressionMethods.Length, outStr);
for (int i = 0; i < offeredCompressionMethods.Length; ++i)
{
- TlsUtilities.WriteUint8((byte)offeredCompressionMethods[i], outStr);
+ TlsUtilities.WriteUint8(offeredCompressionMethods[i], outStr);
}
}
@@ -1123,7 +1103,7 @@ namespace Org.BouncyCastle.Crypto.Tls
* @param alertDescription The exact alert message.
* @throws IOException If alert was fatal.
*/
- private void FailWithError(AlertLevel alertLevel, AlertDescription alertDescription)
+ private void FailWithError(byte alertLevel, byte alertDescription)
{
/*
* Check if the connection is still open.
@@ -1155,11 +1135,9 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
- internal void SendAlert(AlertLevel alertLevel, AlertDescription alertDescription)
+ internal void SendAlert(byte alertLevel, byte alertDescription)
{
- byte[] error = new byte[2];
- error[0] = (byte)alertLevel;
- error[1] = (byte)alertDescription;
+ byte[] error = new byte[] { alertLevel, alertDescription };
rs.WriteMessage(ContentType.alert, error, 0, 2);
}
@@ -1218,7 +1196,7 @@ namespace Org.BouncyCastle.Crypto.Tls
return false;
}
- private static bool ArrayContains(CompressionMethod[] a, CompressionMethod n)
+ private static bool ArrayContains(byte[] a, byte n)
{
for (int i = 0; i < a.Length; ++i)
{
diff --git a/crypto/src/crypto/tls/TlsPskKeyExchange.cs b/crypto/src/crypto/tls/TlsPskKeyExchange.cs
index cadd643ca..b1f14e156 100644
--- a/crypto/src/crypto/tls/TlsPskKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsPskKeyExchange.cs
@@ -8,42 +8,42 @@ using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls
{
- internal class TlsPskKeyExchange
- : TlsKeyExchange
- {
- protected TlsClientContext context;
- protected KeyExchangeAlgorithm keyExchange;
- protected TlsPskIdentity pskIdentity;
+ internal class TlsPskKeyExchange
+ : TlsKeyExchange
+ {
+ protected TlsClientContext context;
+ protected KeyExchangeAlgorithm keyExchange;
+ protected TlsPskIdentity pskIdentity;
- protected byte[] psk_identity_hint = null;
+ protected byte[] psk_identity_hint = null;
- protected DHPublicKeyParameters dhAgreeServerPublicKey = null;
- protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null;
+ protected DHPublicKeyParameters dhAgreeServerPublicKey = null;
+ protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null;
protected AsymmetricKeyParameter serverPublicKey = null;
protected RsaKeyParameters rsaServerPublicKey = null;
- protected byte[] premasterSecret;
-
- internal TlsPskKeyExchange(TlsClientContext context, KeyExchangeAlgorithm keyExchange,
- TlsPskIdentity pskIdentity)
- {
- switch (keyExchange)
- {
- case KeyExchangeAlgorithm.PSK:
- case KeyExchangeAlgorithm.RSA_PSK:
- case KeyExchangeAlgorithm.DHE_PSK:
- break;
- default:
- throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
- }
-
- this.context = context;
- this.keyExchange = keyExchange;
- this.pskIdentity = pskIdentity;
- }
-
- public virtual void SkipServerCertificate()
- {
+ protected byte[] premasterSecret;
+
+ internal TlsPskKeyExchange(TlsClientContext context, KeyExchangeAlgorithm keyExchange,
+ TlsPskIdentity pskIdentity)
+ {
+ switch (keyExchange)
+ {
+ case KeyExchangeAlgorithm.PSK:
+ case KeyExchangeAlgorithm.RSA_PSK:
+ case KeyExchangeAlgorithm.DHE_PSK:
+ break;
+ default:
+ throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
+ }
+
+ this.context = context;
+ this.keyExchange = keyExchange;
+ this.pskIdentity = pskIdentity;
+ }
+
+ public virtual void SkipServerCertificate()
+ {
if (keyExchange == KeyExchangeAlgorithm.RSA_PSK)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
@@ -51,13 +51,13 @@ namespace Org.BouncyCastle.Crypto.Tls
}
public virtual void ProcessServerCertificate(Certificate serverCertificate)
- {
+ {
if (keyExchange != KeyExchangeAlgorithm.RSA_PSK)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- X509CertificateStructure x509Cert = serverCertificate.certs[0];
+ X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
@@ -88,107 +88,107 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
}
- public virtual void SkipServerKeyExchange()
- {
+ public virtual void SkipServerKeyExchange()
+ {
if (keyExchange == KeyExchangeAlgorithm.DHE_PSK)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- this.psk_identity_hint = new byte[0];
- }
-
- public virtual void ProcessServerKeyExchange(Stream input)
- {
- this.psk_identity_hint = TlsUtilities.ReadOpaque16(input);
-
- if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
- {
- byte[] pBytes = TlsUtilities.ReadOpaque16(input);
- byte[] gBytes = TlsUtilities.ReadOpaque16(input);
- byte[] YsBytes = TlsUtilities.ReadOpaque16(input);
-
- BigInteger p = new BigInteger(1, pBytes);
- BigInteger g = new BigInteger(1, gBytes);
- BigInteger Ys = new BigInteger(1, YsBytes);
-
- this.dhAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey(
- new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
- }
- else if (this.psk_identity_hint.Length == 0)
- {
- // TODO Should we enforce that this message should have been skipped if hint is empty?
- //throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
- }
-
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- public virtual void SkipClientCredentials()
- {
- // OK
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
-
- public virtual void GenerateClientKeyExchange(Stream output)
- {
- if (psk_identity_hint == null || psk_identity_hint.Length == 0)
- {
- pskIdentity.SkipIdentityHint();
- }
- else
- {
- pskIdentity.NotifyIdentityHint(psk_identity_hint);
- }
-
- byte[] psk_identity = pskIdentity.GetPskIdentity();
-
- TlsUtilities.WriteOpaque16(psk_identity, output);
-
- if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK)
- {
- this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(
- context.SecureRandom, this.rsaServerPublicKey, output);
- }
- else if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
- {
- this.dhAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(
- context.SecureRandom, this.dhAgreeServerPublicKey.Parameters, output);
- }
- }
-
- public virtual byte[] GeneratePremasterSecret()
- {
- byte[] psk = pskIdentity.GetPsk();
- byte[] other_secret = GenerateOtherSecret(psk.Length);
-
- MemoryStream buf = new MemoryStream(4 + other_secret.Length + psk.Length);
- TlsUtilities.WriteOpaque16(other_secret, buf);
- TlsUtilities.WriteOpaque16(psk, buf);
- return buf.ToArray();
- }
-
- protected virtual byte[] GenerateOtherSecret(int pskLength)
- {
- if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
- {
- return TlsDHUtilities.CalculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey);
- }
-
- if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK)
- {
- return this.premasterSecret;
- }
-
- return new byte[pskLength];
- }
+ this.psk_identity_hint = TlsUtilities.EmptyBytes;
+ }
+
+ public virtual void ProcessServerKeyExchange(Stream input)
+ {
+ this.psk_identity_hint = TlsUtilities.ReadOpaque16(input);
+
+ if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ {
+ byte[] pBytes = TlsUtilities.ReadOpaque16(input);
+ byte[] gBytes = TlsUtilities.ReadOpaque16(input);
+ byte[] YsBytes = TlsUtilities.ReadOpaque16(input);
+
+ BigInteger p = new BigInteger(1, pBytes);
+ BigInteger g = new BigInteger(1, gBytes);
+ BigInteger Ys = new BigInteger(1, YsBytes);
+
+ this.dhAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey(
+ new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
+ }
+ else if (this.psk_identity_hint.Length == 0)
+ {
+ // TODO Should we enforce that this message should have been skipped if hint is empty?
+ //throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+ }
+
+ public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ {
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
+ public virtual void SkipClientCredentials()
+ {
+ // OK
+ }
+
+ public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ public virtual void GenerateClientKeyExchange(Stream output)
+ {
+ if (psk_identity_hint == null || psk_identity_hint.Length == 0)
+ {
+ pskIdentity.SkipIdentityHint();
+ }
+ else
+ {
+ pskIdentity.NotifyIdentityHint(psk_identity_hint);
+ }
+
+ byte[] psk_identity = pskIdentity.GetPskIdentity();
+
+ TlsUtilities.WriteOpaque16(psk_identity, output);
+
+ if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK)
+ {
+ this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(
+ context.SecureRandom, this.rsaServerPublicKey, output);
+ }
+ else if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ {
+ this.dhAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(
+ context.SecureRandom, this.dhAgreeServerPublicKey.Parameters, output);
+ }
+ }
+
+ public virtual byte[] GeneratePremasterSecret()
+ {
+ byte[] psk = pskIdentity.GetPsk();
+ byte[] other_secret = GenerateOtherSecret(psk.Length);
+
+ MemoryStream buf = new MemoryStream(4 + other_secret.Length + psk.Length);
+ TlsUtilities.WriteOpaque16(other_secret, buf);
+ TlsUtilities.WriteOpaque16(psk, buf);
+ return buf.ToArray();
+ }
+
+ protected virtual byte[] GenerateOtherSecret(int pskLength)
+ {
+ if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ {
+ return TlsDHUtilities.CalculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey);
+ }
+
+ if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK)
+ {
+ return this.premasterSecret;
+ }
+
+ return new byte[pskLength];
+ }
protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key)
{
diff --git a/crypto/src/crypto/tls/TlsRsaKeyExchange.cs b/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
index ad61f08de..aad482316 100644
--- a/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
@@ -11,117 +11,117 @@ using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// TLS 1.0 RSA key exchange.
- /// </summary>
- internal class TlsRsaKeyExchange
- : TlsKeyExchange
- {
- protected TlsClientContext context;
+ /// <summary>
+ /// TLS 1.0 RSA key exchange.
+ /// </summary>
+ internal class TlsRsaKeyExchange
+ : TlsKeyExchange
+ {
+ protected TlsClientContext context;
- protected AsymmetricKeyParameter serverPublicKey = null;
+ protected AsymmetricKeyParameter serverPublicKey = null;
protected RsaKeyParameters rsaServerPublicKey = null;
protected byte[] premasterSecret;
- internal TlsRsaKeyExchange(TlsClientContext context)
- {
- this.context = context;
- }
-
- public virtual void SkipServerCertificate()
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
- {
- X509CertificateStructure x509Cert = serverCertificate.certs[0];
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
-
- try
- {
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
- }
+ internal TlsRsaKeyExchange(TlsClientContext context)
+ {
+ this.context = context;
+ }
+
+ public virtual void SkipServerCertificate()
+ {
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
+ public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ {
+ X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+
+ try
+ {
+ this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ }
// catch (RuntimeException)
- catch (Exception)
- {
- throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
- }
-
- // Sanity check the PublicKeyFactory
- if (this.serverPublicKey.IsPrivate)
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
-
- this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey);
-
- TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
-
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
- }
-
- public virtual void SkipServerKeyExchange()
- {
- // OK
- }
-
- public virtual void ProcessServerKeyExchange(Stream input)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
- {
- ClientCertificateType[] types = certificateRequest.CertificateTypes;
- foreach (ClientCertificateType type in types)
- {
- switch (type)
- {
- case ClientCertificateType.rsa_sign:
- case ClientCertificateType.dss_sign:
- case ClientCertificateType.ecdsa_sign:
- break;
- default:
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
- }
- }
-
- public virtual void SkipClientCredentials()
- {
- // OK
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
- {
- if (!(clientCredentials is TlsSignerCredentials))
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- }
-
+ catch (Exception)
+ {
+ throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
+ }
+
+ // Sanity check the PublicKeyFactory
+ if (this.serverPublicKey.IsPrivate)
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey);
+
+ TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
+
+ // TODO
+ /*
+ * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
+ * signing algorithm for the certificate must be the same as the algorithm for the
+ * certificate key."
+ */
+ }
+
+ public virtual void SkipServerKeyExchange()
+ {
+ // OK
+ }
+
+ public virtual void ProcessServerKeyExchange(Stream input)
+ {
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
+ public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ {
+ byte[] types = certificateRequest.CertificateTypes;
+ foreach (byte type in types)
+ {
+ switch (type)
+ {
+ case ClientCertificateType.rsa_sign:
+ case ClientCertificateType.dss_sign:
+ case ClientCertificateType.ecdsa_sign:
+ break;
+ default:
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ }
+ }
+ }
+
+ public virtual void SkipClientCredentials()
+ {
+ // OK
+ }
+
+ public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ {
+ if (!(clientCredentials is TlsSignerCredentials))
+ {
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+ }
+
public virtual void GenerateClientKeyExchange(Stream output)
- {
- this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(
- context.SecureRandom, this.rsaServerPublicKey, output);
- }
-
- public virtual byte[] GeneratePremasterSecret()
- {
- byte[] tmp = this.premasterSecret;
- this.premasterSecret = null;
- return tmp;
- }
-
- // Would be needed to process RSA_EXPORT server key exchange
+ {
+ this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(
+ context.SecureRandom, this.rsaServerPublicKey, output);
+ }
+
+ public virtual byte[] GeneratePremasterSecret()
+ {
+ byte[] tmp = this.premasterSecret;
+ this.premasterSecret = null;
+ return tmp;
+ }
+
+ // Would be needed to process RSA_EXPORT server key exchange
// protected virtual void ProcessRsaServerKeyExchange(Stream input, ISigner signer)
// {
// Stream sigIn = input;
@@ -150,16 +150,16 @@ namespace Org.BouncyCastle.Crypto.Tls
// }
protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key)
- {
- // TODO What is the minimum bit length required?
+ {
+ // TODO What is the minimum bit length required?
// key.Modulus.BitLength;
- if (!key.Exponent.IsProbablePrime(2))
- {
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
+ if (!key.Exponent.IsProbablePrime(2))
+ {
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ }
- return key;
- }
- }
+ return key;
+ }
+ }
}
diff --git a/crypto/src/crypto/tls/TlsSrpKeyExchange.cs b/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
index cb4e26e58..8040f8e6c 100644
--- a/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- X509CertificateStructure x509Cert = serverCertificate.certs[0];
+ X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
diff --git a/crypto/src/crypto/tls/TlsUtilities.cs b/crypto/src/crypto/tls/TlsUtilities.cs
index dca842a80..5ed659ce7 100644
--- a/crypto/src/crypto/tls/TlsUtilities.cs
+++ b/crypto/src/crypto/tls/TlsUtilities.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.IO;
using System.Text;
@@ -16,6 +17,41 @@ namespace Org.BouncyCastle.Crypto.Tls
/// <remarks>Some helper functions for MicroTLS.</remarks>
public class TlsUtilities
{
+ public static readonly byte[] EmptyBytes = new byte[0];
+
+ public static void CheckUint8(int i)
+ {
+ if (!IsValidUint8(i))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ public static void CheckUint16(int i)
+ {
+ if (!IsValidUint16(i))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ public static void CheckUint24(int i)
+ {
+ if (!IsValidUint24(i))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ public static bool IsValidUint8(int i)
+ {
+ return (i & 0xFF) == i;
+ }
+
+ public static bool IsValidUint16(int i)
+ {
+ return (i & 0xFFFF) == i;
+ }
+
+ public static bool IsValidUint24(int i)
+ {
+ return (i & 0xFFFFFF) == i;
+ }
+
internal static void WriteUint8(byte i, Stream os)
{
os.WriteByte(i);
@@ -99,6 +135,13 @@ namespace Org.BouncyCastle.Crypto.Tls
os.Write(uints, 0, uints.Length);
}
+ public static void WriteUint8ArrayWithUint8Length(byte[] uints, Stream output)
+ {
+ CheckUint8(uints.Length);
+ WriteUint8((byte)uints.Length, output);
+ WriteUint8Array(uints, output);
+ }
+
internal static void WriteUint16Array(int[] uints, Stream os)
{
for (int i = 0; i < uints.Length; ++i)
@@ -140,6 +183,16 @@ namespace Org.BouncyCastle.Crypto.Tls
return (i1 << 16) | (i2 << 8) | i3;
}
+ public static byte[] ReadFully(int length, Stream input)
+ {
+ if (length < 1)
+ return EmptyBytes;
+ byte[] buf = new byte[length];
+ if (length != Streams.ReadFully(input, buf))
+ throw new EndOfStreamException();
+ return buf;
+ }
+
internal static void ReadFully(byte[] buf, Stream inStr)
{
if (Streams.ReadFully(inStr, buf, 0, buf.Length) < buf.Length)
@@ -162,6 +215,12 @@ namespace Org.BouncyCastle.Crypto.Tls
return bytes;
}
+ public static byte[] ReadOpaque24(Stream input)
+ {
+ int length = ReadUint24(input);
+ return ReadFully(length, input);
+ }
+
internal static void CheckVersion(byte[] readVersion)
{
if ((readVersion[0] != 3) || (readVersion[1] != 1))
@@ -180,6 +239,30 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
+ public static Asn1Object ReadAsn1Object(byte[] encoding)
+ {
+ Asn1InputStream asn1 = new Asn1InputStream(encoding);
+ Asn1Object result = asn1.ReadObject();
+ if (null == result)
+ throw new TlsFatalAlert(AlertDescription.decode_error);
+ if (null != asn1.ReadObject())
+ throw new TlsFatalAlert(AlertDescription.decode_error);
+ return result;
+ }
+
+ public static Asn1Object ReadDerObject(byte[] encoding)
+ {
+ /*
+ * NOTE: The current ASN.1 parsing code can't enforce DER-only parsing, but since DER is
+ * canonical, we can check it by re-encoding the result and comparing to the original.
+ */
+ Asn1Object result = ReadAsn1Object(encoding);
+ byte[] check = result.GetEncoded(Asn1Encodable.Der);
+ if (!Arrays.AreEqual(check, encoding))
+ throw new TlsFatalAlert(AlertDescription.decode_error);
+ return result;
+ }
+
internal static void WriteGmtUnixTime(byte[] buf, int offset)
{
int t = (int)(DateTimeUtilities.CurrentUnixMs() / 1000L);
@@ -201,6 +284,35 @@ namespace Org.BouncyCastle.Crypto.Tls
buf[offset + 1] = 1;
}
+ public static void EncodeSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms, bool allowAnonymous,
+ Stream output)
+ {
+ if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1
+ || supportedSignatureAlgorithms.Count >= (1 << 15))
+ {
+ throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms");
+ }
+
+ // supported_signature_algorithms
+ int length = 2 * supportedSignatureAlgorithms.Count;
+ TlsUtilities.CheckUint16(length);
+ TlsUtilities.WriteUint16(length, output);
+
+ foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms)
+ {
+ if (!allowAnonymous && entry.Signature == SignatureAlgorithm.anonymous)
+ {
+ /*
+ * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used
+ * in Section 7.4.3. It MUST NOT appear in this extension.
+ */
+ throw new ArgumentException(
+ "SignatureAlgorithm.anonymous MUST NOT appear in the signature_algorithms extension");
+ }
+ entry.Encode(output);
+ }
+ }
+
private static void hmac_hash(IDigest digest, byte[] secret, byte[] seed, byte[] output)
{
HMac mac = new HMac(digest);
|