a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: SecurityUtils.java,v 1.5 2009/06/08 23:42:33 madan_ranganath Exp $
272ac8a1a482b3baeff7293aac5de828cfd1ee69Mark de Reeper * Portions Copyrighted 2014 ForgeRock AS
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.configuration.SystemPropertiesManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.liberty.ws.common.wsse.BinarySecurityToken;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.liberty.ws.common.wsse.WSSEConstants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.liberty.ws.soapbinding.Message;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.assertion.AuthenticationStatement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.assertion.Statement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.assertion.SubjectConfirmation;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLConstants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.xmlsig.KeyProvider;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.xmlsig.XMLSignatureException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.xmlsig.XMLSignatureManager;
272ac8a1a482b3baeff7293aac5de828cfd1ee69Mark de Reeperimport org.apache.xml.security.exceptions.XMLSecurityException;
272ac8a1a482b3baeff7293aac5de828cfd1ee69Mark de Reeperimport org.apache.xml.security.keys.content.keyvalues.DSAKeyValue;
272ac8a1a482b3baeff7293aac5de828cfd1ee69Mark de Reeperimport org.apache.xml.security.keys.content.keyvalues.RSAKeyValue;
272ac8a1a482b3baeff7293aac5de828cfd1ee69Mark de Reeperimport org.apache.xml.security.utils.Constants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This class has common utility methods .
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static SecurityUtils securityManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static String PROP_TRUSTED_CA_CERT_ALIASES =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "com.sun.identity.liberty.ws.trustedca.certaliases";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Set trustedCACertAliases = new HashSet();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Map issuerTrustedCACertAliases = new HashMap();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.message("SecurityUtils.static: trusted ca certaliases = " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringTokenizer stz = new StringTokenizer(tmpStr, "|");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String alias = aliasIssuer.substring(0, index).trim();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "] to issuerTrustedCACertAliases");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sign part of the Message object based on the Security Token
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * profile embedded in the object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param m Message object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return Signature of Security Token Profile
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.message("Security Type = " + securityType);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return sm.signWithWSSX509TokenProfile(doc, cert, "", ids,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SecurityAssertion assertion = m.getAssertion();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String assertionID = assertion.getAssertionID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return sm.signWithWSSSAMLTokenProfile(doc, cert, assertionID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Should be transportation layer encryption.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Verify all the signatures of the of Message object passed
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * from Soap Binding.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param m Message object whose signature to be verified
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return true if the signature is verified.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static boolean verifyMessage(Message m){
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Certificate clientCert = (Certificate) m.getPeerCertificate();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Certificate messageCert = (Certificate) m.getMessageCertificate();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int securityProfileType = m.getSecurityProfileType();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (securityProfileType == Message.SAML_TOKEN ||
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SecurityAssertion assertion = m.getAssertion();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Certificate signingCert = getAssertionSigningCert(assertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "assertion doesn't have keyInfo and " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "issuer is not in " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "com.sun.identity.liberty.ws.trustedca.certalias" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster " in AMConfig");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster certAlias = keystore.getCertificateAlias(signingCert);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "assertion is signed with a certificate that " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster " is not in the keystore");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (!trustedCACertAliases.contains(certAlias)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "assertion is signed with a certificate that " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster " is in the keystore but not in " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "com.sun.identity.liberty.ws.trustedca.certalias" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster " in AMConfig");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.error("SecurityUtils.verifyMessage: assertion " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "signature invalid");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.message("SecurityUtils.verifyMessage: Assertion " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((clientCert!=null)&&(!clientCert.equals(messageCert))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.error("Client authentication certificate is not " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "the same as the certificate inside the " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "soap message");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return sm.verifyXMLSignature(m.getWSFVersion(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.error("Unable to verify Soap Message!", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Get Certificate from X509 Security Token Profile document.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param binarySecurityToken the Security Token.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return X509 Certiticate object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static java.security.cert.Certificate getCertificate(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String certString = binarySecurityToken.getTokenValue();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster CertificateFactory cf = CertificateFactory.getInstance("X.509");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ByteArrayInputStream bais = new ByteArrayInputStream(barr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster QName valueType = binarySecurityToken.getValueType();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (valueType.equals(BinarySecurityToken.PKCS7)) { // PKCS7 format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (i.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cert = (java.security.cert.Certificate) i.next();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else { //X509:v3 format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Certificate encoding error!
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.error("WSSecurityManager:getX509Certificate", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Gets the Certificate from the <code>Assertion</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param assertion the SAML <code>Assertion</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return <code>X509Certificate</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static java.security.cert.Certificate getCertificate(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.message("SecurityAssertion = " + assertion.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (statements !=null && !(statements.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Statement statement =(Statement)iterator.next();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (stype == Statement.AUTHENTICATION_STATEMENT) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ((AuthenticationStatement)statement).getSubject();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (stype ==
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ResourceAccessStatement.RESOURCEACCESS_STATEMENT) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (stype ==
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SessionContextStatement.SESSIONCONTEXT_STATEMENT) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (subConfirm.getConfirmationMethod().contains(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLConstants.CONFIRMATION_METHOD_HOLDEROFKEY)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.error("Assertion does not contain any Statement.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the <code>X509Certificate</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param keyinfo the <code>KeyInfo</code> Document Element.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>X509Certificate</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static X509Certificate getCertificate(Element keyinfo) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster debug.message("KeyInfo = " + XMLUtils.print(keyinfo));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element x509 = (Element) keyinfo.getElementsByTagNameNS(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (x509 == null) { // no cert found. try DSA/RSA key
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cert = (X509Certificate) keystore.getCertificate(pk);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String certString = x509.getChildNodes().item(0).getNodeValue();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the <code>PublicKey</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static PublicKey getPublicKey(Element reference)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element dsaKey = (Element) reference.getElementsByTagNameNS(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Node sub = currentNode.getChildNodes().item(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster BigInteger v = new BigInteger(Base64.decode(value));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("Wrong tag name in DSA key.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DSAKeyValue dsaKeyValue = new DSAKeyValue(doc, p, q, g, y);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("Could not get Public Key from" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster " DSA key value.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Node sub = currentNode.getChildNodes().item(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster BigInteger v =new BigInteger(Base64.decode(value));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "RSA key element.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("Could not get Public Key from" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster " RSA key value.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the <code>X509Certificate</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param certString the Certificate String.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param format the Certificate's format.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>X509Certificate</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static X509Certificate getCertificate(String certString,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("getCertificate(Assertion) : " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster CertificateFactory cf = CertificateFactory.getInstance("X.509");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ByteArrayInputStream bais = new ByteArrayInputStream(barr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster format.equals(SAMLConstants.TAG_PKCS7)) { // PKCS7 format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (i.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cert = (java.security.cert.X509Certificate) i.next();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else { //X509:v3 format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("getCertificate Exception: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the <code>X509Certificate</code> in the <code>Assertion</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param assertion the SAML <code>Assertion</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>X509Certificate</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static X509Certificate getAssertionSigningCert(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element keyInfo = (Element) signature.getElementsByTagNameNS(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cert = (X509Certificate) getCertificate(keyInfo);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns XML Signature instance.