github的源码。直接用vs2017运行,新版的代码在vs2015上是运行不了的。
1、修改上的坑
2、部署的问题
private static void CheckCertificateDomain(ConfiguredEndpoint endpoint) { bool domainFound = false; X509Certificate2 serverCertificate = new X509Certificate2(endpoint.Description.ServerCertificate); // check the certificate domains. IList<string> domains = Utils.GetDomainsFromCertficate(serverCertificate); if (domains != null) { string hostname; string dnsHostName = hostname = endpoint.EndpointUrl.DnsSafeHost; bool isLocalHost = false; if (endpoint.EndpointUrl.HostNameType == UriHostNameType.Dns) { if (dnsHostName.ToLowerInvariant() == "localhost") { isLocalHost = true; } else { // strip domain names from hostname hostname = dnsHostName.Split('.')[0]; } } else { // dnsHostname is a IPv4 or IPv6 address // normalize ip addresses, cert parser returns normalized addresses hostname = Utils.NormalizedIPAddress(dnsHostName); if (hostname == "127.0.0.1" || hostname == "::1") { isLocalHost = true; } } if (isLocalHost) { dnsHostName = Utils.GetFullQualifiedDomainName(); hostname = Utils.GetHostName(); } for (int ii = 0; ii < domains.Count; ii++) { if (String.Compare(hostname, domains[ii], StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(dnsHostName, domains[ii], StringComparison.OrdinalIgnoreCase) == 0) { domainFound = true; break; } } } if (!domainFound) { string message = Utils.Format( "The domain '{0}' is not listed in the server certificate.", endpoint.EndpointUrl.DnsSafeHost); throw new ServiceResultException(StatusCodes.BadCertificateHostNameInvalid, message); } }
看到domainFound是去判断连接的地址是不是在证书里面。domains这个列表是怎么得到的。
public static IList<string> GetDomainsFromCertficate(X509Certificate2 certificate) { List<string> dnsNames = new List<string>(); // extracts the domain from the subject name. List<string> fields = Utils.ParseDistinguishedName(certificate.Subject); StringBuilder builder = new StringBuilder(); for (int ii = 0; ii < fields.Count; ii++) { if (fields[ii].StartsWith("DC=")) { if (builder.Length > 0) { builder.Append('.'); } builder.Append(fields[ii].Substring(3)); } } if (builder.Length > 0) { dnsNames.Add(builder.ToString().ToUpperInvariant()); } // extract the alternate domains from the subject alternate name extension. X509SubjectAltNameExtension alternateName = null; foreach (X509Extension extension in certificate.Extensions) { if (extension.Oid.Value == X509SubjectAltNameExtension.SubjectAltNameOid || extension.Oid.Value == X509SubjectAltNameExtension.SubjectAltName2Oid) { alternateName = new X509SubjectAltNameExtension(extension, extension.Critical); break; } } if (alternateName != null) { for (int ii = 0; ii < alternateName.DomainNames.Count; ii++) { string hostname = alternateName.DomainNames[ii]; // do not add duplicates to the list. bool found = false; for (int jj = 0; jj < dnsNames.Count; jj++) { if (String.Compare(dnsNames[jj], hostname, StringComparison.OrdinalIgnoreCase) == 0) { found = true; break; } } if (!found) { dnsNames.Add(hostname.ToUpperInvariant()); } } for (int ii = 0; ii < alternateName.IPAddresses.Count; ii++) { string ipAddress = alternateName.IPAddresses[ii]; if (!dnsNames.Contains(ipAddress)) { dnsNames.Add(ipAddress); } } } // return the list. return dnsNames; }
文章来源: OPC UA的源码使用