Package com.eviware.soapui.impl.wsdl.support.wss.entries

Source Code of com.eviware.soapui.impl.wsdl.support.wss.entries.SignatureEntry$BinarySecurityTokenDOMCallbackLookup

/*
* Copyright 2004-2014 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/

package com.eviware.soapui.impl.wsdl.support.wss.entries;

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;

import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.message.DOMCallbackLookup;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.WSSEntryConfig;
import com.eviware.soapui.impl.wsdl.support.wss.OutgoingWss;
import com.eviware.soapui.impl.wsdl.support.wss.WssCrypto;
import com.eviware.soapui.impl.wsdl.support.wss.support.KeystoresComboBoxModel;
import com.eviware.soapui.impl.wsdl.support.wss.support.WSPartsTable;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.components.SimpleBindingForm;
import com.eviware.soapui.support.types.StringToStringMap;
import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
import com.eviware.soapui.support.xml.XmlUtils;
import com.jgoodies.binding.PresentationModel;

public class SignatureEntry extends WssEntryBase {
    private static final String DEFAULT_OPTION = "<default>";
    public static final String TYPE = "Signature";
    private String crypto;
    private int keyIdentifierType = 0;
    private String signatureAlgorithm;
    private boolean useSingleCert;
    private String signatureCanonicalization;
    private String digestAlgorithm;
    private List<StringToStringMap> parts = new ArrayList<StringToStringMap>();
    private com.eviware.soapui.impl.wsdl.support.wss.entries.WssEntryBase.KeyAliasComboBoxModel keyAliasComboBoxModel;
    private com.eviware.soapui.impl.wsdl.support.wss.entries.SignatureEntry.InternalWssContainerListener wssContainerListener;

    public void init(WSSEntryConfig config, OutgoingWss container) {
        super.init(config, container, TYPE);
    }

    @Override
    protected JComponent buildUI() {
        SimpleBindingForm form = new SimpleBindingForm(new PresentationModel<SignatureEntry>(this));
        form.addSpace(5);
        wssContainerListener = new InternalWssContainerListener();
        getWssContainer().addWssContainerListener(wssContainerListener);

        form.appendComboBox("crypto", "Keystore",
                new KeystoresComboBoxModel(getWssContainer(), getWssContainer().getCryptoByName(crypto), true),
                "Selects the Keystore containing the key to use for signing").addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                keyAliasComboBoxModel.update(getWssContainer().getCryptoByName(crypto));
            }
        });

        keyAliasComboBoxModel = new KeyAliasComboBoxModel(getWssContainer().getCryptoByName(crypto));
        form.appendComboBox("username", "Alias", keyAliasComboBoxModel, "The alias for the key to use for encryption");

        form.appendPasswordField("password", "Password", "The certificate password");

        form.appendComboBox("keyIdentifierType", "Key Identifier Type", new Integer[]{1, 2, 3, 4, 8},
                "Sets which key identifier to use").setRenderer(new KeyIdentifierTypeRenderer());
        form.appendComboBox("signatureAlgorithm", "Signature Algorithm", new String[]{DEFAULT_OPTION, WSConstants.RSA,
                WSConstants.DSA, XMLSignature.ALGO_ID_MAC_HMAC_SHA1, XMLSignature.ALGO_ID_MAC_HMAC_SHA256,
                XMLSignature.ALGO_ID_MAC_HMAC_SHA384, XMLSignature.ALGO_ID_MAC_HMAC_SHA512,
                XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160, XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
                XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1, XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
                XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256,
                XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512,
                XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160}, "Set the name of the signature encryption algorithm to use");
        form.appendComboBox("signatureCanonicalization", "Signature Canonicalization", new String[]{DEFAULT_OPTION,
                WSConstants.C14N_OMIT_COMMENTS, WSConstants.C14N_WITH_COMMENTS, WSConstants.C14N_EXCL_OMIT_COMMENTS,
                WSConstants.C14N_EXCL_WITH_COMMENTS}, "Set the canonicalization method to use.");

        form.appendComboBox("digestAlgorithm", "Digest Algorithm", new String[]{DEFAULT_OPTION,
                MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5, MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1,
                MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256, MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA384,
                MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512, MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160},
                "Set the digest algorithm to use");

        form.appendCheckBox("useSingleCert", "Use Single Certificate", "Use single certificate for signing");

        form.append("Parts", new WSPartsTable(parts, this));

        return new JScrollPane(form.getPanel());
    }

    @Override
    public void release() {
        if (wssContainerListener != null) {
            getWssContainer().removeWssContainerListener(wssContainerListener);
        }
    }

    @Override
    protected void load(XmlObjectConfigurationReader reader) {
        crypto = reader.readString("crypto", null);
        keyIdentifierType = readKeyIdentifierType(reader);
        signatureAlgorithm = reader.readString("signatureAlgorithm", null);
        signatureCanonicalization = reader.readString("signatureCanonicalization", null);
        useSingleCert = reader.readBoolean("useSingleCert", false);

        digestAlgorithm = reader.readString("digestAlgorithm", null);

        parts = readTableValues(reader, "signaturePart");
    }

    @Override
    protected void save(XmlObjectConfigurationBuilder builder) {
        builder.add("crypto", crypto);
        builder.add("keyIdentifierType", keyIdentifierType);
        builder.add("signatureAlgorithm", signatureAlgorithm);
        builder.add("signatureCanonicalization", signatureCanonicalization);
        builder.add("useSingleCert", useSingleCert);

        builder.add("digestAlgorithm", digestAlgorithm);

        saveTableValues(builder, parts, "signaturePart");
    }

    public void process(WSSecHeader secHeader, Document doc, PropertyExpansionContext context) {
        StringWriter writer = null;

        try {
            WssCrypto wssCrypto = getWssContainer().getCryptoByName(crypto);
            if (wssCrypto == null) {
                throw new Exception("Missing crypto [" + crypto + "] for signature entry");
            }

            WSSecSignature wssSign = new WSSecSignature();
            wssSign.setUserInfo(context.expand(getUsername()), context.expand(getPassword()));

            // default is
            // http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/WSConstants.html#ISSUER_SERIAL
            if (keyIdentifierType != 0) {
                wssSign.setKeyIdentifierType(keyIdentifierType);
            }

            if (StringUtils.hasContent(signatureAlgorithm) && !signatureAlgorithm.equals(DEFAULT_OPTION)) {
                wssSign.setSignatureAlgorithm(signatureAlgorithm);
            }

            if (StringUtils.hasContent(signatureCanonicalization) && !signatureCanonicalization.equals(DEFAULT_OPTION)) {
                wssSign.setSigCanonicalization(signatureCanonicalization);
            }

            wssSign.setUseSingleCertificate(useSingleCert);

            if (StringUtils.hasContent(digestAlgorithm)) {
                wssSign.setDigestAlgo(digestAlgorithm);
            }

            Vector<WSEncryptionPart> wsParts = createWSParts(parts);
            if (!wsParts.isEmpty()) {
                wssSign.setParts(wsParts);
            }

            writer = new StringWriter();
            XmlUtils.serialize(doc, writer);

            wssSign.setCallbackLookup(new BinarySecurityTokenDOMCallbackLookup(doc, wssSign));
            wssSign.build(doc, wssCrypto.getCrypto(), secHeader);
        } catch (Exception e) {
            SoapUI.logError(e);

            if (writer != null && writer.getBuffer().length() > 0) {
                try {
                    doc.replaceChild(doc.importNode(XmlUtils.parseXml(writer.toString()).getDocumentElement(), true),
                            doc.getDocumentElement());
                } catch (Exception e1) {
                    SoapUI.logError(e1);
                }
            }
        }
    }

    @Override
    protected void addPropertyExpansions(PropertyExpansionsResult result) {
        super.addPropertyExpansions(result);
    }

    public String getCrypto() {
        return crypto;
    }

    public void setCrypto(String crypto) {
        this.crypto = crypto;
        saveConfig();
    }

    public int getKeyIdentifierType() {
        return keyIdentifierType;
    }

    public void setKeyIdentifierType(int keyIdentifierType) {
        this.keyIdentifierType = keyIdentifierType;
        saveConfig();
    }

    public String getSignatureAlgorithm() {
        return StringUtils.isNullOrEmpty(signatureAlgorithm) ? DEFAULT_OPTION : signatureAlgorithm;
    }

    public void setSignatureAlgorithm(String signatureAlgorithm) {
        if (DEFAULT_OPTION.equals(signatureAlgorithm)) {
            signatureAlgorithm = null;
        }

        this.signatureAlgorithm = signatureAlgorithm;
        saveConfig();
    }

    public String getDigestAlgorithm() {
        return StringUtils.isNullOrEmpty(digestAlgorithm) ? DEFAULT_OPTION : digestAlgorithm;
    }

    public void setDigestAlgorithm(String digestAlgorithm) {
        if (DEFAULT_OPTION.equals(digestAlgorithm)) {
            digestAlgorithm = null;
        }

        this.digestAlgorithm = digestAlgorithm;
        saveConfig();
    }

    public String getSignatureCanonicalization() {
        return StringUtils.isNullOrEmpty(signatureCanonicalization) ? DEFAULT_OPTION : signatureCanonicalization;
    }

    public void setSignatureCanonicalization(String signatureCanonicalization) {
        if (DEFAULT_OPTION.equals(signatureCanonicalization)) {
            signatureCanonicalization = null;
        }

        this.signatureCanonicalization = signatureCanonicalization;
        saveConfig();
    }

    public boolean isUseSingleCert() {
        return useSingleCert;
    }

    public void setUseSingleCert(boolean useSingleCert) {
        this.useSingleCert = useSingleCert;
        saveConfig();
    }

    public void setParts(List<StringToStringMap> parts) {
        this.parts = parts;
        saveConfig();
    }

    private final class InternalWssContainerListener extends WssContainerListenerAdapter {
        @Override
        public void cryptoUpdated(WssCrypto crypto) {
            if (crypto.getLabel().equals(getCrypto())) {
                keyAliasComboBoxModel.update(crypto);
            }
        }
    }

    /**
     * This callback class extends the default DOMCallbackLookup class with a hook to return the prepared
     * wsse:BinarySecurityToken
     */
    private static class BinarySecurityTokenDOMCallbackLookup extends DOMCallbackLookup {

        private final WSSecSignature wssSign;

        public BinarySecurityTokenDOMCallbackLookup(Document doc, WSSecSignature wssSign) {
            super(doc);
            this.wssSign = wssSign;
        }

        @Override
        public List<Element> getElements(String localname, String namespace) throws WSSecurityException {
            List<Element> elements = super.getElements(localname, namespace);
            if (elements.isEmpty()) {
                // element was not found in DOM document
                if (WSConstants.BINARY_TOKEN_LN.equals(localname) && WSConstants.WSSE_NS.equals(namespace)) {
                    /* In case the element searched for is the wsse:BinarySecurityToken, return the element prepared by
                       wsee4j. If we return the original DOM element, the digest calculation fails because the element
                       is not yet attached to the DOM tree, so instead return a copy which includes all namespaces */
                    try {
                        DOMResult result = new DOMResult();
                        Transformer transformer = TransformerFactory.newInstance().newTransformer();
                        transformer.transform(new DOMSource(wssSign.getBinarySecurityTokenElement()), result);
                        return Collections.singletonList(((Document) result.getNode()).getDocumentElement());
                    } catch (TransformerException e) {
                        SoapUI.logError(e);
                    }
                }
            }
            return elements;
        }
    }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.support.wss.entries.SignatureEntry$BinarySecurityTokenDOMCallbackLookup

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.