using System; using System.Collections.Generic; using System.Net; using System.Text; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography; using System.Net.Security; using System.Security; namespace Intel.Management.Wsman { class WsmanConnectionOptions : IWsmanConnectionOptions { 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"; public const int MAX_PWD_LENGTH = 32; public const int MIN_PWD_LENGTH = 8; public const int MAX_USERNAME_LENGTH = 32; private const int DEFAULT_TIME_OUT = 30000; private int _maxElements; private int _timeout; private int _maxConnections; private X509Certificate _clientCert; private InternetProtocolType _protocolType; private bool _useDmp; private bool _hidePassword; private bool _bVerifyCerts; private bool _acceptSelfSignedCertificate; private string _proxyUser; private string _proxyAddress; private SecureString _proxyPassword; private string _serviceName; private ServerCertificateValidationCallback _serverCertificateValidationCallback; public WsmanConnectionOptions() { _timeout = DEFAULT_TIME_OUT; //default 30 second time for sleeping ME _maxElements=20; _clientCert = null; _proxyAddress = null; _proxyUser = null; _proxyPassword = null; _serviceName = null; _bVerifyCerts = true; _protocolType = InternetProtocolType.IPv4; _maxConnections = 20; _acceptSelfSignedCertificate = false; } public int MaxElements { get { return _maxElements; } set { _maxElements = value; } } public int Timeout { get { return _timeout; } set { _timeout = value; } } /// /// The certificate to use for establishing the connection. /// To set this property by providing a certificate name string only, use the SetClientCertificateByCertificateName function. /// public X509Certificate ClientCertificate { get { return _clientCert; } set { _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 WsmanConnectionException("Username can contain up to 32 characters."); } } } public SecureString ProxyPassword { get { return _proxyPassword; } set { if (value == null || value.Length == 0) { _proxyPassword?.Dispose(); _proxyPassword = value ?? new SecureString(); return; } if (value.Length < MIN_PWD_LENGTH || value.Length > MAX_PWD_LENGTH) throw new WsmanConnectionException("Password can contain between 8 to 32 characters."); _proxyPassword?.Dispose(); _proxyPassword = value; } } public string ProxyAddress { get { return _proxyAddress; } set { if (!Uri.IsWellFormedUriString(value, 0)) throw new WsmanConnectionException("Invalid argument - Address is not a valid uri"); _proxyAddress = value; } } public string ServiceName { get { return _serviceName; } set { _serviceName = value; } } public bool VerifyCertificates { get { return _bVerifyCerts;; } set { _bVerifyCerts = value; } } public bool AcceptSelfSignedCertificate { get { return _acceptSelfSignedCertificate; ; } set { _acceptSelfSignedCertificate = value; } } public bool UseDigestMasterPassword { get { return _useDmp; } set { _useDmp = 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); } return result; } } public bool IsSetupCertificate(X509Certificate2 cert) { bool isSetupCert = false; // check the EnhacedKeyUsageExtention to see if its a AMTRemoteConfig Certificate foreach (X509Extension extention in cert.Extensions) { if (extention is X509EnhancedKeyUsageExtension) { X509EnhancedKeyUsageExtension enhanced = (X509EnhancedKeyUsageExtension)extention; foreach (Oid oid in enhanced.EnhancedKeyUsages) { if (oid.Value.Equals("2.16.840.1.113741.1.2.3")) { isSetupCert = true; } } } } // check to see of the subject says its an Setup Certificate if (!isSetupCert && cert.Subject.IndexOf("Intel(R) Client Setup Certificate") > 0) { isSetupCert = true; } return isSetupCert; } public bool HidePassword { get { return _hidePassword; } set { _hidePassword = value; } } public InternetProtocolType InternetProtocol { get { return _protocolType; } set { _protocolType = value; } } public int MaxConnections { get { return _maxConnections; } set { _maxConnections = value; } } public ServerCertificateValidationCallback ServerCertificateValidationCallback { get { return _serverCertificateValidationCallback; } set { _serverCertificateValidationCallback = value; } } /// /// Sets the client certificate to be used in the connection by giving the certificate name. /// ///The certificate name. public void SetClientCertificateByCertificateName(string clientCert) { if (!string.IsNullOrEmpty(clientCert)) { X509CertificateCollection collection = GetCertFromStore(clientCert); ClientCertificate = collection.Count > 0 ? collection[0] : null; } } //return a specific certificate from the cert store. private static X509CertificateCollection GetCertFromStore(string clientCert) { X509CertificateCollection certificatesCollection = new X509CertificateCollection(); // 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 (certificate.Subject.Contains(clientCert)) { // 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 (certificate.Subject.Contains(clientCert)) { // 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); } } } } } } return certificatesCollection; } #region IDisposable Implementation private bool _disposed = false; /// /// Implement IDisposable method /// /// protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { ProxyPassword?.Dispose(); } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~WsmanConnectionOptions() { Dispose(false); } #endregion } //end WsmanConnectionOptions }//end namspace