STRTransform.java revision 4a2f0f0be43dfd4c1b490cbf3cc48b6ba6084b1c
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster/**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster *
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster *
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * The contents of this file are subject to the terms
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * of the Common Development and Distribution License
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * (the License). You may not use this file except in
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * compliance with the License.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster *
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * You can obtain a copy of the License at
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * opensso/legal/CDDLv1.0.txt
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * See the License for the specific language governing
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * permission and limitations under the License.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster *
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * When distributing Covered Code, include this CDDL
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Header Notice in each file and include the License file
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * at opensso/legal/CDDLv1.0.txt.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * If applicable, add the following below the CDDL Header,
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * with the fields enclosed by brackets [] replaced by
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * your own identifying information:
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster *
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * $Id: STRTransform.java,v 1.6 2008/07/21 17:18:32 mallas Exp $
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster *
590e03a0114f53c994d970cfb356dadaaa57e39dJaco Jooste */
3286da3756e1d2f07709aafdbc5419b26ff71dffPhill Cunnington
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterpackage com.sun.identity.wss.security;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport java.io.IOException;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport java.security.cert.X509Certificate;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport org.w3c.dom.Document;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport org.w3c.dom.Element;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport org.w3c.dom.Node;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.c14n.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster InvalidCanonicalizerException;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.transforms.Transform;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.transforms.TransformSpi;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.transforms.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster TransformationException;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.org.apache.xml.internal.security.keys.content.X509Data;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.identity.shared.xml.XMLUtils;
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterimport com.sun.identity.shared.debug.Debug;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster/**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * This class <code>STRTransform</code> extends from <code>TransformSpi</code>
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * and will be used to transform the <code>XMLSignatureInput</code> as
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * required by the WS-Security specification.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster */
0a99555401a033704f1f171baab6db11fb5528f2Allan Fosterpublic class STRTransform extends TransformSpi {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster public static final String STR_TRANSFORM_URI =
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster "http://docs.oasis-open.org/wss/2004/01/" +
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster "oasis-200401-wss-soap-message-security-1.0#STR-Transform";
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
d135fba117a27e6d0de2f5518a274bba4c0a38efJames Phillpotts
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster private static String XMLNS = "xmlns=";
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster //private static Debug debug = WSSUtils.debug;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster static {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster try {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Transform.register(STR_TRANSFORM_URI, STRTransform.class.getName());
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster } catch (Exception e) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster //debug.message("STRTransform.static already registered");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster /**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Returns the transformation engine URI.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster */
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster protected String engineGetURI() {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return STR_TRANSFORM_URI;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster /**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Perform the XMLSignature transformation for the given input.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster */
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster throws IOException, CanonicalizationException,
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster InvalidCanonicalizerException, TransformationException {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.message("STRTransform.enginePerformTransform:: Start");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Document doc = this._transformObject.getDocument();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Element str = null;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster if(input.isElement()) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster } else {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.error("STRTransform.enginePerformTransform:: Input" +
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster " is not an element");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster throw new CanonicalizationException(
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.bundle.getString("invalidElement"));
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Element element = (Element)input.getSubNode();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster if(!WSSConstants.TAG_SECURITYTOKEN_REFERENCE.equals(
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster element.getLocalName())) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.error("STRTransform.enginePerformTransform:: input" +
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster " must be security token reference");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster throw new IOException(
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.bundle.getString("invalidElement"));
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Element dereferencedToken = null;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster SecurityTokenReference ref = null;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster try {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster ref = new SecurityTokenReference(element);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster dereferencedToken = dereferenceSTR(doc, ref);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster } catch (SecurityException se) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.error("STRTransform.enginePerformTransform:: error",
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster se);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster throw new TransformationException(
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.bundle.getString("transformfailed"));
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
ece5a262d20a50d0abf584d0f7ec73929ede9cfdJaco Jooste String canonAlgo = getCanonicalizationAlgo();
590e03a0114f53c994d970cfb356dadaaa57e39dJaco Jooste Canonicalizer canon = Canonicalizer.getInstance(canonAlgo);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster byte[] buf = canon.canonicalizeSubtree(dereferencedToken, "#default");
d135fba117a27e6d0de2f5518a274bba4c0a38efJames Phillpotts StringBuffer bf = new StringBuffer(new String(buf));
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster String bf1 = bf.toString();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster int lt = bf1.indexOf("<");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster int gt = bf1.indexOf(">");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster int idx = bf1.indexOf(XMLNS);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster if (idx < 0 || idx > gt) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster idx = bf1.indexOf(" ");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster bf.insert(idx + 1, "xmlns=\"\" ");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster bf1 = bf.toString();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return new XMLSignatureInput(bf1.getBytes());
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster /**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Derefence the security token reference from the given document.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster */
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster private Element dereferenceSTR(Document doc, SecurityTokenReference secRef)
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster throws SecurityException {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.message("STRTransform.deferenceSTR:: start");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Element tokenElement = null;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster String refType = secRef.getReferenceType();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster if(SecurityTokenReference.DIRECT_REFERENCE.equals(refType)) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.message("STRTRansform.deferenceSTR:: Direct " +
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster "reference");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster tokenElement = secRef.getTokenElement(doc);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster } else if(SecurityTokenReference.X509DATA_REFERENCE.equals(refType)) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.message("STRTRansform.deferenceSTR:: X509 data " +
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster "reference");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster X509Data x509Data = secRef.getX509IssuerSerial();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster X509Certificate cert =
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster AMTokenProvider.getX509Certificate(x509Data);
590e03a0114f53c994d970cfb356dadaaa57e39dJaco Jooste tokenElement = createBinaryToken(doc, cert);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster } else if(SecurityTokenReference.KEYIDENTIFIER_REFERENCE.
f56a278c148b90f6c2a675e0c1fa8686ca5abed4Robert Wapshott equals(refType)) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSUtils.debug.message("STRTRansform.deferenceSTR:: keyidentifier" +
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster " reference");
3286da3756e1d2f07709aafdbc5419b26ff71dffPhill Cunnington KeyIdentifier keyIdentifier = secRef.getKeyIdentifier();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster String valueType = keyIdentifier.getValueType();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster if(WSSConstants.ASSERTION_VALUE_TYPE.equals(valueType) ||
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSConstants.SAML2_ASSERTION_VALUE_TYPE.equals(valueType)) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster tokenElement = keyIdentifier.getTokenElement(doc);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster } else {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster X509Certificate cert = keyIdentifier.getX509Certificate();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster tokenElement = createBinaryToken(doc, cert);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
d135fba117a27e6d0de2f5518a274bba4c0a38efJames Phillpotts }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return tokenElement;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster /**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Creates binary security token using the given x509 certificate.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster */
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster private Element createBinaryToken(Document doc,
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster X509Certificate cert) throws SecurityException {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster BinarySecurityToken token = new BinarySecurityToken(cert,
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster BinarySecurityToken.X509V3, BinarySecurityToken.BASE64BINARY);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Element tokenE = token.toDocumentElement();
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster doc.importNode(tokenE, true);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return tokenE;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster /**
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Returns the canonicalization algorithm in transformation params.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster */
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster private String getCanonicalizationAlgo() {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster String canonAlgo = null;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster if (this._transformObject.length(WSSConstants.WSSE_NS,
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSConstants.TRANSFORMATION_PARAMETERS) == 1) {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Node tmpE = XMLUtils.getChildNode(
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster this._transformObject.getElement(), WSSConstants.WSSE_TAG + ":"
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster + WSSConstants.TRANSFORMATION_PARAMETERS);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster Element canonElem = (Element) WSSUtils.getDirectChild(
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster tmpE, "CanonicalizationMethod",
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster WSSConstants.XMLSIG_NAMESPACE_URI);
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster canonAlgo = canonElem.getAttribute("Algorithm");
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return canonAlgo;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster public boolean wantsOctetStream () {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return true;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster public boolean wantsNodeSet () {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return true;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster public boolean returnsOctetStream () {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return true;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster public boolean returnsNodeSet () {
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster return false;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster }
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster}
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster