Package org.ejbca.core.protocol.cmp

Source Code of org.ejbca.core.protocol.cmp.CmpPbeVerifyer

/*************************************************************************
*                                                                       *
*  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.core.protocol.cmp;

import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.log4j.Logger;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.ejbca.core.model.InternalResources;

import com.novosec.pkix.asn1.cmp.CMPObjectIdentifiers;
import com.novosec.pkix.asn1.cmp.PKIHeader;
import com.novosec.pkix.asn1.cmp.PKIMessage;
import com.novosec.pkix.asn1.crmf.PBMParameter;

/**
* Helper class to verify PBE of CMP messages, also extracts owf, mac Oids and iteration count.
* @author tomas
* @version $Id: CmpPbeVerifyer.java 10435 2010-11-11 20:08:29Z jeklund $
*/
public class CmpPbeVerifyer {
  private static final Logger LOG = Logger.getLogger(CmpPbeVerifyer.class);
    /** Internal localization of logs and errors */
    private static final InternalResources INTRES = InternalResources.getInstance();

    private byte[] protectedBytes = null;
    private DERBitString protection = null;
  private AlgorithmIdentifier pAlg = null;
  private String errMsg = null;
  private String owfOid = null;
  private String macOid = null;
  private int iterationCount = 1024;
  private byte[] salt = null;
  private String lastUsedRaSecret = null;
 
  public CmpPbeVerifyer(PKIMessage msg) {
    PKIHeader head = msg.getHeader();
    protectedBytes = msg.getProtectedBytes();
    protection = msg.getProtection();
    pAlg = head.getProtectionAlg();
    LOG.debug("Protection type is: "+pAlg.getObjectId().getId());
    PBMParameter pp = PBMParameter.getInstance(pAlg.getParameters());
    iterationCount = pp.getIterationCount().getPositiveValue().intValue();
    LOG.debug("Iteration count is: "+iterationCount);
    AlgorithmIdentifier owfAlg = pp.getOwf();
    // Normal OWF alg is 1.3.14.3.2.26 - SHA1
    owfOid = owfAlg.getObjectId().getId();
    LOG.debug("Owf type is: "+owfOid);
    AlgorithmIdentifier macAlg = pp.getMac();
    // Normal mac alg is 1.3.6.1.5.5.8.1.2 - HMAC/SHA1
    macOid = macAlg.getObjectId().getId();
    LOG.debug("Mac type is: "+macOid);
    salt = pp.getSalt().getOctets();
    //log.info("Salt: "+new String(salt));
  }
 
  public boolean verify(String raAuthenticationSecret) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
    lastUsedRaSecret = raAuthenticationSecret;
    boolean ret = false;
    // Verify the PasswordBased protection of the message
    if (!pAlg.getObjectId().equals(CMPObjectIdentifiers.passwordBasedMac)) {
      errMsg = INTRES.getLocalizedMessage("cmp.errorunknownprotalg", pAlg.getObjectId().getId());
      LOG.error(errMsg);
      return ret;
    } else {
      if (iterationCount > 10000) {
        LOG.info("Received message with too many iterations in PBE protection: "+iterationCount);
        throw new InvalidKeyException("Iteration count can not exceed 10000");
      }     
      byte[] raSecret = raAuthenticationSecret.getBytes();
      byte[] basekey = new byte[raSecret.length + salt.length];
      for (int i = 0; i < raSecret.length; i++) {
        basekey[i] = raSecret[i];
      }
      for (int i = 0; i < salt.length; i++) {
        basekey[raSecret.length+i] = salt[i];
      }
      // Construct the base key according to rfc4210, section 5.1.3.1
      MessageDigest dig = MessageDigest.getInstance(owfOid, "BC");
      for (int i = 0; i < iterationCount; i++) {
        basekey = dig.digest(basekey);
        dig.reset();
      }
      // HMAC/SHA1 is normal 1.3.6.1.5.5.8.1.2 or 1.2.840.113549.2.7
      Mac mac = Mac.getInstance(macOid, "BC");
      SecretKey key = new SecretKeySpec(basekey, macOid);
      mac.init(key);
      mac.reset();
      mac.update(protectedBytes, 0, protectedBytes.length);
      byte[] out = mac.doFinal();
      // My out should now be the same as the protection bits
      byte[] pb = protection.getBytes();
      ret = Arrays.equals(out, pb);
    }
    return ret;
  }

  public String getErrMsg() {
    return errMsg;
  }

  public String getMacOid() {
    return macOid;
  }

  public String getOwfOid() {
    return owfOid;
  }

  public int getIterationCount() {
    return iterationCount;
  }
 
  public String getLastUsedRaSecret() {
    return lastUsedRaSecret;
  }
 
}
TOP

Related Classes of org.ejbca.core.protocol.cmp.CmpPbeVerifyer

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.