/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package utils; import hsm.HSMManager; import hsm.HSMManagerImp; import hsm.HSMUtils; import hsmexampleconsole.HSMExampleConsole; import iaik.pkcs.pkcs11.objects.ECDSAPrivateKey; import iaik.pkcs.pkcs11.objects.ECDSAPublicKey; import iaik.pkcs.pkcs11.objects.KeyPair; import iaik.pkcs.pkcs11.wrapper.PKCS11Constants; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.interfaces.ECPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.List; import javax.xml.bind.DatatypeConverter; import objects.Keys; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequenceGenerator; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.ejbca.cvc.AlgorithmUtil; import org.ejbca.cvc.CAReferenceField; import org.ejbca.cvc.CVCPublicKey; import org.ejbca.cvc.CVCertificate; import org.ejbca.cvc.CVCertificateBody; import org.ejbca.cvc.HolderReferenceField; import org.ejbca.cvc.OIDField; import org.ejbca.cvc.PublicKeyEC; import org.ejbca.cvc.util.BCECUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author TuoiCM */ public class ExampleHSM { // private static final Logger logger = LoggerFactory.getLogger(HSMExampleConsole.class); private static HSMManager hsmManager; // // public static void init() { if (hsmManager == null) { try { hsmManager = HSMManagerImp.getInstance( Configuration.getInstance().getHsmModule(), HSMUtils.loadP11Wrapper(), Configuration.getInstance().getHsmSlot(), new String(DatatypeConverter.parseBase64Binary(Configuration.getInstance().getHsmPin()))); logger.info("SUCCESSFULLY CONNECT TO HSM"); } catch (Exception e) { logger.error("ERROR WHILE CONNECTING TO HSM. DETAILS: " + Utils.printStackTrace(e)); } } } // // public static HSMManager getHsmManager() { return hsmManager; } // // public static void destroy() { if (hsmManager != null) { hsmManager.disconnectHSM(); } } // // public static Keys[] getKeys() { try { if (null == hsmManager) { logger.error("HSM MANAGER IS NULL"); return null; } List ecdsaPrivateKey = hsmManager.listECKeys(); Keys[] keys = new Keys[ecdsaPrivateKey.size()]; for (int i = 0; i < ecdsaPrivateKey.size(); i++) { byte[] keyIdBytes = ecdsaPrivateKey.get(i).getId().getByteArrayValue(); char[] keyLabelChars = ecdsaPrivateKey.get(i).getLabel().getCharArrayValue(); String keyId = null; String keyLabel = null; if (keyIdBytes != null) { keyId = new String(keyIdBytes); } if (keyLabelChars != null) { keyLabel = new String(keyLabelChars); } Keys k = new Keys(keyId, keyLabel); keys[i] = k; } return keys; } catch (Exception e) { logger.error("GET LIST KEY HSM FAIL " + Utils.printStackTrace(e)); return null; } } // // public static Keys[] generateKeyPari(String curveName, String keyId, String keyLable) { try { if (null == hsmManager) { logger.error("HSM MANAGER IS NULL"); return null; } String curveOID = null; if (Utils.isNullOrEmpty(curveName)) { curveOID = CurveName.DEFAULT_CURVE_OID; } else { curveOID = CurveName.getOID(curveName); if (Utils.isNullOrEmpty(curveOID)) { logger.warn("INVALID CURVE NAME"); return null; } } String generatedKeyIDAndLabel = Utils.generateUUID(); if (Utils.isNullOrEmpty(keyId)) { keyId = generatedKeyIDAndLabel; } else { if (hsmManager.idExists(keyId)) { logger.error("KEY ID EXISTED"); return null; } } if (Utils.isNullOrEmpty(keyLable)) { keyLable = generatedKeyIDAndLabel; } else { if (hsmManager.labelExists(keyLable)) { logger.error("KEY LABEL EXISTED"); return null; } } ASN1ObjectIdentifier curveId = new ASN1ObjectIdentifier(curveOID); KeyPair keypair = hsmManager.genECDSAKeyPair(keyId, keyLable, curveId); if (null == keypair) { return null; } Keys[] keys = new Keys[1]; Keys key = new Keys(keyId, keyLable); keys[0] = key; return keys; } catch (Exception ex) { logger.error("GENERATE KEY PAIR FAIL " + Utils.printStackTrace(ex)); return null; } } // // public static String cvcRequest(String country, String mnemonic, String sequence, String signatureAlg, String keyId, String keyLabel) { try { if (null == hsmManager) { logger.error("HSM MANAGER IS NULl"); return null; } Security.addProvider(new BouncyCastleProvider()); if (Utils.isNullOrEmpty(keyId) && Utils.isNullOrEmpty(keyLabel)) { logger.error("KEY ID && KEY LABEL IS NULL"); return null; } if (Utils.isNullOrEmpty(country)) { logger.error("COUNTRY IS NULL"); return null; } if (Utils.isNullOrEmpty(sequence)) { logger.error("SEQUENCE IS NULL"); return null; } if (Utils.isNullOrEmpty(signatureAlg)) { signatureAlg = SignatureAlgorithm.DEFAULT_SIG_ALGO; } else { signatureAlg = SignatureAlgorithm.getSignatureAlgorithm(signatureAlg); if (Utils.isNullOrEmpty(signatureAlg)) { signatureAlg = SignatureAlgorithm.DEFAULT_SIG_ALGO; } } boolean findByLabel = false; List ecdsaPrivateKey = null; List ecdsaPublicKey = null; if (!Utils.isNullOrEmpty(keyId)) { ecdsaPrivateKey = hsmManager.getECKeyByID(keyId); } if (Utils.isNullOrEmpty(ecdsaPrivateKey)) { if (!Utils.isNullOrEmpty(keyLabel)) { ecdsaPrivateKey = hsmManager.getECKeyByLabel(keyLabel); findByLabel = true; } } if (Utils.isNullOrEmpty(ecdsaPrivateKey)) { logger.error("NO KEY ID FOUND"); return null; } if (findByLabel) { ecdsaPublicKey = hsmManager.getPublicECKeyByLabel(keyLabel); } else { ecdsaPublicKey = hsmManager.getPublicECKeyByID(keyId); } if (Utils.isNullOrEmpty(ecdsaPublicKey)) { logger.error("NO PUBLIC KEY ID FOUND"); return null; } CAReferenceField caRef = null; HolderReferenceField holderRef = new HolderReferenceField(country, mnemonic, sequence); OIDField oid = AlgorithmUtil.getOIDField(signatureAlg); ECDSAPrivateKey signingKey = ecdsaPrivateKey.get(0); ECDSAPublicKey publicKey = ecdsaPublicKey.get(0); byte[] encodedAlgorithmIdParameters = publicKey.getEcdsaParams().getByteArrayValue(); byte[] encodedPoint = DEROctetString.getInstance( publicKey.getEcPoint().getByteArrayValue()).getOctets(); ECPublicKey ecPublicKey = createECPublicKey(encodedAlgorithmIdParameters, encodedPoint); CVCPublicKey cvcPublicKey = new PublicKeyEC(oid, ecPublicKey, null); CVCertificateBody reqBody = new CVCertificateBody(caRef, cvcPublicKey, holderRef); CVCertificate cvc = new CVCertificate(reqBody); byte[] dataToBeSigned = cvc.getTBS(); //hash the message MessageDigest md = MessageDigest.getInstance(SignatureAlgorithm.getHashAlgorithm(signatureAlg)); md.update(dataToBeSigned); byte[] hashedMessage = md.digest(); byte[] signature = hsmManager.sign(PKCS11Constants.CKM_ECDSA, hashedMessage, signingKey); if (null == signature) { logger.error("SIGNATURE IS NULL"); return null; } byte[] r = new byte[signature.length / 2]; byte[] s = new byte[signature.length / 2]; System.arraycopy(signature, 0, r, 0, signature.length / 2); System.arraycopy(signature, signature.length / 2, s, 0, signature.length / 2); BigInteger[] bigSignature = new BigInteger[2]; bigSignature[0] = new BigInteger(1, r); bigSignature[1] = new BigInteger(1, s); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DERSequenceGenerator seq = new DERSequenceGenerator(byteArrayOutputStream); seq.addObject(new ASN1Integer(bigSignature[0])); seq.addObject(new ASN1Integer(bigSignature[1])); seq.close(); byte[] finalSignature = byteArrayOutputStream.toByteArray(); // Now convert the X9.62 signature to a CVC signature byte[] sig = BCECUtil.convertX962SigToCVC(signatureAlg, finalSignature); // Create and return the CVCRequest (which is an instance of CVCertificate) cvc.setSignature(sig); String cvcRequest = DatatypeConverter.printBase64Binary(cvc.getDEREncoded()); //LOG.info("signature: " + DatatypeConverter.printHexBinary(signature)); //LOG.info("r: " + DatatypeConverter.printHexBinary(r)); //LOG.info("s: " + DatatypeConverter.printHexBinary(s)); //LOG.info("finalSignature: " + DatatypeConverter.printHexBinary(finalSignature)); //LOG.info("finalSignature: " + DatatypeConverter.printBase64Binary(finalSignature)); //LOG.info("cvcRequest: " + cvcRequest); return cvcRequest; } catch (Exception ex) { logger.error("CVC REQUEST FAIL " + Utils.printStackTrace(ex)); return null; } } // // private boolean deleteKeys(String keyId, String keyLabel) { try { if (null == hsmManager) { logger.error("HSM MANAGER IS NULL"); return false; } if (Utils.isNullOrEmpty(keyId) && Utils.isNullOrEmpty(keyLabel)) { logger.error("KEY ID && KEY LABEL IS NULL"); return false; } boolean findByLabel = false; List ecdsaPrivateKey = null; List ecdsaPublicKey = null; if (!Utils.isNullOrEmpty(keyId)) { ecdsaPrivateKey = hsmManager.getECKeyByID(keyId); } if (Utils.isNullOrEmpty(ecdsaPrivateKey)) { if (!Utils.isNullOrEmpty(keyLabel)) { ecdsaPrivateKey = hsmManager.getECKeyByLabel(keyLabel); findByLabel = true; } } if (findByLabel) { ecdsaPublicKey = hsmManager.getPublicECKeyByLabel(keyLabel); } else { ecdsaPublicKey = hsmManager.getPublicECKeyByID(keyId); } if (Utils.isNullOrEmpty(ecdsaPrivateKey) && Utils.isNullOrEmpty(ecdsaPublicKey)) { logger.error("NO KEY ID FOUND"); return false; } else { if (!Utils.isNullOrEmpty(ecdsaPrivateKey)) { for (ECDSAPrivateKey k : ecdsaPrivateKey) { hsmManager.deleteKey(k); } } if (!Utils.isNullOrEmpty(ecdsaPublicKey)) { for (ECDSAPublicKey k : ecdsaPublicKey) { hsmManager.deleteKey(k); } } return true; } } catch (Exception ex) { logger.error("DELETE KEYS FAIL " + Utils.printStackTrace(ex)); return false; } } // // public static String getTASginature(String keyId, String keyLabel, String hash, String encoding) { try { if (null == hsmManager) { logger.error("HSM MANAGER IS NULL"); return null; } if(Utils.isNullOrEmpty(keyId) && Utils.isNullOrEmpty(keyLabel)) { logger.error("KEY ID && KEY LABEL IS NULL"); return null; } if(Utils.isNullOrEmpty(hash)) { logger.error("HASH IS NULL"); return null; } byte[] dataToBeSigned = null; try { if (Utils.isNullOrEmpty(encoding)) { dataToBeSigned = DatatypeConverter.parseBase64Binary(hash); } else { if (encoding.equalsIgnoreCase(Constant.ENCODING_BASE64)) { dataToBeSigned = DatatypeConverter.parseBase64Binary(hash); } else { dataToBeSigned = DatatypeConverter.parseHexBinary(hash); } } } catch (Exception e) { throw e; } if(null == dataToBeSigned) { logger.error("DATA TO BE SIGNED IS NULL"); return null; } List ecdsaPrivateKey = null; if (!Utils.isNullOrEmpty(keyId)) { ecdsaPrivateKey = hsmManager.getECKeyByID(keyId); } if (Utils.isNullOrEmpty(ecdsaPrivateKey)) { if (!Utils.isNullOrEmpty(keyLabel)) { ecdsaPrivateKey = hsmManager.getECKeyByLabel(keyLabel); } } if(Utils.isNullOrEmpty(ecdsaPrivateKey)) { logger.error("NO KEY ID FOUND"); return null; } ECDSAPrivateKey signingKey = ecdsaPrivateKey.get(0); byte[] signature = hsmManager.sign(PKCS11Constants.CKM_ECDSA, dataToBeSigned, signingKey); if(null == signature) { logger.error("SIGNATURE IS NULL"); return null; } return DatatypeConverter.printBase64Binary(signature); } catch (Exception ex) { logger.error("GET TA SIGNATURE FAIL " + ex); return null; } } // // private static ECPublicKey createECPublicKey(byte[] encodedAlgorithmIdParameters, byte[] encodedPoint) throws InvalidKeySpecException, IOException { ASN1Encodable algParams; if (encodedAlgorithmIdParameters[0] == 6) { algParams = ASN1ObjectIdentifier.getInstance(encodedAlgorithmIdParameters); } else { algParams = X962Parameters.getInstance(encodedAlgorithmIdParameters); } AlgorithmIdentifier algId = new AlgorithmIdentifier( X9ObjectIdentifiers.id_ecPublicKey, algParams); SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(algId, encodedPoint); X509EncodedKeySpec keySpec; try { keySpec = new X509EncodedKeySpec(spki.getEncoded()); } catch (IOException ex) { throw new InvalidKeySpecException(ex.getMessage(), ex); } KeyFactory kf; try { kf = KeyFactory.getInstance("EC", "BC"); } catch (NoSuchAlgorithmException | NoSuchProviderException ex) { throw new InvalidKeySpecException(ex.getMessage(), ex); } return (ECPublicKey) kf.generatePublic(keySpec); } // }