From 0b4a093a66ffa77fd60e0a9c229f915b30cfe507 Mon Sep 17 00:00:00 2001 From: Peter Dennis Bartok Date: Tue, 31 Jan 2017 06:08:02 -0700 Subject: [PATCH] - Added checking of SubjectAltName entries to ssl remote certificate name verification --- src/ModernHttpClient/Utility.cs | 38 ++++++++++++++++++- .../iOS/NSUrlSessionHandler.cs | 6 +++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/ModernHttpClient/Utility.cs b/src/ModernHttpClient/Utility.cs index f2b0ed9..4a3d061 100644 --- a/src/ModernHttpClient/Utility.cs +++ b/src/ModernHttpClient/Utility.cs @@ -1,12 +1,46 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Security.Cryptography.X509Certificates; +using Mono.Security.X509.Extensions; namespace ModernHttpClient { internal static class Utility { - public static bool MatchHostnameToPattern(string hostname, string pattern) - { + const string subjectAltNameOid = "2.5.29.17"; + + internal static List GetSans(X509Certificate2 certificate) { + Mono.Security.X509.X509Certificate mono_cert; + Mono.Security.X509.X509Extension ext; + SubjectAltNameExtension san; + List result; + + result = new List(); + try { + mono_cert = new Mono.Security.X509.X509Certificate(certificate.RawData); + ext = mono_cert.Extensions[subjectAltNameOid]; + if (ext == null) { + return result; + } + + san = new SubjectAltNameExtension(ext); + if (san != null) { + result.AddRange(san.DNSNames); + result.AddRange(san.IPAddresses); + } + + return result; + } catch (Exception ex) { + return result; + } + } + + public static bool MatchHostnameToPattern(string hostname, string pattern) { + if (string.IsNullOrWhiteSpace(hostname)) { + return false; + } + // check if this is a pattern int index = pattern.IndexOf('*'); if (index == -1) { diff --git a/src/ModernHttpClient/iOS/NSUrlSessionHandler.cs b/src/ModernHttpClient/iOS/NSUrlSessionHandler.cs index 610999d..de20bda 100644 --- a/src/ModernHttpClient/iOS/NSUrlSessionHandler.cs +++ b/src/ModernHttpClient/iOS/NSUrlSessionHandler.cs @@ -330,7 +330,13 @@ public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask var subject = root.Subject; var subjectCn = cnRegex.Match(subject).Groups[1].Value; + bool match; + List subjects; + match = false; + subjects = Utility.GetSans(root); + subjects.Insert(0, subjectCn); + for (int i = 0; i < subjects.Count; i++) { if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; goto sslErrorVerify;