Implement unique name_type restriction from RFC 6066
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);
+ }
}
}
|