244 lines
8.7 KiB
C#
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
|