rmundell

Untitled

Jun 3rd, 2015
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.46 KB | None | 0 0
  1. <%@ page import="org.apache.commons.codec.binary.Base64"%>
  2. <%@ page import="org.apache.commons.lang.StringEscapeUtils"%>
  3. <%@ page import="java.io.ByteArrayInputStream"%>
  4. <%@ page import="java.io.InputStream"%>
  5. <%@ page import="java.io.StringReader"%>
  6. <%@ page import="javax.xml.parsers.DocumentBuilderFactory" %>
  7. <%@ page import="javax.xml.parsers.DocumentBuilder" %>
  8. <%@ page import="org.xml.sax.InputSource" %>
  9. <%@ page import="org.opensaml.DefaultBootstrap" %>
  10. <%@ page import="org.opensaml.common.xml.SAMLSchemaBuilder" %>
  11. <%@ page import="org.opensaml.saml2.core.Assertion" %>
  12. <%@ page import="org.opensaml.saml2.core.Attribute" %>
  13. <%@ page import="org.opensaml.saml2.core.AttributeStatement" %>
  14. <%@ page import="org.opensaml.saml2.core.Response" %>
  15. <%@ page import="org.opensaml.saml2.encryption.Decrypter" %>
  16. <%@ page import="org.opensaml.xml.Configuration" %>
  17. <%@ page import="org.opensaml.xml.XMLObject" %>
  18. <%@ page import="org.opensaml.xml.encryption.DecryptionException" %>
  19. <%@ page import="org.opensaml.xml.encryption.InlineEncryptedKeyResolver" %>
  20. <%@ page import="org.opensaml.xml.io.Unmarshaller" %>
  21. <%@ page import="org.opensaml.xml.io.UnmarshallerFactory" %>
  22. <%@ page import="org.opensaml.xml.parse.BasicParserPool" %>
  23. <%@ page import="org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver" %>
  24. <%@ page import="org.opensaml.xml.security.x509.BasicX509Credential" %>
  25. <%@ page import="org.opensaml.xml.signature.Signature" %>
  26. <%@ page import="org.opensaml.xml.signature.SignatureValidator" %>
  27. <%@ page import="org.opensaml.xml.validation.ValidationException" %>
  28. <%@ page import="java.security.KeyFactory" %>
  29. <%@ page import="java.security.KeyStore" %>
  30. <%@ page import="java.security.PublicKey" %>
  31. <%@ page import="java.security.cert.CertificateFactory" %>
  32. <%@ page import="java.security.cert.X509Certificate" %>
  33. <%@ page import="java.security.interfaces.RSAPrivateKey" %>
  34. <%@ page import="java.security.spec.X509EncodedKeySpec" %>
  35. <%@ page import="org.w3c.dom.Document" %>
  36. <%@ page import="org.w3c.dom.Element" %>
  37. <%@ page import="org.slf4j.Logger" %>
  38. <%@ page import="org.slf4j.LoggerFactory" %>
  39. <%
  40.        Logger logger = LoggerFactory.getLogger("example");
  41.              
  42.        // This assertion was received from the testshib.org site
  43.        String assertionXml="<?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2:Assertion xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_d242c7b96762fed98b2e59cbd8fad184\" IssueInstant=\"2015-05-20T13:50:17.954Z\" Version=\"2.0\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n"
  44.               +"   <saml2:Issuer Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:entity\">https://idp.testshib.org/idp/shibboleth</saml2:Issuer>\n"
  45.               +"   <ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n"
  46.               +"      <ds:SignedInfo>\n"
  47.               +"         <ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n"
  48.               +"         <ds:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\"/>\n"
  49.               +"         <ds:Reference URI=\"#_d242c7b96762fed98b2e59cbd8fad184\">\n"
  50.               +"            <ds:Transforms>\n"
  51.               +"               <ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/>\n"
  52.               +"               <ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\">\n"
  53.               +"                  <ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"xs\"/>\n"
  54.               +"               </ds:Transform>\n"
  55.               +"            </ds:Transforms>\n"
  56.               +"            <ds:DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\"/>\n"
  57.               +"            <ds:DigestValue>+wT+bc12rwuALedTdoA2h8Cbf8uTxlaIC8JYWyBv6tc=</ds:DigestValue>\n"
  58.               +"         </ds:Reference>\n"
  59.               +"      </ds:SignedInfo>\n"
  60.               +"      <ds:SignatureValue>GopkQy+blXCfm7BYxqm7IJ8W1S5mRjFdg/uVkhnQC25AdHG47S3Dl90cUcVn8Bp4fYm+OEK36a4I0hH7LszhVDhZFK7mbR9R8VdnRniZl7edqc/uAuU5QIZyymrZjJnQGhTVKCRl26qzb6348MF6hkBaJVWrVzXe8HuOt1Bqy4XEMijBg8L0j1xfO6BGuog4JeRVwewLFdzJmGkLu5F78Q/LZatr39jrNGnJRni7jJ+Oduv/ElDEzrXlIyiOl527SaYtBEOcLAdI8pC1wsSG8fVZv824mAlpUQl7WlzUDGjVygE+5PVNflltM7XBDf3WpfCMsSGhTVY7XHKbcZyhIA==</ds:SignatureValue>\n"
  61.               +"      <ds:KeyInfo>\n"
  62.               +"         <ds:X509Data>\n"
  63.               +"            <ds:X509Certificate>MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEVMBMGA1UECBMM\n"
  64.               +"UGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYDVQQKEwhUZXN0U2hpYjEZMBcG\n"
  65.               +"A1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcx\n"
  66.               +"CzAJBgNVBAYTAlVTMRUwEwYDVQQIEwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gx\n"
  67.               +"ETAPBgNVBAoTCFRlc3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG\n"
  68.               +"9w0BAQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7CyVTDClcp\n"
  69.               +"u93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe3OQ01Ow3yT4I+Wdg1tsT\n"
  70.               +"pSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aTNPFmDixzUjoYzbGDrtAyCqA8f9CN2txI\n"
  71.               +"fJnpHE6q6CmKcoLADS4UrNPlhHSzd614kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB\n"
  72.               +"5/9nb0yh/ojRuJGmgMWHgWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HE\n"
  73.               +"MIHBMB0GA1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ869nh8\n"
  74.               +"3KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTET\n"
  75.               +"MBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNoaWIxGTAXBgNVBAMTEGlkcC50ZXN0\n"
  76.               +"c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5M\n"
  77.               +"FfSVk98t3CT9jHZoYxd8QMRLI4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpk\n"
  78.               +"OAvZZUosVkUo93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4\n"
  79.               +"/SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAjGeka8nz8Jjwx\n"
  80.               +"pUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr8K/qhmFT2nIQi538n6rVYLeW\n"
  81.               +"j8Bbnl+ev0peYzxFyF5sQA==</ds:X509Certificate>\n"
  82.               +"         </ds:X509Data>\n"
  83.               +"      </ds:KeyInfo>\n"
  84.               +"   </ds:Signature>\n"
  85.               +"   <saml2:Subject>\n"
  86.               +"      <saml2:NameID Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:transient\" NameQualifier=\"https://idp.testshib.org/idp/shibboleth\">_8a766900dd07a031fc7b7216a0c348a7</saml2:NameID>\n"
  87.               +"      <saml2:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\">\n"
  88.               +"         <saml2:SubjectConfirmationData Address=\"81.149.233.84\" InResponseTo=\"cmkplofodakgilpmlgogbeohljibddobekmkhmjj\" NotOnOrAfter=\"2015-05-20T13:55:17.954Z\" Recipient=\"http://trg63:8080/saml/responseconsumer.jsp\"/>\n"
  89.               +"      </saml2:SubjectConfirmation>\n"
  90.               +"   </saml2:Subject>\n"
  91.               +"   <saml2:Conditions NotBefore=\"2015-05-20T13:50:17.954Z\" NotOnOrAfter=\"2015-05-20T13:55:17.954Z\">\n"
  92.               +"      <saml2:AudienceRestriction>\n"
  93.               +"         <saml2:Audience>trg63testpost</saml2:Audience>\n"
  94.               +"      </saml2:AudienceRestriction>\n"
  95.               +"   </saml2:Conditions>\n"
  96.               +"   <saml2:AuthnStatement AuthnInstant=\"2015-05-20T13:34:56.451Z\" SessionIndex=\"_2b92be04044ed4d4d36ae87ca4a082a9\">\n"
  97.               +"      <saml2:SubjectLocality Address=\"81.149.233.84\"/>\n"
  98.               +"      <saml2:AuthnContext>\n"
  99.               +"         <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>\n"
  100.               +"      </saml2:AuthnContext>\n"
  101.               +"   </saml2:AuthnStatement>\n"
  102.               +"   <saml2:AttributeStatement>\n"
  103.               +"      <saml2:Attribute FriendlyName=\"uid\" Name=\"urn:oid:0.9.2342.19200300.100.1.1\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  104.               +"<saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">alterego</saml2:AttributeValue>\n"
  105.               +"      </saml2:Attribute>\n"
  106.               +"      <saml2:Attribute FriendlyName=\"eduPersonAffiliation\" Name=\"urn:oid:1.3.6.1.4.1.5923.1.1.1.1\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  107.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Member</saml2:AttributeValue>\n"
  108.               +"      </saml2:Attribute>\n"
  109.               +"      <saml2:Attribute FriendlyName=\"eduPersonPrincipalName\" Name=\"urn:oid:1.3.6.1.4.1.5923.1.1.1.6\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  110.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">[email protected]</saml2:AttributeValue>\n"
  111.               +"      </saml2:Attribute>\n"
  112.               +"      <saml2:Attribute FriendlyName=\"sn\" Name=\"urn:oid:2.5.4.4\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  113.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Ego</saml2:AttributeValue>\n"
  114.               +"      </saml2:Attribute>\n"
  115.               +"      <saml2:Attribute FriendlyName=\"eduPersonScopedAffiliation\" Name=\"urn:oid:1.3.6.1.4.1.5923.1.1.1.9\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  116.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">[email protected]</saml2:AttributeValue>\n"
  117.               +"      </saml2:Attribute>\n"
  118.               +"      <saml2:Attribute FriendlyName=\"givenName\" Name=\"urn:oid:2.5.4.42\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  119.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Alter</saml2:AttributeValue>\n"
  120.               +"      </saml2:Attribute>\n"
  121.               +"      <saml2:Attribute FriendlyName=\"eduPersonEntitlement\" Name=\"urn:oid:1.3.6.1.4.1.5923.1.1.1.7\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  122.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">urn:mace:dir:entitlement:common-lib-terms</saml2:AttributeValue>\n"
  123.               +"      </saml2:Attribute>\n"
  124.               +"      <saml2:Attribute FriendlyName=\"cn\" Name=\"urn:oid:2.5.4.3\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  125.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Alter Ego</saml2:AttributeValue>\n"
  126.               +"      </saml2:Attribute>\n"
  127.               +"      <saml2:Attribute FriendlyName=\"eduPersonTargetedID\" Name=\"urn:oid:1.3.6.1.4.1.5923.1.1.1.10\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  128.               +"         <saml2:AttributeValue>\n"
  129.               +"            <saml2:NameID Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent\" NameQualifier=\"https://idp.testshib.org/idp/shibboleth\" SPNameQualifier=\"trg63testpost\">z34O5IMEvJB4PnYP8iQqfKL2tmE=</saml2:NameID>\n"
  130.               +"         </saml2:AttributeValue>\n"
  131.               +"      </saml2:Attribute>\n"
  132.               +"      <saml2:Attribute FriendlyName=\"telephoneNumber\" Name=\"urn:oid:2.5.4.20\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
  133.               +"         <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">555-5555</saml2:AttributeValue>\n"
  134.               +"      </saml2:Attribute>\n"
  135.               +"   </saml2:AttributeStatement>\n"
  136.               +"</saml2:Assertion>";
  137.              
  138.        // This is the signing cert from the testshib.org metadata (which is also included in the assertion too)
  139.        String certificate = "MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEVMBMGA1UECBMM"
  140.               +"UGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYDVQQKEwhUZXN0U2hpYjEZMBcG"
  141.               +"A1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcx"
  142.               +"CzAJBgNVBAYTAlVTMRUwEwYDVQQIEwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gx"
  143.               +"ETAPBgNVBAoTCFRlc3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG"
  144.               +"9w0BAQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7CyVTDClcp"
  145.               +"u93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe3OQ01Ow3yT4I+Wdg1tsT"
  146.               +"pSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aTNPFmDixzUjoYzbGDrtAyCqA8f9CN2txI"
  147.               +"fJnpHE6q6CmKcoLADS4UrNPlhHSzd614kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB"
  148.               +"5/9nb0yh/ojRuJGmgMWHgWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HE"
  149.               +"MIHBMB0GA1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ869nh8"
  150.               +"3KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTET"
  151.               +"MBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNoaWIxGTAXBgNVBAMTEGlkcC50ZXN0"
  152.               +"c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5M"
  153.               +"FfSVk98t3CT9jHZoYxd8QMRLI4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpk"
  154.               +"OAvZZUosVkUo93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4"
  155.               +"/SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAjGeka8nz8Jjwx"
  156.               +"pUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr8K/qhmFT2nIQi538n6rVYLeW"
  157.               +"j8Bbnl+ev0peYzxFyF5sQA==";
  158.    
  159.        // Bootstrap OpenSAML
  160.        DefaultBootstrap.bootstrap();
  161.        
  162.        // Convert our XML string into an XML document
  163.        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
  164.        documentBuilderFactory.setNamespaceAware(true);
  165.        DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
  166.        InputSource is = new InputSource(new StringReader(assertionXml));
  167.        Document document = docBuilder.parse(is);
  168.        
  169.        // Unmarshall the assertion into an OpenSAML assertion object
  170.        Element element = document.getDocumentElement();
  171.        element=document.getDocumentElement();
  172.        UnmarshallerFactory unmarshallerFactory = org.opensaml.xml.Configuration.getUnmarshallerFactory();
  173.        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
  174.        Assertion assertion = (Assertion) unmarshaller.unmarshall(element);
  175.  
  176.        // Get the signature from the assertion
  177.        Signature signature = assertion.getSignature();
  178.  
  179.        /* so far so good...works fine up to here – the assertion was unmarshalled okay which means the XML is valid and it found the signature */
  180.    
  181.        // Convert the cert from base64 to X509Certificate object
  182.        Base64 base64KeyDecoder = new Base64();
  183.        byte[] byteKey = base64KeyDecoder.decode(certificate.getBytes("UTF-8"));
  184.        InputStream stream = new ByteArrayInputStream(byteKey);
  185.        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
  186.        X509Certificate cert = (X509Certificate)certFactory.generateCertificate(stream);
  187.  
  188.        // Get the public key from the certificate
  189.        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec((cert).getPublicKey().getEncoded());
  190.        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  191.        PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
  192.    
  193.        /* again, so far so good – no errors unpacking the cert from base64 representation and retrieving the key which implies the base64 is correctly formatted */
  194.  
  195.        // Validate the signature
  196.        BasicX509Credential publicCredential = new BasicX509Credential();
  197.        publicCredential.setPublicKey(publicKey);
  198.        SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
  199.        try {
  200.               signatureValidator.validate(signature);
  201.               /* I wish we got to here... */
  202.               out.println("Valid signature");
  203.        } catch (Exception e) {
  204.               /* ...but unfortunately it throws the exception and ends up here */
  205.               out.println("Invalid signature due to this error: "+e.getMessage());
  206.               e.printStackTrace();
  207.        }
  208. %>
Add Comment
Please, Sign In to add comment