542 lines
20 KiB
C#
542 lines
20 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 TLSService : DriveContainer
|
|
{
|
|
|
|
/// <summary>
|
|
/// Construcutor
|
|
/// </summary>
|
|
/// <param name="parent"></param>
|
|
public TLSService( DriveItem parent)
|
|
: base("TLS", parent)
|
|
{
|
|
}
|
|
|
|
public override void GetChildItems(ChildWriter writer)
|
|
{
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
|
|
IManagedReference refToLocal = conn.NewReference("AMT_TLSSettingData");
|
|
refToLocal.AddSelector("InstanceID", "Intel(r) AMT LMS TLS Settings");
|
|
|
|
IManagedReference refToRemote = conn.NewReference("AMT_TLSSettingData");
|
|
refToRemote.AddSelector("InstanceID", "Intel(r) AMT 802.3 TLS Settings");
|
|
|
|
writer.Add(new Certificates(this));
|
|
writer.Add(new Credential(this));
|
|
writer.Add(new TLSSettings("LocalSettings", refToLocal, this));
|
|
writer.Add(new TLSSettings("RemoteSettings",refToRemote, this));
|
|
writer.Add(new RsaKeys(this));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public static IManagedReference GetCertificateRef(DeviceCertificate devCert, IWsmanConnection conn)
|
|
{
|
|
IManagedReference refToCert = conn.NewReference("AMT_PublicKeyCertificate");
|
|
refToCert.AddSelector("InstanceID", devCert.InstanceID);
|
|
|
|
return refToCert;
|
|
}
|
|
|
|
public static IManagedReference GetTlsCertificate(string thumbprint, IWsmanConnection conn)
|
|
{
|
|
return Certificates.FindCertificate(thumbprint, conn);
|
|
}
|
|
|
|
public override object GetReturnObject()
|
|
{
|
|
return new NameValuePairItem(Name, Value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Embedded TLSSettings container
|
|
/// </summary>
|
|
class TLSSettings : SettingsContainer
|
|
{
|
|
public TLSSettings(string name, IManagedReference refToSettings, DriveItem parent)
|
|
: base(name, parent)
|
|
{
|
|
_refToSettings = refToSettings;
|
|
}
|
|
|
|
|
|
public override void GetChildItems(ChildWriter writer)
|
|
{
|
|
base.GetChildItems(writer);
|
|
|
|
if (HasSetting("AcceptNonSecureConnections"))
|
|
writer.Add(new BooleanSetting("AcceptNonSecureConnections", this));
|
|
|
|
writer.Add(new BooleanSetting("Enabled", this));
|
|
writer.Add(new BooleanSetting("MutualAuthentication", this));
|
|
writer.Add(new StringsSetting("TrustedCN", this));
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Contains all the private keys in the store
|
|
/// </summary>
|
|
public class RsaKeys : DriveContainer
|
|
{
|
|
public RsaKeys(DriveItem parent)
|
|
: base("RsaKeys", parent)
|
|
{
|
|
}
|
|
|
|
|
|
public override void GetChildItems(ChildWriter writer)
|
|
{
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
|
|
|
|
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM AMT_PublicPrivateKeyPair");
|
|
foreach (IWsmanItem item in colObj)
|
|
{
|
|
|
|
byte[] rawData = Convert.FromBase64String(item.Object.GetProperty("DERKey").ToString());
|
|
string name = item.Object.GetProperty("InstanceID").ToString();
|
|
writer.Add(new DriveEntry(name, Intel.Management.Mei.KeyFormatter.GetRSAKey(rawData), this));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public override object GetReturnObject()
|
|
{
|
|
return new NameValuePairItem(Name, Value);
|
|
|
|
}
|
|
}
|
|
|
|
class Credential : DriveContainer
|
|
{
|
|
public Credential(DriveContainer parent)
|
|
: base("Credentials", parent)
|
|
{
|
|
}
|
|
|
|
public override void GetChildItems(ChildWriter writer)
|
|
{
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
|
|
string thumbprint = string.Empty;
|
|
DeviceCertificate devCert = null;
|
|
|
|
foreach (IWsmanItem item in conn.ExecQuery("SELECT * FROM AMT_TLSCredentialContext"))
|
|
{
|
|
IManagedInstance certObj = item.Object.GetProperty("ElementInContext").Ref.Get();
|
|
|
|
devCert = new DeviceCertificate(certObj.GetProperty("X509Certificate").ToString(),
|
|
certObj.GetProperty("InstanceID").ToString(), false);
|
|
}
|
|
|
|
if (devCert == null)
|
|
devCert = new DeviceCertificate();
|
|
|
|
writer.Add(new ServerCertificate(devCert, this));
|
|
|
|
}
|
|
|
|
|
|
public override object GetReturnObject()
|
|
{
|
|
return new NameValuePairItem(Name, Value);
|
|
}
|
|
|
|
}
|
|
|
|
class ServerCertificate : DriveEntry
|
|
{
|
|
|
|
public ServerCertificate(DeviceCertificate devCert, DriveItem parent)
|
|
: base("ServerCertificate", devCert, parent)
|
|
{
|
|
}
|
|
|
|
public override void SetItem(object values, DriveProvider provider)
|
|
{
|
|
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
|
|
//look for exising TLS Credential
|
|
IManagedReference refToContext = Certificates.FindTlsCredential(conn);
|
|
|
|
if (values == null && refToContext != null)
|
|
{
|
|
refToContext.Delete();
|
|
_value = new DeviceCertificate();
|
|
}
|
|
else if (values is DeviceCertificate)
|
|
{
|
|
IManagedReference refToCertificate = GetCertificateRef((DeviceCertificate)values, conn);
|
|
// no existing reference
|
|
if (refToContext == null)
|
|
{
|
|
provider.WriteVerbose("No existing TLS Credential found so creating one.");
|
|
|
|
IManagedReference refToCollection = conn.NewReference("AMT_TLSProtocolEndpointCollection");
|
|
refToCollection.AddSelector("ElementName", "TLSProtocolEndpoint Instances Collection");
|
|
|
|
IManagedInstance credObj = conn.NewInstance("AMT_TLSCredentialContext");
|
|
credObj.SetProperty("ElementInContext", refToCertificate);
|
|
credObj.SetProperty("ElementProvidingContext", refToCollection);
|
|
|
|
credObj.Create();
|
|
_value = (DeviceCertificate)values;
|
|
}
|
|
else
|
|
{
|
|
provider.WriteVerbose("Updating exisiting TLS Certificate");
|
|
IManagedInstance credObj = refToContext.Get();
|
|
credObj.SetProperty("ElementInContext", refToCertificate);
|
|
refToContext.Put(credObj);
|
|
_value = (DeviceCertificate)values;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new System.Management.Automation.PSArgumentException("Value must be of type DeviceCertificate");
|
|
}
|
|
|
|
} //end set item
|
|
}// end ServerCertificate
|
|
|
|
class CertificateDriveItem : DriveItem
|
|
{
|
|
string[] _properties;
|
|
|
|
public override string[] Properties
|
|
{
|
|
get
|
|
{
|
|
return _properties;
|
|
}
|
|
}
|
|
|
|
public CertificateDriveItem(DeviceCertificate cert, DriveItem parent)
|
|
: base(cert.Thumbprint, cert, parent)
|
|
{
|
|
|
|
_properties = new string[2];
|
|
_properties[0] = "TrustedRootCertificate";
|
|
_properties[1] = "InstanceID";
|
|
|
|
}
|
|
|
|
|
|
public override void RemoveItem(DriveProvider provider)
|
|
{
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
IManagedReference refToCert = conn.NewReference("AMT_PublicKeyCertificate");
|
|
refToCert.AddSelector("InstanceID", InstanceID);
|
|
|
|
refToCert.Delete();
|
|
|
|
_parent.RemoveChildItem(this);
|
|
}
|
|
|
|
|
|
public string InstanceID
|
|
{
|
|
get { return ((DeviceCertificate)_value).InstanceID; }
|
|
}
|
|
|
|
public bool TrustedRootCertificate
|
|
{
|
|
get { return ((DeviceCertificate)_value).IsTrustedRootCertificate; }
|
|
}
|
|
|
|
|
|
public override object GetReturnObject()
|
|
{
|
|
return new CertificateItem(_value as DeviceCertificate);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Contains all certificates in the store
|
|
/// </summary>
|
|
class Certificates : DriveContainer
|
|
{
|
|
public Certificates(DriveItem parent)
|
|
: base("Certificates", parent)
|
|
{
|
|
}
|
|
|
|
|
|
public override void GetChildItems(ChildWriter writer)
|
|
{
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
|
|
|
|
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate");
|
|
foreach (IWsmanItem item in colObj)
|
|
{
|
|
|
|
|
|
//byte[] rawData = Convert.FromBase64String(item.Object.GetProperty("X509Certificate").ToString());
|
|
//X509Certificate2 cert = new X509Certificate2(rawData);
|
|
DeviceCertificate cert = new DeviceCertificate(
|
|
item.Object.GetProperty("X509Certificate").ToString(),
|
|
item.Object.GetProperty("InstanceID").ToString(),
|
|
bool.Parse(item.Object.GetProperty("TrustedRootCertficate").ToString()));
|
|
|
|
writer.Add(new CertificateDriveItem(cert, this));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override DriveItem NewItem(string name, string type, object newItem, DriveProvider provider)
|
|
{
|
|
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
|
|
|
|
if (type == null)
|
|
type = "Certificate";
|
|
|
|
if (string.Compare(type, "Certificate", true) == 0 ||
|
|
string.Compare(type, "TrustedRootCertificate", true) == 0 )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
|
|
X509Certificate2 cert = null;
|
|
|
|
if (newItem is PSObject)
|
|
{
|
|
cert = (X509Certificate2)((PSObject)newItem).BaseObject;
|
|
|
|
}
|
|
else if (newItem is X509Certificate)
|
|
{
|
|
cert = (X509Certificate2)newItem;
|
|
}
|
|
|
|
if (cert==null)
|
|
throw new PSArgumentException("Only X509 Certificates can be created in this container");
|
|
|
|
IManagedReference refToService = conn.NewReference("SELECT * FROM AMT_PublicKeyManagementService");
|
|
|
|
|
|
IManagedReference refToCertificate = AddCertificate(cert, type, refToService, false);
|
|
|
|
IManagedInstance certObj = refToCertificate.Get();
|
|
|
|
if (string.Compare(type, "TrustedRootCertificate", true) != 0)
|
|
AddCertificateKey(cert, refToService);
|
|
|
|
|
|
bool trusted = bool.Parse(certObj.GetProperty("TrustedRootCertficate").ToString());
|
|
string instanceId = certObj.GetProperty("InstanceID").ToString();
|
|
|
|
DeviceCertificate firmCert = new DeviceCertificate(cert, instanceId, trusted);
|
|
|
|
CertificateDriveItem result= new CertificateDriveItem(firmCert, this);
|
|
AddChildItem(result);
|
|
|
|
return result;
|
|
}
|
|
|
|
public static IManagedReference FindCertificate(string thumbprint, IWsmanConnection conn)
|
|
{
|
|
IManagedReference result = null;
|
|
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate");
|
|
foreach (IWsmanItem item in colObj)
|
|
{
|
|
|
|
byte[] rawData = Convert.FromBase64String(item.Object.GetProperty("X509Certificate").ToString());
|
|
X509Certificate2 cert2 = new X509Certificate2(rawData);
|
|
if (string.Compare(cert2.Thumbprint, thumbprint, true) == 0)
|
|
{
|
|
result = conn.NewReference(item.Object.ResourceUri);
|
|
result.AddSelector("InstanceID", item.Object.GetProperty("InstanceID").ToString());
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/* public static string GetTlsThumbrint(IWsmanConnection conn)
|
|
{
|
|
//look for exising TLS Credential
|
|
String result = string.Empty;
|
|
foreach (IWsmanItem item in conn.ExecQuery("SELECT * FROM AMT_TLSCredentialContext"))
|
|
{
|
|
IManagedInstance certObj = item.Object.GetProperty("ElementInContext").Ref.Get();
|
|
|
|
byte[] rawData = Convert.FromBase64String(certObj.GetProperty("X509Certificate").ToString());
|
|
X509Certificate2 cert2 = new X509Certificate2(rawData);
|
|
result = cert2.Thumbprint;
|
|
|
|
}
|
|
|
|
return result;
|
|
}*/
|
|
|
|
|
|
public static IManagedReference FindTlsCredential(IWsmanConnection conn)
|
|
{
|
|
//look for exising TLS Credential
|
|
IManagedReference refToContext = null;
|
|
foreach (IWsmanItem item in conn.ExecQuery("SELECT * FROM AMT_TLSCredentialContext"))
|
|
{
|
|
refToContext = conn.NewReference("AMT_TLSCredentialContext");
|
|
refToContext.AddSelector("ElementProvidingContext", item.Object.GetProperty("ElementProvidingContext").Ref);
|
|
refToContext.AddSelector("ElementInContext", item.Object.GetProperty("ElementInContext").Ref);
|
|
}
|
|
|
|
return refToContext;
|
|
}
|
|
|
|
|
|
|
|
public static IManagedReference FindCertificate(X509Certificate2 cert, IWsmanConnection conn)
|
|
{
|
|
IManagedReference result = null;
|
|
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM AMT_PublicKeyCertificate");
|
|
foreach (IWsmanItem item in colObj)
|
|
{
|
|
|
|
byte[] rawData = Convert.FromBase64String(item.Object.GetProperty("X509Certificate").ToString());
|
|
X509Certificate2 cert2 = new X509Certificate2(rawData);
|
|
if (string.Compare(cert2.Thumbprint, cert.Thumbprint, true) == 0)
|
|
{
|
|
result = conn.NewReference(item.Object.ResourceUri);
|
|
result.AddSelector("InstanceID", item.Object.GetProperty("InstanceID").ToString());
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static IManagedReference AddCertificate(X509Certificate2 cert, string type, IManagedReference refToService, bool allowDuplicate)
|
|
{
|
|
|
|
IManagedReference result = null;
|
|
IManagedInstance inputObj = null;
|
|
|
|
|
|
if (string.Compare(type, "trustedrootcertificate", true) == 0)
|
|
{
|
|
inputObj = refToService.CreateMethodInput("AddTrustedRootCertificate");
|
|
}
|
|
else
|
|
{
|
|
inputObj = refToService.CreateMethodInput("AddCertificate");
|
|
}
|
|
|
|
inputObj.SetProperty("CertificateBlob", Convert.ToBase64String(cert.RawData));
|
|
IManagedInstance outObj = refToService.InvokeMethod(inputObj);
|
|
|
|
switch (outObj.GetProperty("ReturnValue").ToString())
|
|
{
|
|
case "0":
|
|
result = outObj.GetProperty("CreatedCertificate").Ref;
|
|
break;
|
|
case "1":
|
|
AmtException.ThrowInvokeError(outObj, "Internal Error");
|
|
break;
|
|
case "16":
|
|
AmtException.ThrowInvokeError(outObj, "Not Permitted");
|
|
break;
|
|
case "23":
|
|
AmtException.ThrowInvokeError(outObj, "Certificate Max Limit Reached");
|
|
break;
|
|
case "38":
|
|
AmtException.ThrowInvokeError(outObj, "Flash write limit reached");
|
|
break;
|
|
case "2058":
|
|
if (allowDuplicate)
|
|
result = FindCertificate(cert, refToService.Connection);
|
|
else
|
|
AmtException.ThrowInvokeError(outObj, "Duplicate Certificate");
|
|
break;
|
|
case "2063":
|
|
AmtException.ThrowInvokeError(outObj, "Invalid Certificate");
|
|
break;
|
|
default:
|
|
throw new WsmanInvokeException("AMT error " + outObj.GetProperty("ReturnValue").ToString());
|
|
}
|
|
return result;
|
|
|
|
}
|
|
|
|
public static void AddCertificateKey(X509Certificate2 cert, IManagedReference refToService)
|
|
{
|
|
|
|
byte[] keyData = null;
|
|
if (cert.HasPrivateKey)
|
|
{
|
|
if (cert.PrivateKey is RSACryptoServiceProvider)
|
|
{
|
|
keyData = Intel.Management.Mei.KeyFormatter.EncodeKey(cert.PrivateKey as RSACryptoServiceProvider, true);
|
|
}
|
|
}
|
|
|
|
if (keyData != null)
|
|
{
|
|
IManagedInstance inputObj = refToService.CreateMethodInput("AddKey");
|
|
inputObj.SetProperty("KeyBlob", Convert.ToBase64String(keyData));
|
|
|
|
IManagedInstance outObj = refToService.InvokeMethod(inputObj);
|
|
|
|
|
|
switch (outObj.GetProperty("ReturnValue").ToString())
|
|
{
|
|
case "0":
|
|
break;
|
|
case "1":
|
|
AmtException.ThrowInvokeError(outObj, "Internal Error");
|
|
break;
|
|
case "23":
|
|
AmtException.ThrowInvokeError(outObj, "Key Max Limit Reached");
|
|
break;
|
|
case "38":
|
|
AmtException.ThrowInvokeError(outObj, "Flash write limit reached");
|
|
break;
|
|
case "2058":
|
|
break;
|
|
case "2062":
|
|
AmtException.ThrowInvokeError(outObj, "Invalid Key");
|
|
break;
|
|
default:
|
|
throw new WsmanInvokeException("AMT error " + outObj.GetProperty("ReturnValue").ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public override object GetReturnObject()
|
|
{
|
|
return new NameValuePairItem(Name, Value);
|
|
}
|
|
}
|
|
|
|
}// end TLS Service
|
|
|
|
|
|
|
|
}//end namespace
|