Package org.apache.wookie.digsig.client.model

Source Code of org.apache.wookie.digsig.client.model.SignWidgets

/*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.wookie.digsig.client.model;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.signature.*;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.XMLUtils;
import org.apache.xml.security.utils.resolver.ResourceResolver;
import org.w3c.dom.Element;

import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Random;

/** @author Pushpalanka */

/**
* Perform signing over a widget according to the recommendations specified
* in W3C widgets digsig specification
*/
public class SignWidgets {

    private String keyStoreType = "JKS";
    private String keyStoreFile = "";
    private String keyStorePass = "";
    private String privateKeyAlias = "";
    private String privateKeyPass = "";
    private String certificateAlias = "";
    private String pathToWidget = "";
    private String documentsList = "";
    private String role = "AuthorSignature";
    private String target = "";
    private String roleURI = "";
    private String name = "";
    private String[] documents;
    private String signatureFileName = "";

    public void setKeyStoreFile(String keyStoreFile) {
        this.keyStoreFile = keyStoreFile;
    }

    public void setKeyStorePass(String keyStorePass) {
        this.keyStorePass = keyStorePass;
    }

    public void setPrivateKeyAlias(String privateKeyAlias) {
        this.privateKeyAlias = privateKeyAlias;
    }

    public void setPrivateKeyPass(String privateKeyPass) {
        this.privateKeyPass = privateKeyPass;
    }

    public void setCertificateAlias(String certificateAlias) {
        this.certificateAlias = certificateAlias;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public void setDocumentsList(String documentsList) {
        this.documentsList = documentsList;
    }

    public void setPathToWidget(String pathToWidget) {
        this.pathToWidget = pathToWidget;
    }

    public void setName(String name) {
        this.name = name;
    }

    static {
        org.apache.xml.security.Init.init();
    }

    /** Generate signature for the widget content under W3C widgets digsig specification */
    public void sign() throws KeyStoreException, IOException,
        NoSuchAlgorithmException, CertificateException,
        UnrecoverableKeyException, XMLSecurityException,
        ParserConfigurationException {

        //set signature file names according to the role as specified in W3C widgets digsig spec
        if(role.equals("AuthorSignature")){
            signatureFileName = "/author-signature.xml";
        }
        else{
            Random randomGenerator = new Random();
            Integer number = randomGenerator.nextInt(20);
            signatureFileName = "/signature" + number + ".xml";
        }

        File signatureFile = new File(pathToWidget + signatureFileName);

        //get the private key from keystore
        KeyStore ks = KeyStore.getInstance(keyStoreType);
        FileInputStream fis = new FileInputStream(keyStoreFile);
                try{
        ks.load(fis, keyStorePass.toCharArray());
        PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias,
            privateKeyPass.toCharArray());

        javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory
            .newInstance();
        dbf.setNamespaceAware(true);
        javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
        org.w3c.dom.Document doc = db.newDocument();

        //BaseURI provides the base for the path to referenced content from the signature
        String BaseURI = signatureFile.toURI().toURL().toString();
        XMLSignature sig = new XMLSignature(doc, BaseURI,
            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256,
            Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);

        sig.setId(role);

        doc.appendChild(sig.getElement());
        {

            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
            addDocuments(sig, documentsList);

            customizeToRole(role);

            //Adding signature properties
            SignatureProperty profile = new SignatureProperty(doc, target,
                SignerConstants.SIGNATURE_PROPERTY_ID_PROFILE);
            Element profileElement = doc
                .createElement(SignerConstants.SIGNATURE_PROPERTY_ID_PROFILE_TAG_NAME);
            profileElement.setAttribute("URI", SignerConstants.PROFILE_URI);
            profile.appendChild(profileElement);

            SignatureProperty role = new SignatureProperty(doc, target,
                SignerConstants.SIGNATURE_PROPERTY_ID_ROLE);
            Element roleElement = doc
                .createElement(SignerConstants.SIGNATURE_PROPERTY_ID_ROLE_TAG_NAME);
            roleElement.setAttribute("URI", roleURI);
            role.appendChild(roleElement);

            SignatureProperty identifier = new SignatureProperty(doc, target,
                SignerConstants.SIGNATURE_PROPERTY_ID_IDENTIFIER);
            Element identifierElement = doc
                .createElement(SignerConstants.SIGNATURE_PROPERTY_ID_IDENTIFIER_TAG_NAME);
            identifierElement.setTextContent(name);
            identifier.appendChild(identifierElement);

            SignatureProperties props = new SignatureProperties(doc);

            props.setXPathNamespaceContext(SignerConstants.XMLNS_DSP,
                SignerConstants.SIGNATURE_PROPERTIES_NAMESPACE);
            props.addSignatureProperty(profile);
            props.addSignatureProperty(role);
            props.addSignatureProperty(identifier);
            ObjectContainer object = new ObjectContainer(doc);
            object.setId("prop");

            object.appendChild(doc.createTextNode("\n"));
            object.appendChild(props.getElement());
            object.appendChild(doc.createTextNode("\n"));

            //Refer the properties section of the signature which needs
            //to be signed too, that include role information.
            sig.appendObject(object);
            sig.addDocument("#prop", transforms,
                SignerConstants.DIGEST_METHOD_ALGORITHM);

            ResourceResolver offlineResolver = null;
            sig.addResourceResolver(offlineResolver);

            {
                X509Certificate cert = (X509Certificate) ks
                    .getCertificate(certificateAlias);

                                sig.addKeyInfo(cert);
                sig.addKeyInfo(cert.getPublicKey());

                System.out.println("Start signing");
                sig.sign(privateKey);
                System.out.println("Finished signing");
            }

            FileOutputStream f = new FileOutputStream(signatureFile);

            try{
                            XMLUtils.outputDOM(doc, f);
                        }
            finally{
                            f.close();
                        }
            System.out.println("Wrote signature to " + BaseURI);
        }
                }
                finally{
                    fis.close();
                }

    }

    /**
     * To add the content of the widget as reference in the signature
     *
     * @param sig : generating signature
     * @param documentsList: list of files inside widget folder. All the content of .wgt needs to be signed.
     */
    private void addDocuments(XMLSignature sig, String documentsList) {
        documents = documentsList.split("\n");
        for(int i = 0; i < documents.length; i++){
            try {
                sig.addDocument(documents[i], null,
                    SignerConstants.DIGEST_METHOD_ALGORITHM);
            }
            catch(XMLSignatureException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Set parameters of the signature according to the role of the signer
     *
     * @param role: whether signing person is author or distributor
     */
    private void customizeToRole(String role) {
        if(role.equals("AuthorSignature")){
            target = SignerConstants.SIGN_TARGET_AUTHOR;
            roleURI = SignerConstants.ROLE_URI_AUTHOR;
        }
        else if(role.equals("DistributorSignature")){
            target = SignerConstants.SIGN_TARGET_DISTRIBUTOR;
            roleURI = SignerConstants.ROLE_URI_DISTRIBUTOR;
        }
        else{

        }
    }

    /** Pack the content into a .wgt package */
    public void repackZip() throws IOException {
        File sourceOfFiles = new File(pathToWidget);
        ZipArchiveOutputStream out = new ZipArchiveOutputStream(new File(
            sourceOfFiles.getAbsolutePath() + File.separator + name + ".wgt"));
                try{
                    out.setEncoding("UTF-8");
            for(File aFile : sourceOfFiles.listFiles()){
            if(!aFile.getName().endsWith(".wgt")){
                pack(aFile, out, "");
            }
        }
                }
                finally{
            out.flush();
            out.close();
                }
    }

    /**
     * Recursively locates and adds files and folders to a zip archive
     *
     * @param file: directory that includes widget content
     * @param out: ZipArchiveOutputStream
     * @param path:location of content inside .wgt, relatively
     */
    private static void pack(File file, ZipArchiveOutputStream out, String path)
        throws IOException {

        // To avoid include of hidden files and folders checking has done on name to
        // start with ".".
        if(file.isDirectory() && !(file.getName().startsWith("."))){
            path = path + file.getName() + "/";
            for(File aFile : file.listFiles()){
                pack(aFile, out, path);
            }
        }
        else{

            String name = file.getName();
            if(!name.startsWith(".")){
                ZipArchiveEntry entry = (ZipArchiveEntry) out.createArchiveEntry(file,
                    path + name);
                out.putArchiveEntry(entry);
                byte[] buf = new byte[1024];
                int len;
                FileInputStream in = new FileInputStream(file);
                                try{
                    while((len = in.read(buf)) > 0){
                    out.write(buf, 0, len);
                }
                                }finally{
                                      in.close();
                                }
                out.closeArchiveEntry();
                                out.close();

            }
        }
    }
}
TOP

Related Classes of org.apache.wookie.digsig.client.model.SignWidgets

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.