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 { /// /// Construcutor /// /// 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); } /// /// Embedded TLSSettings container /// 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)); } } /// /// Contains all the private keys in the store /// 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); } } /// /// Contains all certificates in the store /// 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