summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-12-11 12:33:38 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-12-11 12:33:38 +0700
commitd843bc61a003d11b1ffe0bd8f871783ea27ff292 (patch)
tree490dee929c1f75c60747ee948c6ee8263a1d9644 /crypto/src
parentPort of a few Java updates (diff)
downloadBouncyCastle.NET-ed25519-d843bc61a003d11b1ffe0bd8f871783ea27ff292.tar.xz
Port of unexpected server extension mechanism, including special case for Supported Elliptic Curves
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/tls/AbstractTlsClient.cs44
1 files changed, 36 insertions, 8 deletions
diff --git a/crypto/src/crypto/tls/AbstractTlsClient.cs b/crypto/src/crypto/tls/AbstractTlsClient.cs
index 8b6e85af5..771bc004b 100644
--- a/crypto/src/crypto/tls/AbstractTlsClient.cs
+++ b/crypto/src/crypto/tls/AbstractTlsClient.cs
@@ -30,6 +30,32 @@ namespace Org.BouncyCastle.Crypto.Tls
             this.mCipherFactory = cipherFactory;
         }
 
+        protected virtual bool AllowUnexpectedServerExtension(int extensionType, byte[] extensionData)
+        {
+            switch (extensionType)
+            {
+            case ExtensionType.elliptic_curves:
+                /*
+                 * Exception added based on field reports that some servers do send this, although the
+                 * Supported Elliptic Curves Extension is clearly intended to be client-only. If
+                 * present, we still require that it is a valid EllipticCurveList.
+                 */
+                TlsEccUtilities.ReadSupportedEllipticCurvesExtension(extensionData);
+                return true;
+            default:
+                return false;
+            }
+        }
+
+        protected virtual void CheckForUnexpectedServerExtension(IDictionary serverExtensions, int extensionType)
+        {
+            byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType);
+            if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData))
+            {
+                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+            }
+        }
+
         public virtual void Init(TlsClientContext context)
         {
             this.mContext = context;
@@ -187,16 +213,18 @@ namespace Org.BouncyCastle.Crypto.Tls
                 /*
                  * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension.
                  */
-                if (serverExtensions.Contains(ExtensionType.signature_algorithms))
-                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+                CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms);
 
-                int[] namedCurves = TlsEccUtilities.GetSupportedEllipticCurvesExtension(serverExtensions);
-                if (namedCurves != null)
-                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+                CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.elliptic_curves);
 
-                this.mServerECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(serverExtensions);
-                if (this.mServerECPointFormats != null && !TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite))
-                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+                if (TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite))
+                {
+                    this.mServerECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(serverExtensions);
+                }
+                else
+                {
+                    CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats);
+                }
             }
         }