serverRoom/amt-sdk-20-0-0-1/WebStorageModule/Src/WebStorageConnectionOptions.cs

244 lines
8.7 KiB
C#

using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Security;
namespace Intel.WebStorage
{
class WebStorageConnectionOptions : IWebStorageConnectionOptions
{
public const int MAX_PWD_LENGTH = 32;
public const int MIN_PWD_LENGTH = 8;
public const int MAX_USERNAME_LENGTH = 32;
//Client certificate OIDs
private const string OID_LOCAL = "2.16.840.1.113741.1.2.2";
private const string OID_REMOTE = "2.16.840.1.113741.1.2.1";
// Max timeout is 100 seconds. This is the default timeout for httpClient timeout
// (https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.timeout?view=netframework-4.8)
private const int MAX_TIME_OUT = 100000;
private const int DEFAULT_TIME_OUT = 30000;
private const int MIN_TIME_OUT = 5000;
private int _timeout;
private X509Certificate2 _clientCert;
private string _clientCertificareCN;
private string _proxyUser;
private string _proxyAddress;
private SecureString _proxyPassword;
private ServerCertificateValidationCallback _serverCertificateValidationCallback;
public WebStorageConnectionOptions()
{
_timeout = DEFAULT_TIME_OUT; //default 30 second time for sleeping ME
_clientCertificareCN = null;
_clientCert = null;
_proxyAddress = null;
_proxyUser = null;
_proxyPassword = null;
}
public int TimeOut
{
get { return _timeout; }
set
{
if (value > MAX_TIME_OUT || value < MIN_TIME_OUT)
throw new WebStorageException("Time out value must be between the range " + MIN_TIME_OUT.ToString() + " and " + MAX_TIME_OUT.ToString()); ;
_timeout = value;
}
}
public string ClientCertificateCommonName
{
get { return _clientCertificareCN; }
set
{
if (!String.IsNullOrEmpty(value))
{
// In the common name field of the DN of a X509 certificate, the limit is up to 64 characters
if (value.Length > 64)
throw new WebStorageException("Invalid argument - invalid certificate CN");
ClientCertificate = getCertFromStore(value)[0]; //If empty string the WebStorage will search a certificate with the appropriate OIDs
}
_clientCertificareCN = value;
}
}
/// <summary>
/// The certificate to use for establishing the connection.
/// To set this property by providing a certificate name string only, use the ClientCertificateCommonName property.
/// </summary>
public X509Certificate2 ClientCertificate
{
get
{
return _clientCert;
}
set
{
_clientCertificareCN = null;
_clientCert = value;
}
}
public string ProxyUser
{
get
{
return _proxyUser;
}
set
{
if (String.IsNullOrEmpty(value))
_proxyUser = "";
else
{
_proxyUser = value;
if (_proxyUser.Length > MAX_USERNAME_LENGTH)
throw new WebStorageException("Invalid Argument - Username can contain up to 32 characters.");
}
}
}
public SecureString ProxyPassword
{
get
{
return _proxyPassword;
}
set
{
if (value == null || value.Length == 0 )
{
_proxyPassword = new SecureString();
}
else
{
if (value.Length < MIN_PWD_LENGTH || value.Length > MAX_PWD_LENGTH)
throw new WebStorageException("Invalid Argument - Password can contain between 8 to 32 characters.");
_proxyPassword?.Dispose();
_proxyPassword = value;
}
}
}
public string ProxyAddress
{
get
{
return _proxyAddress;
}
set
{
if (String.IsNullOrEmpty(value))
throw new WebStorageException("Host name is null or an empty string.");
if (!Uri.IsWellFormedUriString(value, 0))
throw new WebStorageException("Incorrect uri.");
_proxyAddress = value;
}
}
public IWebProxy Proxy
{
get
{
WebProxy result = null;
if (_proxyAddress != null)
{
result = new WebProxy(_proxyAddress, false);
}
if (result != null && _proxyUser != null && _proxyPassword != null)
{
result.Credentials = new NetworkCredential(_proxyUser, _proxyPassword.Copy());
}
return result;
}
}
public ServerCertificateValidationCallback ServerCertificateValidationCallback
{
get
{
return _serverCertificateValidationCallback;
}
set
{
_serverCertificateValidationCallback = value;
}
}
//Return a specific certificate from the cert store.
//If empty string the WebStorage will search a certificate with the appropriate OIDs
private X509Certificate2Collection getCertFromStore(String clientCert)
{
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection();
// Open CurrentUser cert store
X509EnhancedKeyUsageExtension ex;
using (X509Store currentUserStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
currentUserStore.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 certificate in currentUserStore.Certificates)
{
if (String.Compare(clientCert, "") == 0 || certificate.Subject.ToLower().Contains(clientCert.ToLower()))
{
// Checking that the Enhanced Key Usage in the certificate is the one for AMT
foreach (X509Extension extension in certificate.Extensions)
{
ex = extension as X509EnhancedKeyUsageExtension;
if (ex != null)
{
foreach (Oid OID in ex.EnhancedKeyUsages)
{
if (OID.Value == OID_REMOTE || OID.Value == OID_LOCAL)
certificatesCollection.Add(certificate);
}
}
}
}
}
}
// Open LocalMachine cert store
using (X509Store localMachineStore = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
localMachineStore.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 certificate in localMachineStore.Certificates)
{
if (String.Compare(clientCert, "") == 0 || certificate.Subject.ToLower().Contains(clientCert.ToLower()))
{
// Checking that the Enhanced Key Usage in the certificate is the one for AMT
foreach (X509Extension extension in certificate.Extensions)
{
ex = extension as X509EnhancedKeyUsageExtension;
if (ex != null)
{
foreach (Oid OID in ex.EnhancedKeyUsages)
{
if (OID.Value == OID_REMOTE || OID.Value == OID_LOCAL)
certificatesCollection.Add(certificate);
}
}
}
}
}
}
if (certificatesCollection.Count < 1)
throw new WebStorageException("Can not find appropriate certificate in certificate store");
return certificatesCollection;
}
}
}//end namspace