From 605ef991b309a87a2ec590625ba449081c806274 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 10 Mar 2016 13:44:13 +0700 Subject: Implement unique name_type restriction from RFC 6066 --- crypto/src/crypto/tls/NameType.cs | 5 +++++ crypto/src/crypto/tls/ServerNameList.cs | 27 +++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/crypto/src/crypto/tls/NameType.cs b/crypto/src/crypto/tls/NameType.cs index 25f6046fc..782164215 100644 --- a/crypto/src/crypto/tls/NameType.cs +++ b/crypto/src/crypto/tls/NameType.cs @@ -8,5 +8,10 @@ namespace Org.BouncyCastle.Crypto.Tls * RFC 3546 3.1. */ public const byte host_name = 0; + + public static bool IsValid(byte nameType) + { + return nameType == host_name; + } } } diff --git a/crypto/src/crypto/tls/ServerNameList.cs b/crypto/src/crypto/tls/ServerNameList.cs index 13da79bf6..5b5b90e58 100644 --- a/crypto/src/crypto/tls/ServerNameList.cs +++ b/crypto/src/crypto/tls/ServerNameList.cs @@ -15,8 +15,8 @@ namespace Org.BouncyCastle.Crypto.Tls */ public ServerNameList(IList serverNameList) { - if (serverNameList == null || serverNameList.Count < 1) - throw new ArgumentException("must not be null or empty", "serverNameList"); + if (serverNameList == null) + throw new ArgumentNullException("serverNameList"); this.mServerNameList = serverNameList; } @@ -40,8 +40,13 @@ namespace Org.BouncyCastle.Crypto.Tls { MemoryStream buf = new MemoryStream(); + byte[] nameTypesSeen = TlsUtilities.EmptyBytes; foreach (ServerName entry in ServerNames) { + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (nameTypesSeen == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + entry.Encode(buf); } @@ -68,14 +73,32 @@ namespace Org.BouncyCastle.Crypto.Tls MemoryStream buf = new MemoryStream(data, false); + byte[] nameTypesSeen = TlsUtilities.EmptyBytes; IList server_name_list = Platform.CreateArrayList(); while (buf.Position < buf.Length) { ServerName entry = ServerName.Parse(buf); + + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (nameTypesSeen == null) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + server_name_list.Add(entry); } return new ServerNameList(server_name_list); } + + private static byte[] CheckNameType(byte[] nameTypesSeen, byte nameType) + { + /* + * RFC 6066 3. The ServerNameList MUST NOT contain more than one name of the same + * name_type. + */ + if (!NameType.IsValid(nameType) || Arrays.Contains(nameTypesSeen, nameType)) + return null; + + return Arrays.Append(nameTypesSeen, nameType); + } } } -- cgit 1.4.1