All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.identity.saml.xmlsig.AMSignatureProvider Maven / Gradle / Ivy

There is a newer version: 14.8.4
Show newest version
/**
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
 *
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License). You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at
 * https://opensso.dev.java.net/public/CDDLv1.0.html or
 * opensso/legal/CDDLv1.0.txt
 * See the License for the specific language governing
 * permission and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at opensso/legal/CDDLv1.0.txt.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * $Id: AMSignatureProvider.java,v 1.11 2009/08/29 03:06:47 mallas Exp $
 *
 * Portions Copyrighted 2013-2016 ForgeRock AS.
 */

package com.sun.identity.saml.xmlsig;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.util.Collection;
import java.util.List;
import java.util.Iterator;
import java.security.Key;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.xml.xpath.XPathException;

import com.sun.identity.liberty.ws.common.wsse.WSSEConstants;
import com.sun.identity.liberty.ws.soapbinding.SOAPBindingConstants;
import com.sun.identity.shared.encode.Base64;
import com.sun.identity.shared.xml.XMLUtils;
import com.sun.identity.shared.xml.XPathAPI;
import com.sun.identity.common.SystemConfigurationUtil;
import com.sun.identity.saml.common.SAMLConstants;
import com.sun.identity.saml.common.SAMLUtilsCommon;

import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.keyvalues.DSAKeyValue;
import org.apache.xml.security.keys.content.keyvalues.RSAKeyValue;
import org.apache.xml.security.keys.storage.StorageResolver;
import org.apache.xml.security.keys.storage.implementations.KeyStoreResolver;
import org.apache.xml.security.keys.keyresolver.implementations.X509CertificateResolver;
import org.apache.xml.security.keys.keyresolver.implementations.X509SubjectNameResolver;
import org.apache.xml.security.keys.keyresolver.implementations.X509IssuerSerialResolver;
import org.apache.xml.security.keys.keyresolver.implementations.X509SKIResolver;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.ElementProxy;
import org.apache.xml.security.transforms.Transforms;

import org.forgerock.openam.utils.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * SignatureProvider is an interface
 * to be implemented to sign and verify xml signature
 * 

*/ public class AMSignatureProvider implements SignatureProvider { protected KeyProvider keystore = null; private String c14nMethod = null; private String transformAlg = null; // define default id attribute name private static final String DEF_ID_ATTRIBUTE = "id"; // flag to check if the partner's signing cert is in the keystore. private boolean checkCert = true; private boolean isJKSKeyStore= false; private String wsfVersion = null; private String defaultSigAlg = null; private String digestAlg = null; /** * Default Constructor */ public AMSignatureProvider() { org.apache.xml.security.Init.init(); try { String kprovider = SystemConfigurationUtil.getProperty( SAMLConstants.KEY_PROVIDER_IMPL_CLASS, SAMLConstants.JKS_KEY_PROVIDER); keystore= (KeyProvider) Class.forName(kprovider).newInstance(); if (keystore instanceof JKSKeyProvider) { isJKSKeyStore=true; } } catch (Exception e) { SAMLUtilsCommon.debug.error("AMSignatureProvider: " + "constructor error"); } c14nMethod = SystemConfigurationUtil.getProperty( SAMLConstants.CANONICALIZATION_METHOD, SAMLConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); transformAlg = SystemConfigurationUtil.getProperty( SAMLConstants.TRANSFORM_ALGORITHM, SAMLConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); defaultSigAlg = SystemConfigurationUtil.getProperty( SAMLConstants.XMLSIG_ALGORITHM); digestAlg = SystemConfigurationUtil.getProperty( SAMLConstants.DIGEST_ALGORITHM, Constants.ALGO_ID_DIGEST_SHA1); try { String valCert = SystemConfigurationUtil.getProperty( "com.sun.identity.saml.checkcert"); if (valCert != null) { if (valCert.trim().equalsIgnoreCase("off")) { checkCert = false; }else if (valCert.trim().equalsIgnoreCase("on")) { checkCert = true; }else { if(SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("SystemConfigurationUtil:" + " com.sun.identity.saml.checkcert has" + " invalid value. Choose default, turn" + " ON checkcert."); } checkCert = true; } } } catch (Exception e) { checkCert = true; } } /** * Constructor */ public void initialize(KeyProvider keyProvider) { if (keyProvider == null) { SAMLUtilsCommon.debug.error("Key Provider is null"); } else { keystore = keyProvider; if (keystore instanceof JKSKeyProvider) { isJKSKeyStore=true; } } } /** * Sign the xml document using enveloped signatures. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @return signature Element object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias) throws XMLSignatureException { return signXML(doc, certAlias, null); } /** * Sign the xml document using enveloped signatures. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @return signature dom object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias, java.lang.String algorithm) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("signXML: doc is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (certAlias == null || certAlias.length() == 0) { SAMLUtilsCommon.debug.error("signXML: certAlias is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } org.w3c.dom.Element root = null; XMLSignature sig = null; try { ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, SAMLConstants.PREFIX_DS); if (keystore == null) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullkeystore")); } PrivateKey privateKey = (PrivateKey) keystore.getPrivateKey(certAlias); if (privateKey == null) { SAMLUtilsCommon.debug.error("private key is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullprivatekey")); } root = doc.getDocumentElement(); if (algorithm == null || algorithm.length() == 0) { algorithm = getKeyAlgorithm(privateKey); } if (!isValidAlgorithm(algorithm)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("invalidalgorithm")); } if (c14nMethod == null || c14nMethod.length() == 0) { sig = new XMLSignature(doc, "", algorithm); } else { if (!isValidCanonicalizationMethod(c14nMethod)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle. getString("invalidCanonicalizationMethod")); } sig = new XMLSignature(doc, "", algorithm, c14nMethod); } root.appendChild(sig.getElement()); sig.getSignedInfo().addResourceResolver( new com.sun.identity.saml.xmlsig.OfflineResolver()); // do transform Transforms transforms = new Transforms(doc); transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE); // If exclusive canonicalization is presented in the saml locale // file, we will add a transform for it. Otherwise, will not do // such transform due to performance reason. if (transformAlg != null && transformAlg.length() != 0) { if (!isValidTransformAlgorithm(transformAlg)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString( "invalidTransformAlgorithm")); } transforms.addTransform(transformAlg); } sig.addDocument("", transforms, digestAlg); // add certificate X509Certificate cert = (X509Certificate) keystore.getX509Certificate(certAlias); sig.addKeyInfo(cert); sig.sign(privateKey); } catch (Exception e) { SAMLUtilsCommon.debug.error("signXML Exception: ", e); throw new XMLSignatureException(e.getMessage()); } return (sig.getElement()); } /** * Sign the xml string using enveloped signatures. * @param xmlString xml string to be signed * @param certAlias Signer's certificate alias name * @return XML signature string * @throws XMLSignatureException if the xml string could not be signed */ public java.lang.String signXML(java.lang.String xmlString, java.lang.String certAlias) throws XMLSignatureException { return signXML(xmlString, certAlias, null); } /** * Sign the xml string using enveloped signatures. * @param xmlString xml string to be signed * @param certAlias Signer's certificate alias name * @param algorithm XML Signature algorithm * @return XML signature string * @throws XMLSignatureException if the xml string could not be signed */ public java.lang.String signXML(java.lang.String xmlString, java.lang.String certAlias, java.lang.String algorithm) throws XMLSignatureException { if (xmlString == null || xmlString.length() == 0) { SAMLUtilsCommon.debug.error("signXML: xmlString is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (certAlias == null || certAlias.length() == 0) { SAMLUtilsCommon.debug.error("signXML: certAlias is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Element el = null; try { Document doc = XMLUtils.toDOMDocument(xmlString, SAMLUtilsCommon.debug); el = signXML(doc, certAlias, algorithm); } catch (Exception e) { SAMLUtilsCommon.debug.error("signXML Exception: ", e); throw new XMLSignatureException(e.getMessage()); } return XMLUtils.print(el); } /** * Sign part of the xml document referered by the supplied id attribute * using enveloped signatures and use exclusive xml canonicalization. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param id id attribute value of the node to be signed * @return signature dom object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias, java.lang.String algorithm, java.lang.String id) throws XMLSignatureException { return signXML(doc, certAlias, algorithm, DEF_ID_ATTRIBUTE, id, false, null); } /** * Sign part of the xml document referered by the supplied id attribute * using enveloped signatures and use exclusive xml canonicalization. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param id id attribute value of the node to be signed * @param xpath expression should uniquly identify a node before which * @return signature dom object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias, java.lang.String algorithm, java.lang.String id, java.lang.String xpath) throws XMLSignatureException { return signXML(doc, certAlias, algorithm, DEF_ID_ATTRIBUTE, id, false, xpath); } /** * Sign part of the xml document referered by the supplied id attribute * using enveloped signatures and use exclusive xml canonicalization. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param idAttrName attribute name for the id attribute of the node to * be signed * @param id id attribute value of the node to be signed * @param includeCert if true, include the signing certificate in KeyInfo. * if false, does not include the signing certificate. * @return signature dom object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias, java.lang.String algorithm, java.lang.String idAttrName, java.lang.String id, boolean includeCert) throws XMLSignatureException { return signXML(doc, certAlias, algorithm, idAttrName, id, includeCert, null); } /** * Sign part of the xml document referered by the supplied id attribute * using enveloped signatures and use exclusive xml canonicalization. * @param xmlString a string representing XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param idAttrName attribute name for the id attribute of the node to be * signed. * @param id id attribute value of the node to be signed * @param includeCert if true, include the signing certificate in KeyInfo. * if false, does not include the signing certificate. * @return a string representing signature dom object * @throws XMLSignatureException if the document could not be signed */ public java.lang.String signXML(java.lang.String xmlString, java.lang.String certAlias, java.lang.String algorithm, java.lang.String idAttrName, java.lang.String id, boolean includeCert) throws XMLSignatureException { if (xmlString == null || xmlString.length() == 0) { SAMLUtilsCommon.debug.error("signXML: xmlString is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Document doc = null; try { doc = XMLUtils.toDOMDocument(xmlString, SAMLUtilsCommon.debug); } catch (Exception e) { SAMLUtilsCommon.debug.error("signXML Exception: ", e); throw new XMLSignatureException(e.getMessage()); } Element el = signXML(doc, certAlias, algorithm, idAttrName, id, includeCert, null); return XMLUtils.print(el); } /** * Sign part of the xml document referred by the supplied id attribute * using enveloped signatures and use exclusive xml canonicalization. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param idAttrName attribute name for the id attribute of the node to * be signed * @param id id attribute value of the node to be signed * @param includeCert if true, include the signing certificate in KeyInfo. * if false, does not include the signing certificate. * @param xpath expression should uniquly identify a node before which * @return a signed dom object * @throws XMLSignatureException if the document could not be signed */ public Element signXML(Document doc, String certAlias, String algorithm, String idAttrName, String id, boolean includeCert, String xpath) throws XMLSignatureException { return signXMLUsingKeyPass(doc, certAlias, null, algorithm, idAttrName, id, includeCert, xpath); } /** * Sign part of the XML document referred by the supplied id attribute * using enveloped signatures and use exclusive XML canonicalization. * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param encryptedKeyPass Use the supplied encrypted key password to get the private key * @param algorithm XML signature algorithm * @param idAttrName attribute name for the id attribute of the node to be * signed. * @param id id attribute value of the node to be signed * @param includeCert if true, include the signing certificate in * KeyInfo. * if false, does not include the signing certificate. * @param xpath expression should uniquely identify a node before which * @return a signed dom object * @throws XMLSignatureException if the document could not be signed */ public Element signXMLUsingKeyPass(Document doc, String certAlias, String encryptedKeyPass, String algorithm, String idAttrName, String id, boolean includeCert, String xpath) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("signXML: doc is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (certAlias == null || certAlias.length() == 0) { SAMLUtilsCommon.debug.error("signXML: certAlias is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Element root = null; XMLSignature sig = null; try { ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, SAMLConstants.PREFIX_DS); PrivateKey privateKey; if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) { privateKey = keystore.getPrivateKey(certAlias); } else { privateKey = keystore.getPrivateKey(certAlias, encryptedKeyPass); } if (privateKey == null) { SAMLUtilsCommon.debug.error("private key is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullprivatekey")); } root = (Element) XPathAPI.selectSingleNode( doc, "//*[@" + idAttrName + "=\"" + id + "\"]"); if (root == null) { SAMLUtilsCommon.debug.error("signXML: could not" + " resolv id attribute"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("invalidIDAttribute")); } // Set the ID attribute if idAttrName is not the default. if (!idAttrName.equals(DEF_ID_ATTRIBUTE)) { root.setIdAttribute(idAttrName, true); } if (algorithm == null || algorithm.length() == 0) { algorithm = getKeyAlgorithm(privateKey); ; } if (!isValidAlgorithm(algorithm)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("invalidalgorithm")); } sig = new XMLSignature(doc, "", algorithm, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); if (xpath == null) { root.appendChild(sig.getElement()); } else { Node beforeNode = XPathAPI.selectSingleNode(doc, xpath); root.insertBefore(sig.getElement(), beforeNode); } sig.getSignedInfo().addResourceResolver(new OfflineResolver()); // do transform Transforms transforms = new Transforms(doc); transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE); transforms.addTransform( Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); String ref = "#" + id; sig.addDocument(ref, transforms, digestAlg); if (includeCert) { X509Certificate cert = (X509Certificate) keystore.getX509Certificate(certAlias); sig.addKeyInfo(cert); } sig.sign(privateKey); } catch (Exception e) { SAMLUtilsCommon.debug.error("signXML Exception: ", e); throw new XMLSignatureException(e.getMessage()); } return (sig.getElement()); } /** * Sign the xml string using enveloped signatures. * @param xmlString xml string to be signed * @param certAlias Signer's certificate alias name * @param algorithm XML Signature algorithm * @param id id attribute value of the node to be signed * @return XML signature string * @throws XMLSignatureException if the xml string could not be signed */ public java.lang.String signXML(java.lang.String xmlString, java.lang.String certAlias, java.lang.String algorithm, java.lang.String id) throws XMLSignatureException { if (xmlString == null || xmlString.length() == 0) { SAMLUtilsCommon.debug.error("signXML: xmlString is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (certAlias == null || certAlias.length() == 0) { SAMLUtilsCommon.debug.error("signXML: certAlias is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Element el = null; try { Document doc = XMLUtils.toDOMDocument(xmlString, SAMLUtilsCommon.debug); el = signXML(doc, certAlias, algorithm, id); } catch (Exception e) { SAMLUtilsCommon.debug.error("signXML Exception: ", e); throw new XMLSignatureException(e.getMessage()); } return XMLUtils.print(el); } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return signature dom object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias, java.lang.String algorithm, java.util.List ids) throws XMLSignatureException { return signXML(doc, certAlias, algorithm, null, ids); } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param transformAlag XML siganture transform algorithm * Those transfer constants are defined as * SAMLConstants.TRANSFORM_XXX. * @param ids list of id attribute values of nodes to be signed * @return signature dom object * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signXML(org.w3c.dom.Document doc, java.lang.String certAlias, java.lang.String algorithm, java.lang.String transformAlag, java.util.List ids) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("signXML: doc is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (certAlias == null || certAlias.length() == 0) { SAMLUtilsCommon.debug.error("signXML: certAlias is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } org.w3c.dom.Element root = doc.getDocumentElement(); XMLSignature signature = null; try { ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, SAMLConstants.PREFIX_DS); PrivateKey privateKey = (PrivateKey) keystore.getPrivateKey(certAlias); if (privateKey == null) { SAMLUtilsCommon.debug.error("private key is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullprivatekey")); } if (algorithm == null || algorithm.length() == 0) { algorithm = getKeyAlgorithm(privateKey); } if (!isValidAlgorithm(algorithm)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("invalidalgorithm")); } signature = new XMLSignature(doc, "", algorithm, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); root.appendChild(signature.getElement()); int size = ids.size(); for (int i = 0; i < size; ++i) { Transforms transforms = new Transforms(doc); if (transformAlag != null) { transforms.addTransform(transformAlag); } transforms.addTransform( Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); String id = (String) ids.get(i); if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("id = " +id); } signature.addDocument("#"+id, transforms, digestAlg); } X509Certificate cert = (X509Certificate) keystore.getX509Certificate(certAlias); signature.addKeyInfo(cert); signature.sign(privateKey); } catch (Exception e) { SAMLUtilsCommon.debug.error("signXML Exception: ", e); throw new XMLSignatureException(e.getMessage()); } return (signature.getElement()); } /** * * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param xmlString XML. * @param certAlias Signer's certificate alias name * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return XML signature string * @throws XMLSignatureException if the document could not be signed */ public java.lang.String signXML(java.lang.String xmlString, java.lang.String certAlias, java.lang.String algorithm, java.util.List ids) throws XMLSignatureException { if (xmlString == null || xmlString.length() == 0) { SAMLUtilsCommon.debug.error("signXML: xmlString is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (certAlias == null || certAlias.length() == 0) { SAMLUtilsCommon.debug.error("signXML: certAlias is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Element el = null; try { Document doc = XMLUtils.toDOMDocument(xmlString, SAMLUtilsCommon.debug); el = signXML(doc, certAlias, algorithm, ids); } catch (Exception e) { e.printStackTrace(); throw new XMLSignatureException(e.getMessage()); } return XMLUtils.print(el); } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param assertionID assertion ID * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return SAML Security Token signature * @throws XMLSignatureException if the document could not be signed */ public Element signWithWSSSAMLTokenProfile(Document doc, java.security.cert.Certificate cert, String assertionID, String algorithm, List ids) throws XMLSignatureException { return signWithWSSSAMLTokenProfile(doc, cert, assertionID, algorithm, ids, SOAPBindingConstants.WSF_10_VERSION); } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param assertionID assertion ID * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @param wsfVersion the web services version. * @return SAML Security Token signature * @throws XMLSignatureException if the document could not be signed */ public Element signWithWSSSAMLTokenProfile(Document doc, java.security.cert.Certificate cert, String assertionID, String algorithm, List ids, String wsfVersion) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("signXML: doc is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (cert == null) { SAMLUtilsCommon.debug.error("signWithWSSSAMLTokenProfile: " + "Certificate is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (assertionID == null) { SAMLUtilsCommon.debug.error("signWithWSSSAMLTokenProfile: " + "AssertionID is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } this.wsfVersion = wsfVersion; String wsseNS = SAMLConstants.NS_WSSE; String wsuNS = SAMLConstants.NS_WSU; if ((wsfVersion != null) && (wsfVersion.equals(SOAPBindingConstants.WSF_11_VERSION))) { wsseNS = WSSEConstants.NS_WSSE_WSF11; wsuNS = WSSEConstants.NS_WSU_WSF11; } Element root = (Element)doc.getDocumentElement(). getElementsByTagNameNS(wsseNS, SAMLConstants.TAG_SECURITY).item(0); XMLSignature signature = null; try { ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, SAMLConstants.PREFIX_DS); Element wsucontext = org.apache.xml.security.utils. XMLUtils.createDSctx(doc, "wsu", wsuNS); NodeList wsuNodes = (NodeList)XPathAPI.selectNodeList(doc, "//*[@wsu:Id]", wsucontext); if(wsuNodes != null && wsuNodes.getLength() != 0) { for(int i=0; i < wsuNodes.getLength(); i++) { Element elem = (Element) wsuNodes.item(i); String id = elem.getAttributeNS(wsuNS, "Id"); if (id != null && id.length() != 0) { elem.setIdAttributeNS(wsuNS, "Id", true); } } } String certAlias = keystore.getCertificateAlias(cert); PrivateKey privateKey = (PrivateKey) keystore.getPrivateKey(certAlias); if (privateKey == null) { SAMLUtilsCommon.debug.error("private key is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullprivatekey")); } if (algorithm == null || algorithm.length() == 0) { algorithm = getKeyAlgorithm(privateKey); } if (!isValidAlgorithm(algorithm)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("invalidalgorithm")); } signature = new XMLSignature(doc, "", algorithm, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); root.appendChild(signature.getElement()); int size = ids.size(); for (int i = 0; i < size; ++i) { Transforms transforms = new Transforms(doc); transforms.addTransform( Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); String id = (String) ids.get(i); if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("id = " +id); } signature.addDocument("#"+id, transforms, digestAlg); } KeyInfo keyInfo = signature.getKeyInfo(); Element securityTokenRef = doc.createElementNS(wsseNS, SAMLConstants.TAG_SECURITYTOKENREFERENCE); keyInfo.addUnknownElement(securityTokenRef); securityTokenRef.setAttributeNS(SAMLConstants.NS_XMLNS, SAMLConstants.TAG_XMLNS, wsseNS); securityTokenRef.setAttributeNS(SAMLConstants.NS_XMLNS, SAMLConstants.TAG_XMLNS_SEC, SAMLConstants.NS_SEC); securityTokenRef.setAttributeNS(null, SAMLConstants.TAG_USAGE, SAMLConstants.TAG_SEC_MESSAGEAUTHENTICATION); Element reference = doc.createElementNS(wsseNS, SAMLConstants.TAG_REFERENCE); reference.setAttributeNS(null, SAMLConstants.TAG_URI, "#"+assertionID); securityTokenRef.appendChild(reference); signature.sign(privateKey); } catch (Exception e) { SAMLUtilsCommon.debug.error("signWithWSSX509TokenProfile " + "Exception: ", e); throw new XMLSignatureException(e.getMessage()); } if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("SAML Signed doc = " + XMLUtils.print(doc.getDocumentElement())); } return signature.getElement(); } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return X509 Security Token signature * @throws XMLSignatureException if the document could not be signed */ public Element signWithWSSX509TokenProfile(Document doc, java.security.cert.Certificate cert, String algorithm, List ids) throws XMLSignatureException { return signWithWSSX509TokenProfile(doc, cert, algorithm, ids, SOAPBindingConstants.WSF_10_VERSION); } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @param wsfVersion the web services version. * @return X509 Security Token signature * @throws XMLSignatureException if the document could not be signed */ public Element signWithWSSX509TokenProfile(Document doc, java.security.cert.Certificate cert, String algorithm, List ids, String wsfVersion) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("signXML: doc is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("Soap Envlope: " + XMLUtils.print(doc.getDocumentElement())); } this.wsfVersion = wsfVersion; String wsseNS = SAMLConstants.NS_WSSE; String wsuNS = SAMLConstants.NS_WSU; if ((wsfVersion != null) && (wsfVersion.equals(SOAPBindingConstants.WSF_11_VERSION))) { wsseNS = WSSEConstants.NS_WSSE_WSF11; wsuNS = WSSEConstants.NS_WSU_WSF11; } Element root = (Element)doc.getDocumentElement(). getElementsByTagNameNS(wsseNS, SAMLConstants.TAG_SECURITY).item(0); XMLSignature signature = null; try { ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, SAMLConstants.PREFIX_DS); Element wsucontext = org.apache.xml.security.utils. XMLUtils.createDSctx(doc, "wsu", wsuNS); NodeList wsuNodes = (NodeList)XPathAPI.selectNodeList(doc, "//*[@wsu:Id]", wsucontext); if ((wsuNodes != null) && (wsuNodes.getLength() != 0)) { for(int i=0; i < wsuNodes.getLength(); i++) { Element elem = (Element) wsuNodes.item(i); String id = elem.getAttributeNS(wsuNS, "Id"); if (id != null && id.length() != 0) { elem.setIdAttributeNS(wsuNS, "Id", true); } } } String certAlias = keystore.getCertificateAlias(cert); PrivateKey privateKey = (PrivateKey) keystore.getPrivateKey(certAlias); if (privateKey == null) { SAMLUtilsCommon.debug.error("private key is null"); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullprivatekey")); } // TODO: code clean up // should find cert alias, add security token and call signXML // to avoid code duplication if (algorithm == null || algorithm.length() == 0) { algorithm = getKeyAlgorithm(privateKey); } if (!isValidAlgorithm(algorithm)) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("invalidalgorithm")); } signature = new XMLSignature(doc, "", algorithm, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); root.appendChild(signature.getElement()); int size = ids.size(); for (int i = 0; i < size; ++i) { Transforms transforms = new Transforms(doc); transforms.addTransform( Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); String id = (String) ids.get(i); if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("id = " +id); } signature.addDocument("#"+id, transforms, digestAlg); } KeyInfo keyInfo = signature.getKeyInfo(); Element securityTokenRef = doc.createElementNS(wsseNS, SAMLConstants.TAG_SECURITYTOKENREFERENCE); keyInfo.addUnknownElement(securityTokenRef); securityTokenRef.setAttributeNS(SAMLConstants.NS_XMLNS, SAMLConstants.TAG_XMLNS, wsseNS); securityTokenRef.setAttributeNS(SAMLConstants.NS_XMLNS, SAMLConstants.TAG_XMLNS_SEC, SAMLConstants.NS_SEC); securityTokenRef.setAttributeNS(null, SAMLConstants.TAG_USAGE, SAMLConstants.TAG_SEC_MESSAGEAUTHENTICATION); Element bsf = (Element)root.getElementsByTagNameNS(wsseNS, SAMLConstants.BINARYSECURITYTOKEN).item(0); String certId = bsf.getAttributeNS(wsuNS, SAMLConstants.TAG_ID); Element reference = doc.createElementNS(wsseNS, SAMLConstants.TAG_REFERENCE); securityTokenRef.appendChild(reference); reference.setAttributeNS(null, SAMLConstants.TAG_URI, "#"+certId); signature.sign(privateKey); } catch (Exception e) { SAMLUtilsCommon.debug.error("signWithWSSX509TokenProfile" + " Exception: ", e); throw new XMLSignatureException(e.getMessage()); } return (signature.getElement()); } /** * Verify all the signatures of the xml document * @param doc XML dom document whose signature to be verified * @param certAlias certAlias alias for Signer's certificate, this is used * to search signer's public certificate if it is not presented in * ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(Document doc, String certAlias) throws XMLSignatureException { return verifyXMLSignature(SOAPBindingConstants.WSF_10_VERSION, certAlias, doc); } /** * Verify all the signatures of the xml document * @param wsfVersion the web services version. * @param doc XML dom document whose signature to be verified * @param certAlias certAlias alias for Signer's certificate, this is used * to search signer's public certificate if it is not presented in * ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @exception XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(String wsfVersion, String certAlias, Document doc) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("verifyXMLSignature:" + " document is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } try { this.wsfVersion = wsfVersion; String wsuNS = SAMLConstants.NS_WSU; String wsseNS = SAMLConstants.NS_WSSE; if((wsfVersion != null) && (wsfVersion.equals(SOAPBindingConstants.WSF_11_VERSION))) { wsuNS = WSSEConstants.NS_WSU_WSF11; wsseNS = WSSEConstants.NS_WSSE_WSF11; } Element wsucontext = org.apache.xml.security.utils.XMLUtils.createDSctx(doc, "wsu", wsuNS); NodeList wsuNodes = (NodeList) XPathAPI.selectNodeList(doc, "//*[@wsu:Id]", wsucontext); if ((wsuNodes != null) && (wsuNodes.getLength() != 0)) { for (int i = 0; i < wsuNodes.getLength(); i++) { Element elem = (Element) wsuNodes.item(i); String id = elem.getAttributeNS(wsuNS, "Id"); if ((id != null) && (id.length() != 0)) { elem.setIdAttributeNS(wsuNS, "Id", true); } } } Element nscontext = org.apache.xml.security.utils. XMLUtils.createDSctx (doc,"ds",Constants.SignatureSpecNS); NodeList sigElements = XPathAPI.selectNodeList (doc, "//ds:Signature", nscontext); if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("verifyXMLSignature: " + "sigElements size = " + sigElements.getLength()); } X509Certificate newcert= keystore.getX509Certificate (certAlias); PublicKey key = keystore.getPublicKey (certAlias); Element sigElement = null; //loop for (int i = 0; i < sigElements.getLength(); i++) { sigElement = (Element)sigElements.item(i); if (SAMLUtilsCommon.debug.messageEnabled ()) { SAMLUtilsCommon.debug.message("Sig(" + i + ") = " + XMLUtils.print(sigElement)); } Element refElement; try { refElement = (Element) XPathAPI.selectSingleNode(sigElement, "//ds:Reference[1]", nscontext); } catch (XPathException te) { throw new XMLSignatureException(te); } String refUri = refElement.getAttribute("URI"); String signedId = null; Element parentElement = (Element) sigElement.getParentNode(); if (parentElement != null) { String idAttrName = null; if ("Assertion".equals(parentElement.getLocalName())) { idAttrName = "AssertionID"; } else if ("Response".equals(parentElement.getLocalName())) { idAttrName = "ResponseID"; } else if ("Request".equals(parentElement.getLocalName())) { idAttrName = "RequestID"; } else { throw new UnsupportedOperationException("Enveloping and detached XML signatures are no longer" + " supported"); } if (idAttrName != null) { parentElement.setIdAttribute(idAttrName, true); signedId = parentElement.getAttribute(idAttrName); } } //NB: this validation only works with enveloped XML signatures, enveloping and detached signatures are //no longer supported. if (refUri == null || signedId == null || !refUri.substring(1).equals(signedId)) { SAMLUtilsCommon.debug.error("Signature reference ID does not match with element ID"); throw new XMLSignatureException(SAMLUtilsCommon.bundle.getString("uriNoMatchWithId")); } XMLSignature signature = new XMLSignature (sigElement, ""); signature.addResourceResolver ( new com.sun.identity.saml.xmlsig.OfflineResolver ()); KeyInfo ki = signature.getKeyInfo (); PublicKey pk = this.getX509PublicKey(doc, ki); if (pk!=null) { // verify using public key if (signature.checkSignatureValue (pk)) { if (SAMLUtilsCommon.debug.messageEnabled ()) { SAMLUtilsCommon.debug.message ( "verifyXMLSignature:" + " Signature " + i + " verified"); } } else { if(SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message( "verifyXMLSignature:" + " Signature Verfication failed"); } return false; } } else { if (certAlias == null || certAlias.equals ("")) { if(SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message( "verifyXMLSignature:" + "Certificate Alias is null"); } return false; } if (SAMLUtilsCommon.debug.messageEnabled ()) { SAMLUtilsCommon.debug.message ( "Could not find a KeyInfo, " + "try to use certAlias"); } if (newcert != null) { if (signature.checkSignatureValue (newcert)) { if (SAMLUtilsCommon.debug.messageEnabled ()) { SAMLUtilsCommon.debug.message ( "verifyXMLSignature:" + " Signature " + i + " verified"); } } else { return false; } } else { if (key != null) { if (signature.checkSignatureValue (key)) { if (SAMLUtilsCommon.debug.messageEnabled ()) { SAMLUtilsCommon.debug.message ( "verifyXMLSignature: Signature " + i + " verified"); } } else { return false; } } else { SAMLUtilsCommon.debug.error ( "Could not find public key" + " based on certAlias to verify signature"); return false; } } } } return true; } catch (Exception ex) { SAMLUtilsCommon.debug.error("verifyXMLSignature Exception: ", ex); throw new XMLSignatureException (ex.getMessage ()); } } /** * Verify the signature of the xml document * @param doc XML dom document whose signature to be verified * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(org.w3c.dom.Document doc) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error( "verifyXMLSignature: document is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } return verifyXMLSignature(doc, (String)null); } /** * Verify the signature of the xml element. * * @param element XML dom element whose signature to be verified * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(org.w3c.dom.Element element) throws XMLSignatureException { if (element == null) { SAMLUtilsCommon.debug.error("signXML: element is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } return verifyXMLSignature(XMLUtils.print(element)); } /** * Verify the signature of the xml document * @param element XML Element whose signature to be verified * @param certAlias certAlias alias for Signer's certificate, this is used to search signer's public certificate if it is not presented in ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(org.w3c.dom.Element element, java.lang.String certAlias) throws XMLSignatureException { return verifyXMLSignature(element, DEF_ID_ATTRIBUTE, certAlias); } /** * Verify the signature of the xml document * @param element XML Element whose signature to be verified * @param idAttrName Attribute name for the id attribute * @param certAlias certAlias alias for Signer's certificate, this is used to search signer's public certificate if it is not presented in ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(org.w3c.dom.Element element, java.lang.String idAttrName, java.lang.String certAlias) throws XMLSignatureException { if (element == null) { SAMLUtilsCommon.debug.error("signXML: element is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Document doc = null; try { doc = XMLUtils.newDocument(); doc.appendChild(doc.importNode(element, true)); } catch (Exception ex) { SAMLUtilsCommon.debug.error("verifyXMLSignature Exception: ", ex); throw new XMLSignatureException(ex.getMessage()); } return verifyXMLSignature(doc, idAttrName, certAlias); } /** * Verify the signature of the xml document * @param doc XML dom document whose signature to be verified * @param cert Signer's certificate, this is used to search signer's public certificate if it is not presented in ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(org.w3c.dom.Document doc, java.security.cert.Certificate cert) throws XMLSignatureException { if (doc == null) { SAMLUtilsCommon.debug.error("verifyXMLSignature: " + "document is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } String certAlias = keystore.getCertificateAlias(cert); return verifyXMLSignature(doc, certAlias); } /** * Verify the signature of the xml string * @param xmlString XML string whose signature to be verified * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(java.lang.String xmlString) throws XMLSignatureException { return verifyXMLSignature(xmlString, null); } /** * Verify the signature of the xml string * @param xmlString XML string whose signature to be verified * @param certAlias certAlias alias for Signer's certificate, this is used to search signer's public certificate if it is not presented in ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(java.lang.String xmlString, java.lang.String certAlias) throws XMLSignatureException { return verifyXMLSignature(xmlString, DEF_ID_ATTRIBUTE, certAlias); } /** * Verify the signature of the xml string * @param xmlString XML string whose signature to be verified * @param idAttrName Attribute name for the id attribute * @param certAlias certAlias alias for Signer's certificate, this is used to search signer's public certificate if it is not presented in ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(java.lang.String xmlString, java.lang.String idAttrName, java.lang.String certAlias) throws XMLSignatureException { if (xmlString == null || xmlString.length() == 0) { SAMLUtilsCommon.debug.error("signXML: xmlString is null."); throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("nullInput")); } Document doc = XMLUtils.toDOMDocument(xmlString, SAMLUtilsCommon.debug); try { return verifyXMLSignature(doc, idAttrName, certAlias); } catch (Exception ex) { SAMLUtilsCommon.debug.error("verifyXMLSignature Exception: ", ex); throw new XMLSignatureException(ex.getMessage()); } } /** * Verify the signature of a DOM Document * @param doc a DOM Document * @param idAttrName Attribute name for the id attribute * @param certAlias certAlias alias for Signer's certificate, this is used to search signer's public certificate if it is not presented in ds:KeyInfo * @return true if the xml signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyXMLSignature(Document doc, java.lang.String idAttrName, java.lang.String certAlias) throws XMLSignatureException { try { Element nscontext = org.apache.xml.security.utils. XMLUtils.createDSctx(doc,"ds",Constants.SignatureSpecNS); Element sigElement = (Element) XPathAPI.selectSingleNode(doc, "//ds:Signature[1]", nscontext); Element refElement; try { refElement = (Element) XPathAPI.selectSingleNode(sigElement, "//ds:Reference[1]", nscontext); } catch (XPathException te) { throw new XMLSignatureException(te); } String refUri = refElement.getAttribute("URI"); String signedId = ((Element) sigElement.getParentNode()).getAttribute(idAttrName); if (refUri == null || signedId == null || !refUri.substring(1).equals(signedId)) { SAMLUtilsCommon.debug.error("Signature reference ID does not match with element ID"); throw new XMLSignatureException(SAMLUtilsCommon.bundle.getString("uriNoMatchWithId")); } XMLSignature signature = new XMLSignature(sigElement, ""); signature.addResourceResolver( new com.sun.identity.saml.xmlsig.OfflineResolver()); doc.getDocumentElement().setIdAttribute(idAttrName, true); KeyInfo ki = signature.getKeyInfo(); PublicKey pk = this.getX509PublicKey(doc, ki); if (pk!=null) { // verify using public key if (signature.checkSignatureValue (pk)) { return true; } else { return false; } } else { if (StringUtils.isEmpty(certAlias)) { if (SAMLUtilsCommon.debug.warningEnabled()) { SAMLUtilsCommon.debug.warning("Could not find a KeyInfo and certAlias was not defined"); } return false; } if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("Could not find a KeyInfo, " + "try to use certAlias"); } X509Certificate newcert= keystore.getX509Certificate(certAlias); if (newcert != null) { if (signature.checkSignatureValue(newcert)) { return true; } else { return false; } } else { PublicKey key = keystore.getPublicKey(certAlias); if (key != null) { if (signature.checkSignatureValue(key)) { return true; } else { return false; } } else { SAMLUtilsCommon.debug.error("Could not find " + "public key based on certAlias to verify" + " signature"); return false; } } } } catch (Exception ex) { SAMLUtilsCommon.debug.error("verifyXMLSignature Exception: ", ex); throw new XMLSignatureException(ex.getMessage()); } } /** * Get the real key provider * @return KeyProvider */ public KeyProvider getKeyProvider() { return keystore; } /** * Get the X509Certificate embedded in the KeyInfo * @param keyinfo KeyInfo * @return a X509Certificate */ protected PublicKey getX509PublicKey(Document doc, KeyInfo keyinfo) { PublicKey pk = null; try { if (keyinfo != null) { if (isJKSKeyStore) { StorageResolver storageResolver = new StorageResolver( new KeyStoreResolver(((JKSKeyProvider) keystore).getKeyStore())); keyinfo.addStorageResolver(storageResolver); keyinfo.registerInternalKeyResolver(new X509IssuerSerialResolver()); keyinfo.registerInternalKeyResolver(new X509CertificateResolver()); keyinfo.registerInternalKeyResolver(new X509SKIResolver()); keyinfo.registerInternalKeyResolver(new X509SubjectNameResolver()); } if (keyinfo.containsX509Data()) { if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("Found X509Data" + " element in the KeyInfo"); } X509Certificate certificate = keyinfo.getX509Certificate(); //use a systemproperty com.sun.identity.saml.checkcert //defined in AMConfig.properties, as a nob to check the // the validity of the cert. if (checkCert) { // validate the X509Certificate if (keystore.getCertificateAlias(certificate)==null) { SAMLUtilsCommon.debug.error ("verifyXMLSignature:" + " certificate is not trusted."); throw new XMLSignatureException ( SAMLUtilsCommon.bundle.getString( "untrustedCertificate")); } else { if (SAMLUtilsCommon.debug.messageEnabled ()) { SAMLUtilsCommon.debug.message( "verifyXMLSignature:"+ " certificate is trused."); } } } else { if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message( "Skip checking whether the" +" cert in the cert db."); } } pk = getPublicKey(certificate); } else { // Do we need to check if the public key is in the // keystore!? pk = getWSSTokenProfilePublicKey(doc); } } } catch (Exception e) { SAMLUtilsCommon.debug.error( "getX509Certificate(KeyInfo) Exception: ", e); } return pk; } /** * Get the PublicKey embedded in the Security Token profile * @param doc the document to be verified * @return a PublicKey */ private PublicKey getWSSTokenProfilePublicKey(Document doc) { PublicKey pubKey = null; try { SAMLUtilsCommon.debug.message("getWSSTTokenProfilePublicKey:"+ " entering"); String wsseNS = SAMLConstants.NS_WSSE; String wsuNS = SAMLConstants.NS_WSU; if ((wsfVersion != null) && (wsfVersion.equals(SOAPBindingConstants.WSF_11_VERSION)) ) { wsseNS = WSSEConstants.NS_WSSE_WSF11; wsuNS = WSSEConstants.NS_WSU_WSF11; } Element securityElement = (Element) doc.getDocumentElement(). getElementsByTagNameNS(wsseNS, SAMLConstants.TAG_SECURITY). item(0); if (securityElement == null) { return null; } Element nscontext = org.apache.xml.security.utils. XMLUtils.createDSctx(doc,"ds",Constants.SignatureSpecNS); Element sigElement = (Element) XPathAPI.selectSingleNode( securityElement, "ds:Signature[1]", nscontext); Element keyinfo = (Element) sigElement.getElementsByTagNameNS( Constants.SignatureSpecNS, SAMLConstants.TAG_KEYINFO).item(0); Element str = (Element) keyinfo.getElementsByTagNameNS(wsseNS, SAMLConstants.TAG_SECURITYTOKENREFERENCE).item(0); Element reference = (Element) keyinfo.getElementsByTagNameNS( wsseNS, SAMLConstants.TAG_REFERENCE).item(0); if (reference != null) { String id = reference.getAttribute(SAMLConstants.TAG_URI); id = id.substring(1); nscontext = org.apache.xml.security.utils. XMLUtils.createDSctx(doc, SAMLConstants.PREFIX_WSU, wsuNS); Node n = XPathAPI.selectSingleNode( doc, "//*[@"+ SAMLConstants.PREFIX_WSU + ":" + SAMLConstants.TAG_ID +"=\"" + id + "\"]", nscontext); if (n != null) { // X509 Security Token profile SAMLUtilsCommon.debug.message("X509 Token"); String format = ((Element) n).getAttribute( SAMLConstants.TAG_VALUETYPE); NodeList children = n.getChildNodes(); n = children.item(0); String certString = n.getNodeValue().trim(); pubKey = getPublicKey(getCertificate(certString, format)); } else { // SAML Token profile SAMLUtilsCommon.debug.message("SAML Token"); reference = (Element) XPathAPI.selectSingleNode( doc, "//*[@AssertionID=\"" + id + "\"]"); if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("SAML Assertion = " + XMLUtils.print(reference)); } // The SAML Statements contain keyinfo, they should be // all the same. get the first keyinfo! reference = (Element) reference.getElementsByTagNameNS( Constants.SignatureSpecNS, SAMLConstants.TAG_KEYINFO).item(0); if (reference == null) { // no cert found! SAMLUtilsCommon.debug.message( "getWSSTokenProfilePublicKey:" + " no KeyInfo found!"); throw new Exception( SAMLUtilsCommon.bundle.getString("nullKeyInfo")); } Element x509Data = (Element) reference.getElementsByTagNameNS( Constants.SignatureSpecNS, SAMLConstants.TAG_X509DATA).item(0); if (x509Data !=null) { // Keyinfo constains certificate reference = (Element) x509Data.getChildNodes().item(0); String certString = x509Data.getChildNodes().item(0). getChildNodes().item(0). getNodeValue(); if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("certString = " + certString); } return getPublicKey(getCertificate(certString, null)); } else { // it should contains RSA/DSA key pubKey = getPublicKeybyDSARSAkeyValue(doc, reference); } } } else { SAMLUtilsCommon.debug.error("getWSSTokenProfilePublicKey:" + " unknow Security Token Reference"); } } catch (Exception e) { SAMLUtilsCommon.debug.error( "getWSSTokenProfilePublicKey Exception: ", e); } return pubKey; } protected PublicKey getPublicKeybyDSARSAkeyValue(Document doc, Element reference) throws XMLSignatureException { PublicKey pubKey = null; Element dsaKey = (Element) reference.getElementsByTagNameNS( Constants.SignatureSpecNS, SAMLConstants.TAG_DSAKEYVALUE).item(0); if (dsaKey != null) { // It's DSAKey NodeList nodes = dsaKey.getChildNodes(); int nodeCount = nodes.getLength(); if (nodeCount > 0) { BigInteger p=null, q=null, g=null, y=null; for (int i = 0; i < nodeCount; i++) { Node currentNode = nodes.item(i); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { String tagName = currentNode.getLocalName(); Node sub = currentNode.getChildNodes().item(0); String value = sub.getNodeValue(); BigInteger v = new BigInteger( Base64.decode( SAMLUtilsCommon.removeNewLineChars(value))); if (tagName.equals("P")) { p = v; } else if (tagName.equals("Q")) { q = v; } else if (tagName.equals("G")) { g = v; } else if (tagName.equals("Y")) { y = v; } else { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString( "errorObtainPK")); } } } DSAKeyValue dsaKeyValue = new DSAKeyValue(doc, p, q, g, y); try { pubKey = dsaKeyValue.getPublicKey(); } catch (Exception e) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("errorObtainPK")); } } } else { Element rsaKey = (Element) reference.getElementsByTagNameNS( Constants.SignatureSpecNS, SAMLConstants.TAG_RSAKEYVALUE).item(0); if (rsaKey != null) { // It's RSAKey NodeList nodes = rsaKey.getChildNodes(); int nodeCount = nodes.getLength(); BigInteger m=null, e=null; if (nodeCount > 0) { for (int i = 0; i < nodeCount; i++) { Node currentNode = nodes.item(i); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { String tagName = currentNode.getLocalName(); Node sub = currentNode.getChildNodes().item(0); String value = sub.getNodeValue(); BigInteger v = new BigInteger( Base64.decode( SAMLUtilsCommon.removeNewLineChars(value))); if (tagName.equals("Exponent")) { e = v; } else if (tagName.equals("Modulus")){ m = v; } else { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString( "errorObtainPK")); } } } } RSAKeyValue rsaKeyValue = new RSAKeyValue(doc,m, e); try { pubKey = rsaKeyValue.getPublicKey(); } catch (Exception ex) { throw new XMLSignatureException( SAMLUtilsCommon.bundle.getString("errorObtainPK")); } } } return pubKey; } /** * Get the X509Certificate from encoded cert string * @param certString BASE64 or PKCS7 encoded certtificate string * @param format encoded format * @return a X509Certificate */ protected X509Certificate getCertificate(String certString, String format) { X509Certificate cert = null; try { if (SAMLUtilsCommon.debug.messageEnabled()) { SAMLUtilsCommon.debug.message("getCertificate(Assertion) : " + certString); } StringBuffer xml = new StringBuffer(100); xml.append(SAMLConstants.BEGIN_CERT); xml.append(certString); xml.append(SAMLConstants.END_CERT); byte[] barr = null; barr = (xml.toString()).getBytes(); CertificateFactory cf = CertificateFactory.getInstance("X.509"); ByteArrayInputStream bais = new ByteArrayInputStream(barr); if ((format !=null) && format.equals(SAMLConstants.TAG_PKCS7)) { // PKCS7 format Collection c = cf.generateCertificates(bais); Iterator i = c.iterator(); while (i.hasNext()) { cert = (java.security.cert.X509Certificate) i.next(); } } else { //X509:v3 format while (bais.available() > 0) { cert = (java.security.cert.X509Certificate) cf.generateCertificate(bais); } } } catch (Exception e) { SAMLUtilsCommon.debug.error("getCertificate Exception: ", e); } return cert; } /** * Returns the public key from the certificate embedded in the KeyInfo. * * @param cert X509 Certificate * @return a public key from the certificate embedded in the KeyInfo. */ protected PublicKey getPublicKey(X509Certificate cert) { PublicKey pk = null; if (cert != null) { pk = cert.getPublicKey(); } return pk; } protected boolean isValidAlgorithm(String algorithm) { if (algorithm.equals(SAMLConstants.ALGO_ID_MAC_HMAC_SHA1) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_DSA) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_RSA) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_RSA_SHA1) || algorithm.equals(SAMLConstants. ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_RSA_RIPEMD160) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_RSA_SHA256) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_RSA_SHA384) || algorithm.equals(SAMLConstants.ALGO_ID_SIGNATURE_RSA_SHA512) || algorithm.equals(SAMLConstants.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5) || algorithm.equals(SAMLConstants.ALGO_ID_MAC_HMAC_RIPEMD160) || algorithm.equals(SAMLConstants.ALGO_ID_MAC_HMAC_SHA256) || algorithm.equals(SAMLConstants.ALGO_ID_MAC_HMAC_SHA384) || algorithm.equals(SAMLConstants.ALGO_ID_MAC_HMAC_SHA512)) { return true; } else { return false; } } private boolean isValidCanonicalizationMethod(String algorithm) { if (algorithm.equals(SAMLConstants.ALGO_ID_C14N_OMIT_COMMENTS) || algorithm.equals(SAMLConstants.ALGO_ID_C14N_WITH_COMMENTS) || algorithm.equals(SAMLConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS) || algorithm.equals(SAMLConstants.ALGO_ID_C14N_EXCL_WITH_COMMENTS)) { return true; } else { return false; } } private boolean isValidTransformAlgorithm(String algorithm) { if (algorithm.equals(SAMLConstants.TRANSFORM_C14N_OMIT_COMMENTS) || algorithm.equals(SAMLConstants.TRANSFORM_C14N_WITH_COMMENTS) || algorithm.equals(SAMLConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS) || algorithm.equals(SAMLConstants.TRANSFORM_C14N_EXCL_WITH_COMMENTS) || algorithm.equals(SAMLConstants.TRANSFORM_XSLT) || algorithm.equals(SAMLConstants.TRANSFORM_BASE64_DECODE) || algorithm.equals(SAMLConstants.TRANSFORM_XPATH ) || algorithm.equals(SAMLConstants.TRANSFORM_ENVELOPED_SIGNATURE) || algorithm.equals(SAMLConstants.TRANSFORM_XPOINTER) || algorithm.equals(SAMLConstants.TRANSFORM_XPATH2FILTER04) || algorithm.equals(SAMLConstants.TRANSFORM_XPATH2FILTER) || algorithm.equals(SAMLConstants.TRANSFORM_XPATHFILTERCHGP)) { return true; } else { return false; } } private String getKeyAlgorithm(PrivateKey pk) { if (defaultSigAlg != null && !defaultSigAlg.equals("")) { return defaultSigAlg; } if (pk.getAlgorithm().equalsIgnoreCase("DSA")) { return SAMLConstants.ALGO_ID_SIGNATURE_DSA; } return SAMLConstants.ALGO_ID_SIGNATURE_RSA_SHA1; } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param assertionID assertion ID * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return SAML Security Token signature * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signWithSAMLToken( org.w3c.dom.Document doc, java.security.cert.Certificate cert, String assertionID, java.lang.String algorithm, java.util.List ids) throws XMLSignatureException { return null; } /** * Sign part of the XML document referred by the supplied a list * of id attributes of nodes using SAML Token. * @param doc XML dom object * @param key the key that will be used to sign the document. * @param symmetricKey true if the supplied key is a symmetric key type. * @param sigingCert signer's Certificate. If present, this certificate * will be added as part of signature KeyInfo. * @param encryptCert the certificate if present will be used to encrypt * the symmetric key and replay it as part of KeyInfo * @param assertionID assertion ID for the SAML Security Token * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return SAML Security Token signature * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signWithSAMLToken( org.w3c.dom.Document doc, java.security.Key key, boolean symmetricKey, java.security.cert.Certificate sigingCert, java.security.cert.Certificate encryptCert, java.lang.String assertionID, java.lang.String algorithm, java.util.List ids) throws XMLSignatureException { return null; } public org.w3c.dom.Element signWithKerberosToken( org.w3c.dom.Document doc, java.security.Key key, java.lang.String algorithm, java.util.List ids) throws XMLSignatureException { return null; } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @return X509 Security Token signature * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signWithUserNameToken( org.w3c.dom.Document doc, java.security.cert.Certificate cert, java.lang.String algorithm, java.util.List ids) throws XMLSignatureException { return null; } /** * Sign part of the xml document referered by the supplied a list * of id attributes of nodes * @param doc XML dom object * @param cert Signer's certificate * @param algorithm XML signature algorithm * @param ids list of id attribute values of nodes to be signed * @param referenceType signed element reference type * @return X509 Security Token signature * @throws XMLSignatureException if the document could not be signed */ public org.w3c.dom.Element signWithBinarySecurityToken( org.w3c.dom.Document doc, java.security.cert.Certificate cert, java.lang.String algorithm, java.util.List ids, java.lang.String referenceType) throws XMLSignatureException { return null; } /** * Verify all the signatures of the XML document for the * web services security. * @param document XML dom document whose signature to be verified * * @param certAlias alias for Signer's certificate, this is used to search * signer's public certificate if it is not presented in * ds:KeyInfo. * @return true if the XML signature is verified, false otherwise * @throws XMLSignatureException if problem occurs during verification */ public boolean verifyWSSSignature(org.w3c.dom.Document document, java.lang.String certAlias) throws XMLSignatureException { return false; } /** * Verify web services message signature using specified key * @param document the document to be validated * @param key the secret key to be used for validating signature * @return true if verification is successful. * @throws com.sun.identity.saml.xmlsig.XMLSignatureException */ public boolean verifyWSSSignature(org.w3c.dom.Document document, java.security.Key key) throws XMLSignatureException { return false; } /** * Verify web services message signature using specified key * @param document the document to be validated * @param key the secret key to be used for validating signature * @param certAlias the certificate alias used for validating the signature * if the key is not available. * @param encryptAlias the certificate alias that may be used to decrypt * the symmetric key that may be part of KeyInfo * @return true if verification is successful. * @throws com.sun.identity.saml.xmlsig.XMLSignatureException */ public boolean verifyWSSSignature(org.w3c.dom.Document document, java.security.Key key, String certAlias, String encryptAlias) throws XMLSignatureException { return false; } /** * Return algorithm URI for the given algorithm. */ protected String getAlgorithmURI(String algorithm) { if(algorithm == null) { return null; } if(algorithm.equals("RSA")) { return SAMLConstants.ALGO_ID_SIGNATURE_RSA; } else if(algorithm.equals("DSA")) { return SAMLConstants.ALGO_ID_SIGNATURE_DSA; } else { return null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy