Package org.ejbca.extra.db

Source Code of org.ejbca.extra.db.ExtRAMsgHelper

/*************************************************************************
*                                                                       *
*  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.ByteArrayOutputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSSignedGenerator;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;

/**
* Class containing static help methods used to encrypt, decrypt, sign  and verify ExtRASubMessages
*
* @author philip
* $Id: ExtRAMsgHelper.java 9330 2010-06-30 18:16:53Z anatom $
*/
public class ExtRAMsgHelper {
 
  private static final Log log = LogFactory.getLog(ExtRAMsgHelper.class);

  private static String provider = "BC"; // default provider
  private static String encAlg = CMSEnvelopedDataGenerator.AES256_CBC; // default encryption algorithm
  private static String signAlg = CMSSignedGenerator.DIGEST_SHA256; // default signature digest
 
  /**
   * Method to initalize the helper class. Should be called before any of the methods are used
   * in not hte default values should be used.
   *
   * @param provider provider to use "BC" is default.
   * @param encAlg encryption algorithm to use, must be supproted by the specified provider.
   * @prarm signAlg signature algorighm to use, must be supproted by the specified provider.
   */
  public static void init(String provider, String encAlg, String signAlg){
    ExtRAMsgHelper.provider = provider;   
    ExtRAMsgHelper.encAlg = encAlg;
    ExtRAMsgHelper.signAlg = signAlg;
  }
 
  /**
   * Method that should be used to encrypt data in a message.
   *
   * Uses the algorithm specified in the init method.
   *
   * @param encCert, the recepient to encrypt to.
   * @param data
   * @return encrypted byte[]
   * @throws IOException
   */
  public static byte[] encryptData(X509Certificate encCert, byte[] data) throws IOException{

        CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();                             
      
      CMSEnvelopedData ed;
    try {
      edGen.addKeyTransRecipient(encCert);
      ed = edGen.generate(
          new CMSProcessableByteArray(data),encAlg,provider);
    } catch (Exception e) {
            log.error("Error Encryotin Keys:: ", e);
            throw new IOException(e.getMessage());       
    }
       
   
    return ed.getEncoded();    
  }

  /**
   * Method that should be used to decrypt data in a message.
   *
   * Uses the algorithm specified in the init method.
   *
   * @param decKey, the recipients private key.
   * @param encData, the encrypted data
   * @return encrypted byte[] or null if decryption failed.
   */
  public static byte[] decryptData(PrivateKey decKey, byte[] encData) {
    byte[] retdata = null;
    try{
      CMSEnvelopedData ed = new CMSEnvelopedData(encData);          
     
      RecipientInformationStore  recipients = ed.getRecipientInfos();            
      Iterator    it =  recipients.getRecipients().iterator();
      RecipientInformation   recipient = (RecipientInformation) it.next();     
      retdata = recipient.getContent(decKey, provider);
    } catch(Exception e){
      log.error("Error decypting data : ", e);
    }
                 
      return retdata; 
 

  /**
   * Method that signes the given data using the algorithm specified in the init method.
   *
   * @param signKey, the key used to sign the data
   * @param signCert the certificate
   * @param data
   * @return the signed data or null if signature failed
   */
  public static byte[] signData(PrivateKey signKey, X509Certificate signCert, byte[] data){
    byte[] retdata = null;
    try{
          ArrayList certList = new ArrayList();
          certList.add(signCert);
          CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), provider);         
      CMSSignedDataGenerator    gen = new CMSSignedDataGenerator();
      gen.addCertificatesAndCRLs(certs);
      gen.addSigner(signKey, signCert, signAlg);       
      CMSSignedData           signedData = gen.generate(new CMSProcessableByteArray(data), true, provider);
      retdata = signedData.getEncoded();
    } catch(Exception e){
      log.error("Error signing data : ", e);
    }
    return retdata;
 

  /**
   * Method used to verify signed data.
   *
   * @param TrustedCACerts a Collection of trusted certifcates, should contain the entire chains
   * @param TrustedCRLs a Collection of trusted CRLS, use null if no CRL check should be used.
   * @param signedData the data to verify
   * @return true if signature verifes
   */
  public static ParsedSignatureResult verifySignature(Collection cACertChain, Collection trustedCRLs, byte[] signedData){
    return verifySignature(cACertChain, trustedCRLs, signedData, new Date());
  }
 
  /**
   * Method used to verify signed data.
   *
   * @param TrustedCACerts a Collection of trusted certificates, should contain the entire chains
   * @param TrustedCRLs a Collection of trusted CRLS, use null if no CRL check should be used.
   * @param signedData the data to verify
   * @param date the date used to check the validity against.
   * @return a ParsedSignatureResult.
   */
  public static ParsedSignatureResult verifySignature(Collection cACertChain, Collection trustedCRLs, byte[] signedData, Date date){
    boolean verifies = false;       
        X509Certificate usercert = null;
        ParsedSignatureResult retval = new ParsedSignatureResult(false,null,null);
    byte[] content = null;
       
       
        try{
          // First verify the signature
          CMSSignedData     sp = new CMSSignedData(signedData);                                 
         
          CertStore               certs = sp.getCertificatesAndCRLs("Collection", "BC");
          SignerInformationStore  signers = sp.getSignerInfos();
         
          ByteArrayOutputStream baos = new ByteArrayOutputStream();         
          ((CMSProcessableByteArray) sp.getSignedContent()).write(baos);
          content = baos.toByteArray();
          baos.close();
         
          Collection              c = signers.getSigners();
          Iterator                it = c.iterator();
         
          while (it.hasNext())
          {
            SignerInformation   signer = (SignerInformation)it.next();
            Collection          certCollection = certs.getCertificates(signer.getSID());
           
            Iterator        certIt = certCollection.iterator();
            usercert = (X509Certificate)certIt.next();  
           
            boolean validalg = signer.getDigestAlgOID().equals(signAlg);
           
           
            verifies = validalg && signer.verify(usercert.getPublicKey(), "BC");
           
          }
         
          // Second validate the certificate          
          X509Certificate rootCert = null;
          Iterator iter = cACertChain.iterator();
          while(iter.hasNext()){
            X509Certificate cert = (X509Certificate) iter.next();
            if(cert.getIssuerDN().equals(cert.getSubjectDN())){
              rootCert = cert;
              break;
            }
          }
         
          if(rootCert == null){
            throw new CertPathValidatorException("Error Root CA cert not found in cACertChain");
          }
         
          List list = new ArrayList();
          list.add(usercert);
          list.add(cACertChain);
          if(trustedCRLs != null){
            list.add(trustedCRLs);
          }
         
          CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(list);
          CertStore store = CertStore.getInstance("Collection", ccsp);
         
          //validating path
          List certchain = new ArrayList();
          certchain.addAll(cACertChain);
          certchain.add(usercert);
          CertPath cp = CertificateFactory.getInstance("X.509","BC").generateCertPath(certchain);
         
          Set trust = new HashSet();
          trust.add(new TrustAnchor(rootCert, null));
         
          CertPathValidator cpv = CertPathValidator.getInstance("PKIX","BC");
          PKIXParameters param = new PKIXParameters(trust);
          param.addCertStore(store);
          param.setDate(date);
          if(trustedCRLs == null){
            param.setRevocationEnabled(false);
          }else{
            param.setRevocationEnabled(true);
          }
          cpv.validate(cp, param);
          retval = new ParsedSignatureResult(verifies, usercert,content);
        }catch(Exception e){
      log.error("Error verifying data : ", e);
    }

   
    return retval;
  }
 
}
TOP

Related Classes of org.ejbca.extra.db.ExtRAMsgHelper

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.