Commit eaee8520 authored by Marvin S. Addison's avatar Marvin S. Addison
Browse files

Certificate verification must include standard X.509 path validation in

addition to custom hostname verification.  Rename classes to indicate broader
scope of function.


git-svn-id: https://svn.middleware.vt.edu/svn/ed/edsamples@10063 fa4a4108-76f2-0310-9f0d-ba9fffaf4ff6
parent f460cc24
......@@ -37,7 +37,7 @@ namespace EdAuthTest
// Must use custom hostname verification strategy due to DNS aliases
conn.SessionOptions.VerifyServerCertificate += new VerifyServerCertificateCallback(
new EdHostnameVerifier(ldapHost).VerifyCertificate);
new EdCertificateVerifier(ldapHost).VerifyCertificate);
// A QueryClientCertificateCallback is required based on our testing.
// We can only imagine that this handler is required when the SSL handshake
......
......@@ -2,14 +2,16 @@
using System.Diagnostics;
using System.DirectoryServices.Protocols;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
namespace EdCommon
{
public class EdHostnameVerifier
public class EdCertificateVerifier
{
public const string SUBJECT_ALT_NAME_OID = "2.5.29.17";
private static readonly Regex CN_REGEX = new Regex(@"CN\s*=\s*([A-Za-z0-9._-]+)");
public EdHostnameVerifier(string hostName)
public EdCertificateVerifier(string hostName)
{
if (hostName == null)
{
......@@ -28,12 +30,37 @@ namespace EdCommon
{
Trace.WriteLine("Verifying certificate for host " + connection.SessionOptions.HostName);
X509Certificate2 extendedCert = new X509Certificate2(certificate);
X509Extension subjectAltNames = extendedCert.Extensions[SUBJECT_ALT_NAME_OID];
// Perform standard X.509 path validation
bool valid = extendedCert.Verify();
// Custom hostname verification
if (valid)
{
valid = CommonNameMatches(extendedCert) || SubjectAltNameMatches(extendedCert);
}
return valid;
}
private bool CommonNameMatches(X509Certificate2 cert)
{
Match m = CN_REGEX.Match(cert.Subject);
string cn = null;
if (m.Success && m.Groups.Count > 0)
{
cn = m.Groups[1].Value;
}
return string.Compare(cn, HostName, true) == 0;
}
private bool SubjectAltNameMatches(X509Certificate2 cert)
{
X509Extension subjectAltNames = cert.Extensions[SUBJECT_ALT_NAME_OID];
if (subjectAltNames != null)
{
foreach (string altName in subjectAltNames.Format(true).Split('\n'))
{
Trace.WriteLine("Evaluating alt name " + altName);
Trace.WriteLine("Evaluating subject alt name " + altName);
if (altName.Trim().EndsWith(HostName))
{
return true;
......
......@@ -47,7 +47,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="EdConstants.cs" />
<Compile Include="EdHostnameVerifier.cs" />
<Compile Include="EdCertificateVerifier.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
......
......@@ -36,7 +36,7 @@ namespace EdIdTest
// Must use custom hostname verification strategy due to DNS aliases
conn.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(
new EdHostnameVerifier(ldapHost).VerifyCertificate);
new EdCertificateVerifier(ldapHost).VerifyCertificate);
// Look up client cert in Local Machine store by subject CN
conn.SessionOptions.QueryClientCertificate =
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment