MoneyServer/addon-modules/OpenSim-Modules-Currency/OpenSim.Modules.Currency/NSLCertificateTools.cs

221 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) Contributors, http://www.nsl.tuis.ac.jp
*
*/
#pragma warning disable S1128 // Unused "using" should be removed
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Net;
using System.Net.Security;
using System.Text;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using log4net;
#pragma warning restore S1128 // Unused "using" should be removed
namespace NSL.Certificate.Tools
{
/// <summary>
/// class NSL Certificate Verify
/// </summary>
public class NSLCertificateVerify
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private X509Chain m_chain = null;
private X509Certificate2 m_cacert = null;
private Mono.Security.X509.X509Crl m_clientcrl = null;
/// <summary>
/// NSL Certificate Verify
/// </summary>
public NSLCertificateVerify()
{
m_chain = null;
m_cacert = null;
m_clientcrl = null;
}
/// <summary>
/// NSL Certificate Verify
/// </summary>
/// <param name="certfile"></param>
public NSLCertificateVerify(string certfile)
{
SetPrivateCA(certfile);
}
/// <summary>
/// NSL Certificate Verify
/// </summary>
/// <param name="certfile"></param>
/// <param name="crlfile"></param>
public NSLCertificateVerify(string certfile, string crlfile)
{
SetPrivateCA (certfile);
}
/// <summary>
/// Set Private CA
/// </summary>
/// <param name="certfile"></param>
public void SetPrivateCA(string certfile)
{
try {
m_cacert = new X509Certificate2(certfile);
}
catch (Exception ex)
{
m_cacert = null;
m_log.ErrorFormat("[SET PRIVATE CA]: CA File reading error [{0}]. {1}", certfile, ex);
}
if (m_cacert!=null) {
m_chain = new X509Chain();
m_chain.ChainPolicy.ExtraStore.Add(m_cacert);
m_chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
m_chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
}
}
/// <summary>
/// Check Private Chain
/// </summary>
/// <param name="cert"></param>
/// <returns></returns>
public bool CheckPrivateChain(X509Certificate2 cert)
{
if (m_chain==null || m_cacert==null) {
return false;
}
bool ret = m_chain.Build((X509Certificate2)cert);
if (ret) {
return true;
}
for (int i=0; i<m_chain.ChainStatus.Length; i++)
{
if (m_chain.ChainStatus[i].Status==X509ChainStatusFlags.UntrustedRoot) return true;
}
//
return false;
}
/// <summary>
/// Validate Server Certificate
/// </summary>
/// <param name="obj"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
public bool ValidateServerCertificate(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (obj is HttpWebRequest)
{
HttpWebRequest Request = (HttpWebRequest)obj;
string noVerify = Request.Headers.Get("NoVerifyCert");
if (noVerify!=null && noVerify.ToLower()=="true")
{
return true;
}
}
X509Certificate2 certificate2 = new X509Certificate2(certificate);
string simplename = certificate2.GetNameInfo(X509NameType.SimpleName, false);
// None, ChainErrors Error except for
if (sslPolicyErrors!=SslPolicyErrors.None && sslPolicyErrors!=SslPolicyErrors.RemoteCertificateChainErrors) {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: ValidateServerCertificate: Policy Error! {0}", sslPolicyErrors);
return false;
}
bool valid = CheckPrivateChain(certificate2);
if (valid) {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: Valid Server Certification for \"{0}\"", simplename);
}
else {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: Failed to Verify Server Certification for \"{0}\"", simplename);
}
return valid;
}
/// <summary>
/// Validate Client Certificate
/// </summary>
/// <param name="obj"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
public bool ValidateClientCertificate(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
X509Certificate2 certificate2 = new X509Certificate2(certificate);
string simplename = certificate2.GetNameInfo(X509NameType.SimpleName, false);
// None, ChainErrors 以外は全てエラーとする.
if (sslPolicyErrors!=SslPolicyErrors.None && sslPolicyErrors!=SslPolicyErrors.RemoteCertificateChainErrors) {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Policy Error! {0}", sslPolicyErrors);
return false;
}
// check CRL
if (m_clientcrl!=null) {
Mono.Security.X509.X509Certificate monocert = new Mono.Security.X509.X509Certificate(certificate.GetRawCertData());
Mono.Security.X509.X509Crl.X509CrlEntry entry = m_clientcrl.GetCrlEntry(monocert);
if (entry!=null) {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Common Name \"{0}\" was revoked at {1}", simplename, entry.RevocationDate.ToString());
return false;
}
}
bool valid = CheckPrivateChain(certificate2);
if (valid) {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Valid Client Certification for \"{0}\"", simplename);
}
else {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Failed to Verify Client Certification for \"{0}\"", simplename);
}
return valid;
}
}
/// <summary>
/// class NSL Certificate Policy
/// </summary>
public class NSLCertificatePolicy : ICertificatePolicy
{
/// <summary>
/// Check Validation Result
/// </summary>
/// <param name="srvPoint"></param>
/// <param name="certificate"></param>
/// <param name="request"></param>
/// <param name="certificateProblem"></param>
/// <returns></returns>
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
if (certificateProblem == 0 || //normal
certificateProblem == -2146762487 || //Not trusted?
certificateProblem == -2146762495 || //Expired
certificateProblem == -2146762481) { //Incorrect name?
return true;
}
else {
return false;
}
}
}
}