Java tutorial
/************************************************************************* * * * 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; } }