org.ejbca.extra.db.SubMessages.java Source code

Java tutorial

Introduction

Here is the source code for org.ejbca.extra.db.SubMessages.java

Source

/*************************************************************************
 *                                                                       *
 *  EJBCA: The OpenSource Certificate Authority                          *
 *                                                                       *
 *  This software is free software; you can redistribute it and/or       *
 *  modify it under the terms of the GNU Lesser General Public           *
 *  License as published by the Free Software Foundation; either         *
 *  version 2.1 of the License, or any later version.                    *
 *                                                                       *
 *  See terms of license at gnu.org.                                     *
 *                                                                       *
 *************************************************************************/
package org.ejbca.extra.db;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.util.encoders.Base64;

/**
 * Class used 
 * 
 * @author Philip Vendil
 * @version $Id: SubMessages.java 11268 2011-01-26 23:02:58Z jeklund $
 */
public class SubMessages {

    private static final Log log = LogFactory.getLog(SubMessages.class);

    private ArrayList<ISubMessage> submessages = new ArrayList<ISubMessage>();

    private boolean isSigned = false;

    private boolean isEncrypted = false;

    private transient X509Certificate userCert = null;
    private transient PrivateKey userKey = null;
    private transient X509Certificate encCert = null;

    private X509Certificate signerCert;

    /**
     * Constructor to use when creating a SubMessages.
     * 
     * @param userCert certificate used for signing the request and used for encryption by 
     * the responding service. Set this to null if no request signing should be performed.
     * @param userKey Key to use as signing, set to null if no signing should be performed.
     * @param encCert certificate that should be used to encrypt the messages. 
     * Set this to null if no encryption should be done.
     */
    public SubMessages(X509Certificate userCert, PrivateKey userKey, X509Certificate encCert) {

        if (userCert != null && userKey != null) {
            this.isSigned = true;
            this.userCert = userCert;
            this.userKey = userKey;
        }

        if (encCert != null) {
            this.isEncrypted = true;
            this.encCert = encCert;
        }

    }

    /**
     * Constructor to use when loading a SubMessage from persisted state
     */
    public SubMessages() {
    }

    /**
     * Method use by db api to load a persisted submessage
     * @param cACertChain is the CA chain that signed the RA and CAService keystore
     * @param crls could be set to null to disable CRL checking
     */
    void load(String data, PrivateKey userKey, Collection cACertChain, Collection crls) {
        try {
            submessages.clear();
            java.beans.XMLDecoder decoder = new java.beans.XMLDecoder(
                    new java.io.ByteArrayInputStream(data.getBytes("UTF8")));
            isSigned = ((Boolean) decoder.readObject()).booleanValue();
            isEncrypted = ((Boolean) decoder.readObject()).booleanValue();
            byte[] messagedata = Base64.decode(((String) decoder.readObject()).getBytes());
            decoder.close();

            if (isEncrypted) {
                messagedata = ExtRAMsgHelper.decryptData(userKey, messagedata);
            }

            if (isSigned) {
                ParsedSignatureResult result = ExtRAMsgHelper.verifySignature(cACertChain, crls, messagedata);
                if (!result.isValid()) {
                    throw new SignatureException("Signature not valid");
                }
                this.signerCert = result.getSignerCert();
                messagedata = result.getContent();
            }

            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(messagedata));
            ArrayList<HashMap> savearray = (ArrayList<HashMap>) ois.readObject();

            Iterator<HashMap> iter = savearray.iterator();
            while (iter.hasNext()) {
                HashMap map = iter.next();
                ISubMessage submessage = SubMessageFactory.createInstance(map);
                submessage.loadData(map);
                submessages.add(submessage);
            }
            ois.close();
        } catch (Exception e) {
            log.error("Error reading persistent SubMessages.", e);
        }
    }

    /**
     * Method used to persist the set of submessages
     * @return a String representation of the data
     */
    String save() {
        String retval = null;

        ArrayList savearray = new ArrayList();

        Iterator<ISubMessage> iter = submessages.iterator();
        while (iter.hasNext()) {
            ISubMessage next = iter.next();
            savearray.add(next.saveData());
        }

        try {
            java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(savearray);
            byte[] messagedata = baos.toByteArray();

            if (isSigned) {
                messagedata = ExtRAMsgHelper.signData(userKey, userCert, messagedata);
            }

            if (isEncrypted) {
                messagedata = ExtRAMsgHelper.encryptData(encCert, messagedata);
            }

            java.io.ByteArrayOutputStream baos2 = new java.io.ByteArrayOutputStream();

            java.beans.XMLEncoder encoder = new java.beans.XMLEncoder(baos2);
            encoder.writeObject(Boolean.valueOf(isSigned));
            encoder.writeObject(Boolean.valueOf(isEncrypted));
            encoder.writeObject(new String(Base64.encode(messagedata)));
            encoder.close();
            retval = baos2.toString("UTF8");
        } catch (Exception e) {
            log.error("Error writing persistent SubMessages.", e);
        }

        return retval;
    }

    /**
     * Method to add a submessage to the message sent between RA and CA.
     */
    public void addSubMessage(ISubMessage submessage) {
        submessages.add(submessage);
    }

    /**
     * Method to retreive a collection of submessages.
     */
    public ArrayList<ISubMessage> getSubMessages() {
        return submessages;
    }

    /**
     * Returns true if this message is signed
     */
    public boolean isSigned() {
        return isSigned;
    }

    /**
     * Returns true if this message is encrypted
     */
    public boolean isEncrypted() {
        return isEncrypted;
    }

    /**
     * Returns the certificate of the signer, or null if message isn't signed
     *
     */
    public X509Certificate getSignerCert() {
        return signerCert;
    }
}