/* * Copyright (C) 2014 Intel Corporation * All rights reserved. */ package test.saml; import com.intel.dcsg.cpg.configuration.CommonsConfigurationAdapter; import com.intel.dcsg.cpg.crypto.RsaUtil; import com.intel.dcsg.cpg.crypto.SimpleKeystore; import com.intel.mtwilson.tag.common.X509AttrBuilder; import com.intel.dcsg.cpg.extensions.Extensions; import com.intel.dcsg.cpg.io.UUID; import com.intel.dcsg.cpg.x509.X509Builder; import com.intel.mtwilson.My; import com.intel.mtwilson.TrustAssertion; import com.intel.mtwilson.agent.VendorHostAgentFactory; import com.intel.mtwilson.agent.vmware.VmwareHostAgentFactory; import com.intel.mtwilson.as.ASComponentFactory; import com.intel.mtwilson.as.business.trust.HostTrustBO; import com.intel.mtwilson.tag.model.X509AttributeCertificate; import com.intel.mtwilson.tag.model.x509.UTF8NameValueSequence; import com.intel.mtwilson.datatypes.HostTrustStatus; import com.intel.mtwilson.datatypes.TxtHost; import com.intel.mtwilson.datatypes.TxtHostRecord; import com.intel.mtwilson.saml.SamlAssertion; import com.intel.mtwilson.saml.SamlGenerator; import com.intel.mtwilson.saml.TrustAssertion.HostTrustAssertion; import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Set; import java.util.concurrent.TimeUnit; import org.junit.Test; /** * * @author jbuhacoff */ public class SAMLTest { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SAMLTest.class); private String hostname = "10.1.71.175"; // TODO: use mtwilson-env // private String hostname = "10.1.70.64"; // TODO: use mtwilson-env private boolean forceVerify = true; /** * sample output using jdk7u13: * <?xml version="1.0" encoding="UTF-8"?><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="HostTrustAssertion" IssueInstant="2014-02-23T04:46:05.708Z" Version="2.0"><saml2:Issuer>https://127.0.0.1:8080</saml2:Issuer><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#HostTrustAssertion"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>aqE/pYDJljeOMQ1Pj7FOtk8f6Kk=</DigestValue></Reference></SignedInfo><SignatureValue>G6XeqweiWyqnISNC/1G38H6jejdgbApJcPXVB55lN2NNKL8HStxoPehKwlZU1Sd5fNlFWr35mR2U 2RlWh082pTwktte4AgM0TkCR2BSpSqXEGhA4o5YVfkkXl2qAVZbUaK7pUop2IuOiOUZZP+1dfSWA Vn7t39KrS2k4jPgGaU7zrgt7Tqc2CtYAC1d4F+6/dCKpd7g76YirUeS90MCenCkmc9dpViAJqsRm hIOC8r6QVtrcehbmsg9pRjVvMWbaxyeP+r1XyMXDHFRpvQ96QB6cDCZYbRpR9zC4HKJIk9bnuORH PNnY6cojC1PmHSOBCb91TSv7TUZRZ98EyJC1dw==</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIC1DCCAbygAwIBAgIIOs/DIxyqZkgwDQYJKoZIhvcNAQELBQAwKTERMA8GA1UECxMIbXR3aWxz b24xFDASBgNVBAMTC210d2lsc29uLWNhMB4XDTE0MDIyMTA3MDk0N1oXDTE1MDIyMTA3MDk0N1ow KzERMA8GA1UECxMIbXR3aWxzb24xFjAUBgNVBAMTDW10d2lsc29uLXNhbWwwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCpOLLVQYZrMhUFPJeAaagorGgF6GSRkLWF981nFkxHdYVLXguz lKuJRj7fnqVUPtXuRB5TvpED4EUdYrWBTAKajCuUFB+gQazEMFNjm4GolfDmh+RTHZKVY+kdNIIy tOx+n9tGO+kGSBLjJeaPtlMb2TsDS7pWlrO3kRkkfjM5Wt8yCMWNCMikKz1PXA9ynpC1cMf/i3lN XG8bOHY5URDXCXdl8IZ1OMUV2yIQ4I5PyFpw9kdiGlW2TvQCMJWyfg+/Sfl9M28Yg1m/nwGY6SdV paFkxNKfBirfiHm+1pk6WSELEvSy+eWILk48C5P6vP9UVm4lzaM3zX6zWUkBnIE9AgMBAAEwDQYJ KoZIhvcNAQELBQADggEBAJmm8okpAajnUoRGiMHPgjqVwD2kjH5+j0Hu9gSWPC4bOeHPleGPLcCa 60MBMWmc3RAH3UxUGlY5augZcXvEcftBUUDvgwQnkvHV2CDsrKN+3qDoVzsGs5NdNMrWO5Ho2VQf 5jJNqQjmU2+m3oCU4Aa9Mwoqhiio9XiS+yQ5L84PqBqAmJX4M548zc9yYqsTvAfFwNFBtlav6xS6 adQFeHGfM6SCxnn0LE/9Xa6wT+9pC29/mBtbdxRoHyntdwa6JoFxjni8dCsPP4Tr5NCXuoiTCAgP 55gw0BInWluHocdkrXzaDmrOYoe9N6nuGbSkJ/TQbW8nX6jo4k4BllugaRY=</X509Certificate></X509Data></KeyInfo></Signature><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">10.1.71.175</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">AttestationService-0.5.4</saml2:NameID><saml2:SubjectConfirmationData Address="10.254.36.218" NotBefore="2014-02-23T04:46:05.755Z" NotOnOrAfter="2014-02-23T05:46:05.755Z"/></saml2:SubjectConfirmation></saml2:Subject><saml2:AttributeStatement><saml2:Attribute Name="Trusted"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">true</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="Trusted_BIOS"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">true</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="BIOS_Name"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Intel_Corporation</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="BIOS_Version"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">01.00.0063</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="BIOS_OEM"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Intel Corporation</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="Trusted_VMM"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">true</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="VMM_Name"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Intel_Thurley_VMware_ESXi</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="VMM_Version"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">5.1.0-1065491</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="VMM_OSName"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">VMware_ESXi</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="VMM_OSVersion"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">5.1.0</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="Asset_Tag"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">false</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:Assertion> * */ @Test public void testGenerateAndVerifySaml() throws Exception { // generate SAML // Extensions.register(VendorHostAgentFactory.class, IntelHostAgentFactory.class); // because 10.1.70.64 is trust agent Extensions.register(VendorHostAgentFactory.class, VmwareHostAgentFactory.class); // because 10.1.71.175 is esxi HostTrustBO hostTrustBO = ASComponentFactory.getHostTrustBO(); String saml = hostTrustBO.getTrustWithSaml(hostname, forceVerify); log.debug("saml = {}", saml); // verify SAML SimpleKeystore keystore = new SimpleKeystore(My.configuration().getSamlKeystoreFile(), My.configuration().getSamlKeystorePassword()); // X509Certificate[] trusted = keystore.getTrustedCertificates(SimpleKeystore.SAML); // this works for the api client's keystore X509Certificate[] trusted = new X509Certificate[] { keystore.getX509Certificate(keystore.aliases()[0]) }; // this works for mtwilson's mtwilson-saml.jks keystore TrustAssertion trustAssertion = new TrustAssertion(trusted, saml); print(trustAssertion); } @Test public void testGenerateAndVerifyMultihostSaml() throws Exception { // generate SAML Extensions.register(VendorHostAgentFactory.class, VmwareHostAgentFactory.class); // because 10.1.71.175 is esxi HostTrustBO hostTrustBO = ASComponentFactory.getHostTrustBO(); ArrayList<String> hostnames = new ArrayList<String>(); hostnames.add(hostname); hostnames.add(hostname); String saml = hostTrustBO.getTrustWithSamlForHostnames(hostnames); log.debug("saml = {}", saml); // verify SAML SimpleKeystore keystore = new SimpleKeystore(My.configuration().getSamlKeystoreFile(), My.configuration().getSamlKeystorePassword()); // X509Certificate[] trusted = keystore.getTrustedCertificates(SimpleKeystore.SAML); // this works for the api client's keystore X509Certificate[] trusted = new X509Certificate[] { keystore.getX509Certificate(keystore.aliases()[0]) }; // this works for mtwilson's mtwilson-saml.jks keystore TrustAssertion trustAssertion = new TrustAssertion(trusted, saml); print(trustAssertion); } /** * Example output (no aik or certificate because it was a vmware esxi host): 2014-02-22 20:59:37,111 DEBUG [main] t.s.SAMLTest [SAMLTest.java:66] isValid true 2014-02-22 20:59:37,112 DEBUG [main] t.s.SAMLTest [SAMLTest.java:71] aikCertificate null 2014-02-22 20:59:37,112 DEBUG [main] t.s.SAMLTest [SAMLTest.java:72] aikPublicKey null 2014-02-22 20:59:37,113 DEBUG [main] t.s.SAMLTest [SAMLTest.java:73] date Sat Feb 22 20:46:05 PST 2014 2014-02-22 20:59:37,113 DEBUG [main] t.s.SAMLTest [SAMLTest.java:74] issuer https://127.0.0.1:8080 2014-02-22 20:59:37,114 DEBUG [main] t.s.SAMLTest [SAMLTest.java:75] subjectFormat urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified 2014-02-22 20:59:37,114 DEBUG [main] t.s.SAMLTest [SAMLTest.java:76] subject 10.1.71.175 2014-02-22 20:59:37,114 DEBUG [main] t.s.SAMLTest [SAMLTest.java:77] isHostBiosTrusted true 2014-02-22 20:59:37,116 DEBUG [main] t.s.SAMLTest [SAMLTest.java:78] isHostVmmTrusted true 2014-02-22 20:59:37,116 DEBUG [main] t.s.SAMLTest [SAMLTest.java:79] isHostLocationTrusted false 2014-02-22 20:59:37,116 DEBUG [main] t.s.SAMLTest [SAMLTest.java:80] isHostTrusted true 2014-02-22 20:59:37,116 DEBUG [main] t.s.SAMLTest [SAMLTest.java:82] 11 attributes 2014-02-22 20:59:37,117 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute BIOS_Name value Intel_Corporation 2014-02-22 20:59:37,117 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute VMM_Name value Intel_Thurley_VMware_ESXi 2014-02-22 20:59:37,117 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute VMM_OSName value VMware_ESXi 2014-02-22 20:59:37,117 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute BIOS_OEM value Intel Corporation 2014-02-22 20:59:37,117 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute Trusted_BIOS value true 2014-02-22 20:59:37,117 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute Trusted_VMM value true 2014-02-22 20:59:37,118 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute BIOS_Version value 01.00.0063 2014-02-22 20:59:37,118 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute VMM_Version value 5.1.0-1065491 2014-02-22 20:59:37,118 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute Trusted value true 2014-02-22 20:59:37,118 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute VMM_OSVersion value 5.1.0 2014-02-22 20:59:37,118 DEBUG [main] t.s.SAMLTest [SAMLTest.java:84] attribute Asset_Tag value false * * @param trustAssertion * @throws Exception */ private void print(TrustAssertion trustAssertion) throws Exception { log.debug("isValid {}", trustAssertion.isValid()); if( !trustAssertion.isValid() ) { log.debug("error {}", trustAssertion.error()); return; } Set<String> hostnames = trustAssertion.getHosts(); for(String hostname : hostnames) { HostTrustAssertion hostTrustAssertion = trustAssertion.getTrustAssertion(hostname); log.debug("aikCertificate {}", hostTrustAssertion.getAikCertificate()); log.debug("aikPublicKey {}", hostTrustAssertion.getAikPublicKey()); log.debug("date {}", hostTrustAssertion.getDate()); log.debug("issuer {}", hostTrustAssertion.getIssuer()); log.debug("subjectFormat {}", hostTrustAssertion.getSubjectFormat()); log.debug("subject {}", hostTrustAssertion.getSubject()); log.debug("isHostBiosTrusted {}", hostTrustAssertion.isHostBiosTrusted()); log.debug("isHostVmmTrusted {}", hostTrustAssertion.isHostVmmTrusted()); log.debug("isHostLocationTrusted {}", hostTrustAssertion.isHostLocationTrusted()); log.debug("isHostTrusted {}", hostTrustAssertion.isHostTrusted()); Set<String> attributeNames = hostTrustAssertion.getAttributeNames(); log.debug("{} attributes", attributeNames.size()); for(String attributeName : attributeNames) { log.debug("attribute {} value {}", attributeName, hostTrustAssertion.getStringAttribute(attributeName)); } } } @Test public void testGenerateSamlWithAssetTags() throws Exception { // equivalent of private SamlGenerator getSamlGenerator() in HostTrustBO: SamlGenerator samlGenerator = new SamlGenerator(new CommonsConfigurationAdapter(My.configuration().getConfiguration())); samlGenerator.setIssuer("junit-test"); // String defaultIssuer = "https://" + localhost.getHostAddress() + ":8181/AttestationService"; // TODO: need to get our local address from the web container or configuration (mtwilson.api.baseurl) instead of hard-coding this here // generate assertion HostTrustStatus trust = new HostTrustStatus(); trust.asset_tag = true; trust.bios = true; trust.location = true; trust.vmm = true; TxtHostRecord data = new TxtHostRecord(); data.BIOS_Name = "Generic BIOS"; data.BIOS_Version = "1.0"; data.BIOS_Oem = "Generic OEM"; data.Hardware_Uuid = new UUID().toString(); data.HostName = "localhost"; data.IPAddress = "127.0.0.1"; data.Location = "here"; data.VMM_Name = "Generic VMM"; data.VMM_Version = "1.0"; data.VMM_OSName = "Generic OS"; data.VMM_OSVersion = "1.0"; TxtHost host = new TxtHost(data, trust); // generate asset tag cert // first, create the CA key pair and certificate KeyPair cakey = RsaUtil.generateRsaKeyPair(2048); X509Certificate cacert = X509Builder.factory().selfSigned("CN=Attr CA,OU=CPG,OU=DCSG,O=Intel,ST=CA,C=US", cakey).build(); // second, create the attribute certificate X509AttrBuilder builder = X509AttrBuilder.factory(); byte[] attrCertBytes = builder .issuerName(cacert).issuerPrivateKey(cakey.getPrivate()) .expires(1, TimeUnit.HOURS) .subjectUuid(new UUID()) .attribute("Country", "US") .attribute("State", "CA", "TX") .build(); X509AttributeCertificate cert = X509AttributeCertificate.valueOf(attrCertBytes); // generate the assertion with trutsed host information and trusted tag certificate SamlAssertion samlAssertion = samlGenerator.generateHostAssertion(host, cert); // verify and print the assertion contents // SamlConfiguration samlConfiguration = new SamlConfiguration(new CommonsConfigurationAdapter(My.configuration().getConfiguration())); SimpleKeystore keystore = new SimpleKeystore(My.configuration().getSamlKeystoreFile(), My.configuration().getSamlKeystorePassword()); // X509Certificate[] trusted = keystore.getTrustedCertificates(SimpleKeystore.SAML); // this works for the api client's keystore X509Certificate[] trusted = new X509Certificate[] { keystore.getX509Certificate(keystore.aliases()[0]) }; // this works for mtwilson's mtwilson-saml.jks keystore TrustAssertion trustAssertion = new TrustAssertion(trusted, samlAssertion.assertion); print(trustAssertion); } }