using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography; using System.Management.Automation; using System.Management.Automation.Provider; using Intel.Management.Wsman; namespace Intel.Management.PSModule.Amt { class CertificateServices : DriveContainer { class CertificateReader : IContentReader { IManagedReference _refToService; List _list; bool _includeTrusted; public CertificateReader(IManagedReference refToService, bool includedTrusted) { _refToService = refToService; _includeTrusted = includedTrusted; } public void Dispose() { } public void Close() { } public void Seek(long offset, System.IO.SeekOrigin origin) { } public System.Collections.IList Read(long size) { System.Collections.IList content = new System.Collections.ArrayList(); if (_list == null) { _list = new List(); IWsmanEnumeration colObj = _refToService.Enumerate(null, null); foreach (IWsmanItem item in colObj) { if ((item.Object.GetProperty("TrustedRootCertficate").ToString().Equals("true") && _includeTrusted) || (item.Object.GetProperty("TrustedRootCertficate").ToString().Equals("false") && !_includeTrusted)) { string certString = item.Object.GetProperty("X509Certificate").ToString(); _list.Add(new X509Certificate2(Convert.FromBase64String(certString))); } } } if (_list != null) { for (long i = 0; i < size && _list.Count > 0; i++) { content.Add(_list[0]); _list.RemoveAt(0); } } return content; } } class CertificateWriter : IContentWriter { IManagedReference _refToService; string _addMethod; bool _includePrivateKey; bool _includeTlsProtocol; public CertificateWriter(IManagedReference refToService) { _includeTlsProtocol = true; _includePrivateKey = true; _addMethod = "AddCertificate"; _refToService = refToService; } public CertificateWriter(IManagedReference refToService,string store,bool includeKey) { _includeTlsProtocol = false; _includePrivateKey = includeKey; _addMethod = "Add" + store; _refToService = refToService; } public void Dispose() { } public void Close() { } public void Seek(long offset, System.IO.SeekOrigin origin) { } public System.Collections.IList Write(System.Collections.IList content) { byte[] keyData = null; byte[] certData = null; IManagedReference refToCertificate=null; if (content.Count > 0) { X509Certificate2 cert2 = null; if (content[0] is PSObject) { if (((PSObject)content[0]).BaseObject is X509Certificate2) cert2 = (X509Certificate2)content[0]; } else if ((content[0] is X509Certificate2)) cert2 = (X509Certificate2)content[0]; if (cert2 == null) throw new FormatException(); if (cert2.HasPrivateKey && _includePrivateKey) { if (cert2.PrivateKey is RSACryptoServiceProvider) { keyData = Intel.Management.Mei.KeyFormatter.EncodeKey(cert2.PrivateKey as RSACryptoServiceProvider, true); } } certData = cert2.RawData; if (keyData != null ) { IManagedInstance inputObj = _refToService.CreateMethodInput("AddKey"); inputObj.SetProperty("KeyBlob", Convert.ToBase64String(keyData)); IManagedInstance outObj = _refToService.InvokeMethod(inputObj); string result = outObj.GetProperty("ReturnValue").ToString(); if (!result.Equals("0") && !result.Equals("2058")) { if (result.Equals("2062")) AmtException.ThrowInvokeError(outObj, "Invalid Key"); else if (result.Equals("1")) AmtException.ThrowInvokeError(outObj, "Internal Error"); else if (result.Equals("23")) AmtException.ThrowInvokeError(outObj, "Max limit reached"); else if (result.Equals("38")) AmtException.ThrowInvokeError(outObj, "Flash write limit reached"); else AmtException.ThrowInvokeError(outObj); } } if (certData != null) { IManagedInstance inputObj = _refToService.CreateMethodInput(_addMethod); inputObj.SetProperty("CertificateBlob", Convert.ToBase64String(certData)); IManagedInstance outObj = _refToService.InvokeMethod(inputObj); string result = outObj.GetProperty("ReturnValue").ToString(); if (!result.Equals("0") && !result.Equals("2058")) { if (result.Equals("2063")) AmtException.ThrowInvokeError(outObj, "Invalid Certificate"); else if (result.Equals("1")) AmtException.ThrowInvokeError(outObj, "Internal Error"); else if (result.Equals("23")) AmtException.ThrowInvokeError(outObj, "Max limit reached"); else if (result.Equals("38")) AmtException.ThrowInvokeError(outObj, "Flash write limit reached"); else AmtException.ThrowInvokeError(outObj); } refToCertificate = outObj.GetProperty("CreatedCertificate").Ref; if (refToCertificate == null) { //find the duplicate and get reference to it string certString = Convert.ToBase64String(certData); IWsmanEnumeration colObj = _refToService.Connection.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate"); foreach (IWsmanItem item in colObj) { if (string.Compare(item.Object.GetProperty("X509Certificate").ToString(), certString, true)==0) { refToCertificate = _refToService.Connection.NewReference("AMT_PublicKeyCertificate"); refToCertificate.AddSelector("InstanceID", item.Object.GetProperty("InstanceID").ToString()); } } } } if (_includeTlsProtocol) { IManagedReference refToCollection = _refToService.Connection.NewReference("AMT_TLSProtocolEndpointCollection"); refToCollection.AddSelector("ElementName","TLSProtocolEndpoint Instances Collection"); IManagedReference refToCred = _refToService.Connection.NewReference("AMT_TLSCredentialContext"); IManagedInstance credObj = _refToService.Connection.NewInstance("AMT_TLSCredentialContext"); credObj.SetProperty("ElementInContext", refToCertificate); credObj.SetProperty("ElementProvidingContext", refToCollection); credObj.Create(); } } return content; } } class TrustedCerts : DriveItem { public TrustedCerts(DriveItem parent) : base("TrustedRoots", parent) { } public override void ClearContent(DriveProvider provider) { CertificateServices service = (CertificateServices)_parent; List list = new List(); IWsmanEnumeration colObj = service._conn.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate"); foreach (IWsmanItem item in colObj) { if (item.Object.GetProperty("TrustedRootCertficate").Equals("true")) { IManagedReference refToCert = service._conn.NewReference("AMT_PublicKeyCertificate"); refToCert.AddSelector("InstanceID",item.Object.GetProperty("InstanceID").ToString()); list.Add(refToCert); } } foreach (IManagedReference refToCert in list) { refToCert.Delete(); } } public override IContentWriter GetContentWriter(DriveProvider provider) { CertificateServices service = (CertificateServices)_parent; IManagedReference refToService = service._conn.NewReference("AMT_PublicKeyManagementService"); return new CertificateWriter(refToService, "TrustedRootCertificate", false); } public override IContentReader GetContentReader(DriveProvider provider) { CertificateServices service = (CertificateServices)_parent; IManagedReference refToService = service._conn.NewReference("AMT_PublicKeyCertificate"); return new CertificateReader(refToService,true); } } class MeCerts : DriveItem { public MeCerts(DriveItem parent) : base("ME", parent) { } public override void ClearContent(DriveProvider provider) { CertificateServices service = (CertificateServices)_parent; List list = new List(); IWsmanEnumeration colObj = service._conn.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate"); foreach (IWsmanItem item in colObj) { if (item.Object.GetProperty("TrustedRootCertficate").Equals("false")) { IManagedReference refToCert = service._conn.NewReference("AMT_PublicKeyCertificate"); refToCert.AddSelector("InstanceID", item.Object.GetProperty("InstanceID").ToString()); list.Add(refToCert); } } // find assocated private keys (if any) /*colObj = service._conn.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate"); foreach (IWsmanItem item in colObj) { if (item.Object.GetProperty("TrustedRootCertficate").Equals("false")) { IManagedReference refToCert = service._conn.NewReference("AMT_PublicKeyCertificate"); refToCert.AddSelector("InstanceID", item.Object.GetProperty("InstanceID").ToString()); list.Add(refToCert); } }*/ foreach (IManagedReference refToCert in list) { refToCert.Delete(); } } public override IContentWriter GetContentWriter(DriveProvider provider) { CertificateServices service = (CertificateServices)_parent; IManagedReference refToService = service._conn.NewReference("AMT_PublicKeyManagementService"); return new CertificateWriter(refToService, "Certificate", true); } public override IContentReader GetContentReader(DriveProvider provider) { CertificateServices service = (CertificateServices)_parent; IManagedReference refToService = service._conn.NewReference("AMT_PublicKeyCertificate"); return new CertificateReader(refToService, false); } } IWsmanConnection _conn; public CertificateServices(IWsmanConnection conn, DriveItem parent) : base("Certificates",parent) { _conn = conn; } public override void GetChildItems(ChildWriter writer) { writer.Add(new MeCerts(this)); writer.Add(new TrustedCerts(this)); } } }