347 lines
14 KiB
C#

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<X509Certificate2> _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<X509Certificate2>();
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<IManagedReference> list = new List<IManagedReference>();
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<IManagedReference> list = new List<IManagedReference>();
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));
}
}
}