Package axiom.saml.idp

Source Code of axiom.saml.idp.XmlObjectSigner

package axiom.saml.idp;

import org.apache.log4j.Logger;
import org.opensaml.Configuration;
import org.opensaml.xml.io.*;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.credential.BasicCredential;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory;
import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorManager;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.opensaml.xml.signature.*;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.SignatureException;
import org.opensaml.xml.signature.Signer;

import java.io.*;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
import java.security.cert.X509Certificate;

/**
* Signs XML Objects using config set in constructor. Also offers convenince method
* for getting public certificate file.
*
* @author rbrainard
*/
public class XmlObjectSigner {
    private static Logger logger = Logger.getLogger(XmlObjectSigner.class);

    private Credential credential;
    private X509Certificate x509cert;

    private String canonicalizationAlgorithm;
    private boolean includeKeyInfoInSignature;

    /**
     * Constructor for XmlObjectSigner should only be called by IdpConfiguration
     * or subclasses
     *
     * @param keystoreFile
     * @param keystorePassword
     * @param keystoreAlias
     * @param keystoreAliasPassword
     * @param credentialType
     */
    protected XmlObjectSigner(URL keystoreFile, char[] keystorePassword, String keystoreAlias, char[] keystoreAliasPassword, CredentialType credentialType) {
        logger.debug("Initializing keystore");
        InputStream keystoreStream = null;
        try {
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystoreStream = keystoreFile.openStream();
            keystore.load(keystoreStream, keystorePassword);

            logger.debug("Loading X509 certificate from keystore");
            x509cert = (X509Certificate) keystore.getCertificate(keystoreAlias);

            logger.debug("Loading credential data from keystore");

            switch (credentialType) {
                case BASIC_CREDENTIAL:
                    BasicCredential basicCredential = new BasicCredential();
                    basicCredential.setPrivateKey((PrivateKey) keystore.getKey(keystoreAlias, keystoreAliasPassword));
                    basicCredential.setPublicKey(keystore.getCertificate(keystoreAlias).getPublicKey());

                    credential = basicCredential;
                    break;

                case X509_CREDENTIAL:
                    BasicX509Credential basicX509Credential = new BasicX509Credential();
                    basicX509Credential.setEntityCertificate(x509cert);
                    basicX509Credential.setPrivateKey((PrivateKey) keystore.getKey(keystoreAlias, keystoreAliasPassword));
                    basicX509Credential.setPublicKey(keystore.getCertificate(keystoreAlias).getPublicKey());

                    credential = basicX509Credential;
                    break;

                default:
                    throw new IllegalStateException("Invalid credentialType");
            }

        } catch (UnrecoverableKeyException e) {
            throw new RuntimeException(e);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (CertificateException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NullPointerException e) {
            throw new RuntimeException("Could not load keystore. Check alias names.", e);
        } finally {
            try {
                logger.debug("Closing keystore");
                if (keystoreStream != null) keystoreStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public SignableXMLObject sign(SignableXMLObject signableXmlObject) {
        logger.debug("Building unsigned Signature");
        Signature signature = (Signature) Configuration.getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME).buildObject(Signature.DEFAULT_ELEMENT_NAME);
        signature.setSigningCredential(credential);
        signature.setCanonicalizationAlgorithm(canonicalizationAlgorithm);

        if (includeKeyInfoInSignature) {
            logger.debug("Building KeyInfo");
            KeyInfoGeneratorManager keyInfoGeneratorManager = Configuration.getGlobalSecurityConfiguration().getKeyInfoGeneratorManager().getDefaultManager();
            KeyInfoGeneratorFactory keyInfoGeneratorFactory = keyInfoGeneratorManager.getFactory(credential);
            KeyInfo keyInfo = null;
            try {
                keyInfo = keyInfoGeneratorFactory.newInstance().generate(credential);
            } catch (SecurityException e) {
                throw new RuntimeException(e);
            }
            signature.setKeyInfo(keyInfo);
        }

        logger.debug("Trying to match signature Algorithm to public key algorithm: " + credential.getPublicKey().getAlgorithm());
        if (credential.getPublicKey().getAlgorithm().equalsIgnoreCase("DSA")) {
            signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_DSA);
        } else if (credential.getPublicKey().getAlgorithm().equalsIgnoreCase("RSA")) {
            signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA);
        } else {
            throw new RuntimeException(new SignatureException("Unknown public key algorithm. Signature algorithm not set."));
        }
        //TODO: add more algos

        signableXmlObject.setSignature(signature);

        logger.debug("Marshalling signableXmlObject");
        MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory();
        Marshaller marshaller = marshallerFactory.getMarshaller(signableXmlObject);
        try {
            marshaller.marshall(signableXmlObject);
        } catch (MarshallingException e) {
            throw new RuntimeException(e);
        }

        logger.debug("Signing signableXmlObject");
        try {
            Signer.signObject(signature);
        } catch (SignatureException e) {
            throw new RuntimeException(e);
        }

        logger.debug("Returning signed signableXmlObject");
        return signableXmlObject;
    }

    public Credential getCredential() {
        return credential;
    }

    public File getCertFile() throws CertificateEncodingException, IOException {
        byte[] certBytes = null;
        File certFile = null;

        logger.debug("Exporting certificate");
        certBytes = x509cert.getEncoded();

        FileOutputStream fos = null;
        try {
            certFile = File.createTempFile("samlIdpCert-", ".cer");
            fos = new FileOutputStream(certFile);
            fos.write(certBytes);
            logger.info("Certificate written to " + certFile.getCanonicalPath());
        } finally {
            if (fos != null) fos.close();
        }

        return certFile;
    }

    public String getCanonicalizationAlgorithm() {
        return canonicalizationAlgorithm;
    }

    public void setCanonicalizationAlgorithm(String canonicalizationAlgorithm) {
        this.canonicalizationAlgorithm = canonicalizationAlgorithm;
    }

    public boolean isIncludeKeyInfoInSignature() {
        return includeKeyInfoInSignature;
    }

    public void setIncludeKeyInfoInSignature(boolean includeKeyInfoInSignature) {
        this.includeKeyInfoInSignature = includeKeyInfoInSignature;
    }

}
TOP

Related Classes of axiom.saml.idp.XmlObjectSigner

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.