Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <%@ page import="org.apache.commons.codec.binary.Base64"%>
- <%@ page import="org.apache.commons.lang.StringEscapeUtils"%>
- <%@ page import="java.io.ByteArrayInputStream"%>
- <%@ page import="java.io.InputStream"%>
- <%@ page import="java.io.StringReader"%>
- <%@ page import="javax.xml.parsers.DocumentBuilderFactory" %>
- <%@ page import="javax.xml.parsers.DocumentBuilder" %>
- <%@ page import="org.xml.sax.InputSource" %>
- <%@ page import="org.opensaml.DefaultBootstrap" %>
- <%@ page import="org.opensaml.common.xml.SAMLSchemaBuilder" %>
- <%@ page import="org.opensaml.saml2.core.Assertion" %>
- <%@ page import="org.opensaml.saml2.core.Attribute" %>
- <%@ page import="org.opensaml.saml2.core.AttributeStatement" %>
- <%@ page import="org.opensaml.saml2.core.Response" %>
- <%@ page import="org.opensaml.saml2.encryption.Decrypter" %>
- <%@ page import="org.opensaml.xml.Configuration" %>
- <%@ page import="org.opensaml.xml.XMLObject" %>
- <%@ page import="org.opensaml.xml.encryption.DecryptionException" %>
- <%@ page import="org.opensaml.xml.encryption.InlineEncryptedKeyResolver" %>
- <%@ page import="org.opensaml.xml.io.Unmarshaller" %>
- <%@ page import="org.opensaml.xml.io.UnmarshallerFactory" %>
- <%@ page import="org.opensaml.xml.parse.BasicParserPool" %>
- <%@ page import="org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver" %>
- <%@ page import="org.opensaml.xml.security.x509.BasicX509Credential" %>
- <%@ page import="org.opensaml.xml.signature.Signature" %>
- <%@ page import="org.opensaml.xml.signature.SignatureValidator" %>
- <%@ page import="org.opensaml.xml.validation.ValidationException" %>
- <%@ page import="java.security.KeyFactory" %>
- <%@ page import="java.security.KeyStore" %>
- <%@ page import="java.security.PublicKey" %>
- <%@ page import="java.security.cert.CertificateFactory" %>
- <%@ page import="java.security.cert.X509Certificate" %>
- <%@ page import="java.security.interfaces.RSAPrivateKey" %>
- <%@ page import="java.security.spec.X509EncodedKeySpec" %>
- <%@ page import="org.w3c.dom.Document" %>
- <%@ page import="org.w3c.dom.Element" %>
- <%@ page import="org.slf4j.Logger" %>
- <%@ page import="org.slf4j.LoggerFactory" %>
- <%
- Logger logger = LoggerFactory.getLogger("example");
- // This assertion was received from the testshib.org site
- 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"
- +" <saml2:Issuer Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:entity\">https://idp.testshib.org/idp/shibboleth</saml2:Issuer>\n"
- +" <ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n"
- +" <ds:SignedInfo>\n"
- +" <ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n"
- +" <ds:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\"/>\n"
- +" <ds:Reference URI=\"#_d242c7b96762fed98b2e59cbd8fad184\">\n"
- +" <ds:Transforms>\n"
- +" <ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/>\n"
- +" <ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\">\n"
- +" <ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"xs\"/>\n"
- +" </ds:Transform>\n"
- +" </ds:Transforms>\n"
- +" <ds:DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\"/>\n"
- +" <ds:DigestValue>+wT+bc12rwuALedTdoA2h8Cbf8uTxlaIC8JYWyBv6tc=</ds:DigestValue>\n"
- +" </ds:Reference>\n"
- +" </ds:SignedInfo>\n"
- +" <ds:SignatureValue>GopkQy+blXCfm7BYxqm7IJ8W1S5mRjFdg/uVkhnQC25AdHG47S3Dl90cUcVn8Bp4fYm+OEK36a4I0hH7LszhVDhZFK7mbR9R8VdnRniZl7edqc/uAuU5QIZyymrZjJnQGhTVKCRl26qzb6348MF6hkBaJVWrVzXe8HuOt1Bqy4XEMijBg8L0j1xfO6BGuog4JeRVwewLFdzJmGkLu5F78Q/LZatr39jrNGnJRni7jJ+Oduv/ElDEzrXlIyiOl527SaYtBEOcLAdI8pC1wsSG8fVZv824mAlpUQl7WlzUDGjVygE+5PVNflltM7XBDf3WpfCMsSGhTVY7XHKbcZyhIA==</ds:SignatureValue>\n"
- +" <ds:KeyInfo>\n"
- +" <ds:X509Data>\n"
- +" <ds:X509Certificate>MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEVMBMGA1UECBMM\n"
- +"UGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYDVQQKEwhUZXN0U2hpYjEZMBcG\n"
- +"A1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcx\n"
- +"CzAJBgNVBAYTAlVTMRUwEwYDVQQIEwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gx\n"
- +"ETAPBgNVBAoTCFRlc3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG\n"
- +"9w0BAQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7CyVTDClcp\n"
- +"u93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe3OQ01Ow3yT4I+Wdg1tsT\n"
- +"pSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aTNPFmDixzUjoYzbGDrtAyCqA8f9CN2txI\n"
- +"fJnpHE6q6CmKcoLADS4UrNPlhHSzd614kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB\n"
- +"5/9nb0yh/ojRuJGmgMWHgWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HE\n"
- +"MIHBMB0GA1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ869nh8\n"
- +"3KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTET\n"
- +"MBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNoaWIxGTAXBgNVBAMTEGlkcC50ZXN0\n"
- +"c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5M\n"
- +"FfSVk98t3CT9jHZoYxd8QMRLI4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpk\n"
- +"OAvZZUosVkUo93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4\n"
- +"/SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAjGeka8nz8Jjwx\n"
- +"pUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr8K/qhmFT2nIQi538n6rVYLeW\n"
- +"j8Bbnl+ev0peYzxFyF5sQA==</ds:X509Certificate>\n"
- +" </ds:X509Data>\n"
- +" </ds:KeyInfo>\n"
- +" </ds:Signature>\n"
- +" <saml2:Subject>\n"
- +" <saml2:NameID Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:transient\" NameQualifier=\"https://idp.testshib.org/idp/shibboleth\">_8a766900dd07a031fc7b7216a0c348a7</saml2:NameID>\n"
- +" <saml2:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\">\n"
- +" <saml2:SubjectConfirmationData Address=\"81.149.233.84\" InResponseTo=\"cmkplofodakgilpmlgogbeohljibddobekmkhmjj\" NotOnOrAfter=\"2015-05-20T13:55:17.954Z\" Recipient=\"http://trg63:8080/saml/responseconsumer.jsp\"/>\n"
- +" </saml2:SubjectConfirmation>\n"
- +" </saml2:Subject>\n"
- +" <saml2:Conditions NotBefore=\"2015-05-20T13:50:17.954Z\" NotOnOrAfter=\"2015-05-20T13:55:17.954Z\">\n"
- +" <saml2:AudienceRestriction>\n"
- +" <saml2:Audience>trg63testpost</saml2:Audience>\n"
- +" </saml2:AudienceRestriction>\n"
- +" </saml2:Conditions>\n"
- +" <saml2:AuthnStatement AuthnInstant=\"2015-05-20T13:34:56.451Z\" SessionIndex=\"_2b92be04044ed4d4d36ae87ca4a082a9\">\n"
- +" <saml2:SubjectLocality Address=\"81.149.233.84\"/>\n"
- +" <saml2:AuthnContext>\n"
- +" <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>\n"
- +" </saml2:AuthnContext>\n"
- +" </saml2:AuthnStatement>\n"
- +" <saml2:AttributeStatement>\n"
- +" <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"
- +"<saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">alterego</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <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"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Member</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <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"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">[email protected]</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <saml2:Attribute FriendlyName=\"sn\" Name=\"urn:oid:2.5.4.4\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Ego</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <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"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">[email protected]</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <saml2:Attribute FriendlyName=\"givenName\" Name=\"urn:oid:2.5.4.42\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Alter</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <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"
- +" <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"
- +" </saml2:Attribute>\n"
- +" <saml2:Attribute FriendlyName=\"cn\" Name=\"urn:oid:2.5.4.3\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">Alter Ego</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <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"
- +" <saml2:AttributeValue>\n"
- +" <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"
- +" </saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" <saml2:Attribute FriendlyName=\"telephoneNumber\" Name=\"urn:oid:2.5.4.20\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\">\n"
- +" <saml2:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\">555-5555</saml2:AttributeValue>\n"
- +" </saml2:Attribute>\n"
- +" </saml2:AttributeStatement>\n"
- +"</saml2:Assertion>";
- // This is the signing cert from the testshib.org metadata (which is also included in the assertion too)
- String certificate = "MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEVMBMGA1UECBMM"
- +"UGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYDVQQKEwhUZXN0U2hpYjEZMBcG"
- +"A1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcx"
- +"CzAJBgNVBAYTAlVTMRUwEwYDVQQIEwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gx"
- +"ETAPBgNVBAoTCFRlc3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG"
- +"9w0BAQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7CyVTDClcp"
- +"u93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe3OQ01Ow3yT4I+Wdg1tsT"
- +"pSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aTNPFmDixzUjoYzbGDrtAyCqA8f9CN2txI"
- +"fJnpHE6q6CmKcoLADS4UrNPlhHSzd614kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB"
- +"5/9nb0yh/ojRuJGmgMWHgWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HE"
- +"MIHBMB0GA1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ869nh8"
- +"3KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTET"
- +"MBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNoaWIxGTAXBgNVBAMTEGlkcC50ZXN0"
- +"c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5M"
- +"FfSVk98t3CT9jHZoYxd8QMRLI4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpk"
- +"OAvZZUosVkUo93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4"
- +"/SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAjGeka8nz8Jjwx"
- +"pUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr8K/qhmFT2nIQi538n6rVYLeW"
- +"j8Bbnl+ev0peYzxFyF5sQA==";
- // Bootstrap OpenSAML
- DefaultBootstrap.bootstrap();
- // Convert our XML string into an XML document
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setNamespaceAware(true);
- DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
- InputSource is = new InputSource(new StringReader(assertionXml));
- Document document = docBuilder.parse(is);
- // Unmarshall the assertion into an OpenSAML assertion object
- Element element = document.getDocumentElement();
- element=document.getDocumentElement();
- UnmarshallerFactory unmarshallerFactory = org.opensaml.xml.Configuration.getUnmarshallerFactory();
- Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
- Assertion assertion = (Assertion) unmarshaller.unmarshall(element);
- // Get the signature from the assertion
- Signature signature = assertion.getSignature();
- /* 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 */
- // Convert the cert from base64 to X509Certificate object
- Base64 base64KeyDecoder = new Base64();
- byte[] byteKey = base64KeyDecoder.decode(certificate.getBytes("UTF-8"));
- InputStream stream = new ByteArrayInputStream(byteKey);
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate)certFactory.generateCertificate(stream);
- // Get the public key from the certificate
- X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec((cert).getPublicKey().getEncoded());
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
- /* again, so far so good – no errors unpacking the cert from base64 representation and retrieving the key which implies the base64 is correctly formatted */
- // Validate the signature
- BasicX509Credential publicCredential = new BasicX509Credential();
- publicCredential.setPublicKey(publicKey);
- SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
- try {
- signatureValidator.validate(signature);
- /* I wish we got to here... */
- out.println("Valid signature");
- } catch (Exception e) {
- /* ...but unfortunately it throws the exception and ends up here */
- out.println("Invalid signature due to this error: "+e.getMessage());
- e.printStackTrace();
- }
- %>
Add Comment
Please, Sign In to add comment