/*
* 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 hsm;
import hsmexampleconsole.HSMExampleConsole;
import iaik.pkcs.pkcs11.Mechanism;
import iaik.pkcs.pkcs11.Session;
import iaik.pkcs.pkcs11.Token;
import iaik.pkcs.pkcs11.TokenException;
import iaik.pkcs.pkcs11.objects.AESSecretKey;
import iaik.pkcs.pkcs11.objects.ECDSAPrivateKey;
import iaik.pkcs.pkcs11.objects.ECDSAPublicKey;
import iaik.pkcs.pkcs11.objects.Key;
import iaik.pkcs.pkcs11.objects.KeyPair;
import iaik.pkcs.pkcs11.objects.RSAPrivateKey;
import iaik.pkcs.pkcs11.objects.RSAPublicKey;
import iaik.pkcs.pkcs11.parameters.InitializationVectorParameters;
import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import javax.xml.bind.DatatypeConverter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.slf4j.LoggerFactory;
/**
*
* @author TuoiCM
*/
public class HSMManagerImp implements HSMManager {
//
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(HSMExampleConsole.class);
private boolean login;
private static HSMManager instance = null;
public HSMFunction hsmFunction;
//public static ConcurrentHashMap sessionManager;
private String passsword;
private Session sessionLogin;
/*private static String LIBS_WRAPPER = "PKCS11Wrapper";
private static String PATH32 = "wrapper32/";
private static String PATH64 = "wrapper64/";*/
private int slotNumber;
private static ReentrantLock lock = new ReentrantLock();
//
public HSMFunction getHsmFunction() {
return hsmFunction;
}
public HSMManagerImp(String pkcs11LibName, String pkcs11Wrapper, int slot, String password) throws IOException, TokenException {
// TODO Auto-generated constructor stub
hsmFunction = new HSMFunction();
//init(pkcs11LibName, pkcs11Wrapper);
hsmFunction.loadDll(pkcs11LibName, pkcs11Wrapper);
this.slotNumber = slot;
this.login = false;
this.passsword = password;
}
@SuppressWarnings("unused")
private void init(String dllName, String wrapper) throws Throwable {
// TODO Auto-generated method stub
//String pkcs11Wrapper = loadWrapper(LIBS_WRAPPER);
String pkcs11Wrapper = wrapper;
//logger.debug("LIBS_WRAPPER: " + pkcs11Wrapper);
hsmFunction.loadDll(dllName, pkcs11Wrapper);
}
public static HSMManager getInstance(String pkcs11LibName, String pkcs11Wrapper, int slot, String password) {
// if (instance != null) {
// return instance;
// }
// lock.lock();
// if (instance != null) {
// lock.unlock();
// return instance;
// }
lock.lock();
try {
instance = new HSMManagerImp(pkcs11LibName, pkcs11Wrapper, slot, password);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return instance;
}
public boolean loginHSM() throws TokenException {
// TODO Auto-generated method stub
if (isLogin()) {
return true;
}
lock.lock();
if (isLogin()) {
lock.unlock();
return true;
}
try {
sessionLogin = hsmFunction.openSession(slotNumber);
login = hsmFunction.login(sessionLogin, passsword);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
throw e;
} finally {
lock.unlock();
}
return login;
}
public boolean logoutHSM() throws TokenException {
// TODO Auto-generated method stub
boolean status1 = hsmFunction.logout(sessionLogin);
if (status1) {
login = false;
sessionLogin.closeSession();
return true;
} else {
return false;
}
}
private boolean isLogin() {
return login;
}
@Override
public Token connectHSM() throws TokenException {
// TODO Auto-generated method stub
Token tokenInfo = hsmFunction.getToken();
if (tokenInfo == null) {
hsmFunction.connectToken(slotNumber);
}
return hsmFunction.getToken();
}
@Override
public boolean disconnectHSM() {
// TODO Auto-generated method stub
boolean res = false;
try {
res = logoutHSM();
} catch (TokenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (hsmFunction.disconnectToken()) {
instance = null;
}
}
return res;
}
@Override
public String encryptDataWithKeyID(String plaintext, String KeyID)
throws TokenException, UnsupportedEncodingException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPublicKey publickey = hsmFunction.getPublicKeyByID(KeyID, session);
if (publickey == null) {
session.closeSession();
return "0";
} else {
//if don't opnen session????
//session = hsmFunction.openSession(null, new PKCS11NotifyImpl());
byte[] enc = hsmFunction.encrypt(plaintext, publickey, session);
String base64enc = DatatypeConverter.printBase64Binary(enc);
session.closeSession();
return base64enc;
}
} else {
return "2";
}
}
@Override
public byte[] encryptDataWithKeyID(byte[] data, String KeyID) throws TokenException, UnsupportedEncodingException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPublicKey publickey = hsmFunction.getPublicKeyByID(KeyID, session);
if (publickey == null) {
session.closeSession();
return null;
} else {
//if don't opnen session????
//session = hsmFunction.openSession(null, new PKCS11NotifyImpl());
byte[] enc = hsmFunction.encrypt(data, publickey, session);
session.closeSession();
return enc;
}
} else {
return null;
}
}
@Override
public String decryptDataWithKeyID(String encText, String KeyID) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
try {
Session session = hsmFunction.openSession(slotNumber);
RSAPrivateKey privatekey = hsmFunction.getPrivateKeyByID(KeyID, session);
if (privatekey == null) {
session.closeSession();
return "0";
}
byte[] e = DatatypeConverter.parseBase64Binary(encText);
byte[] dec = hsmFunction.decryptData(e, privatekey, session);
String plaintext = new String(dec, "UTF-8");
session.closeSession();
return plaintext;
} catch (IOException var16) {
var16.printStackTrace();
return "1";
}
} else {
return "2";
}
}
@Override
public byte[] decryptDataWithKeyID(byte[] dataEncoded, String KeyID) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPrivateKey privatekey = hsmFunction.getPrivateKeyByID(KeyID, session);
if (privatekey == null) {
session.closeSession();
return null;
}
byte[] data = hsmFunction.decryptData(dataEncoded, privatekey, session);
session.closeSession();
return data;
} else {
return null;
}
}
@Override
public byte[] unWrapKey(byte[] secretKeyWrapped, String hsmKeyID) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
//byte[] wrappedKeyRaw = DatatypeConverter.parseBase64Binary(wrappedKey);
// System.out.println("wrappedKeyRaw: " +
// DatatypeConverter.printHexBinary(wrappedKeyRaw));
RSAPrivateKey privateKey = hsmFunction.getPrivateKeyByID(hsmKeyID, session);
privateKey.getUnwrap().setBooleanValue(Boolean.TRUE);
byte[] rawKeyWrapped = hsmFunction.unwrapAESKey(privateKey, secretKeyWrapped, session);
session.closeSession();
return rawKeyWrapped;
} else {
return null;
}
}
@Override
public AESSecretKey genAESSecretKey(int size) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
AESSecretKey response = hsmFunction.genAESKey(size, session);
//not close session when crate AES-key
//session.closeSession();
return response;
}
return null;
}
@Override
public byte[] wrapKey(AESSecretKey scSysKey, String hsmKeyID) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPublicKey publicKey = hsmFunction.getPublicKeyByID(hsmKeyID, session);
publicKey.getWrap().setBooleanValue(Boolean.TRUE);
byte[] rawKeyWrapped = hsmFunction.wrapKey((Key) publicKey, (Key) scSysKey, session);
//String base64WrappedKey = DatatypeConverter.printBase64Binary(rawKeyWrapped);
session.closeSession();
return rawKeyWrapped;
} else {
return null;
}
}
@Override
public byte[] wrapKey(Key wrappedKey, Key wrappingKey, long mode, byte[] iv) throws TokenException {
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
Mechanism mechanism = Mechanism.get(mode);
if (iv != null) {
mechanism.setParameters(new InitializationVectorParameters(iv));
}
byte[] rawKeyWrapped = hsmFunction.wrapKey(wrappingKey, wrappedKey, session, mechanism);
session.closeSession();
return rawKeyWrapped;
} else {
return null;
}
}
@Override
public boolean hasKeyID(String keyID) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPublicKey publicKey = hsmFunction.getPublicKeyByID(keyID, session);
session.closeSession();
return publicKey != null;
} else {
return false;
}
}
@Override
public byte[] signWithKeyID(long pkcs11MechanismCode, byte[] data, String KeyID)
throws PKCS11Exception, TokenException, UnsupportedEncodingException, HSMException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPrivateKey privateKey = hsmFunction.getPrivateKeyByID(KeyID, session);
if (privateKey == null) {
session.closeSession();
throw new HSMException("HSM not found key for id " + KeyID);
}
byte[] signed = hsmFunction.sign(pkcs11MechanismCode, data, privateKey, session);
session.closeSession();
return signed;
}
return null;
}
@Override
public byte[] genAndWrapAESSecretKey(int size, String hsmKeyID) throws Exception {
// TODO Auto-generated method stub
byte[] rawKeyWrapped = null;
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
AESSecretKey aesKey = hsmFunction.genAESKey(size, session);
RSAPublicKey publicKey = hsmFunction.getPublicKeyByID(hsmKeyID, session);
publicKey.getWrap().setBooleanValue(Boolean.TRUE);
rawKeyWrapped = hsmFunction.wrapKey((Key) publicKey, (Key) aesKey, session);
session.closeSession();
}
return rawKeyWrapped;
}
@Override
public byte[] signWithPrivateKey(long pkcs11MechanismCode, byte[] plaintext, Key privateKey)
throws PKCS11Exception, TokenException, UnsupportedEncodingException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
if (privateKey == null) {
session.closeSession();
return null;
}
byte[] signed = hsmFunction.sign(pkcs11MechanismCode, plaintext, privateKey, session);
session.closeSession();
return signed;
}
return null;
}
@Override
public byte[] signWithPrivateKey20210224(long pkcs11MechanismCode, byte[] plaintext, RSAPrivateKey privateKey)
throws PKCS11Exception, TokenException, UnsupportedEncodingException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
if (privateKey == null) {
session.closeSession();
return null;
}
byte[] signed = hsmFunction.sign(pkcs11MechanismCode, plaintext, privateKey, session);
session.closeSession();
return signed;
}
return null;
}
@Override
public RSAPrivateKey getPrivateKeyWithKeyID(String keyId) throws TokenException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
RSAPrivateKey privateKey = hsmFunction.getPrivateKeyByID(keyId, session);
session.closeSession();
return privateKey;
} else {
return null;
}
}
@Override
public Key getKeyWithKeyID(String keyId) throws TokenException {
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
Key key = hsmFunction.getKeyByID(keyId, session);
session.closeSession();
return key;
} else {
return null;
}
}
@Override
public Key unWrapKey(byte[] secretKeyWrapped, Key wrappingKey, long mode, byte[] iv, Long keyType, String keyID, boolean isToken) throws TokenException {
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
Mechanism mechanism = Mechanism.get(mode);
if (iv != null) {
mechanism.setParameters(new InitializationVectorParameters(iv));
}
Key wrappedKey = hsmFunction.unwrapKey(wrappingKey, secretKeyWrapped, session, mechanism, keyType, keyID, isToken);
session.closeSession();
return wrappedKey;
} else {
return null;
}
}
@Override
public AESSecretKey genAESSecretKey(String keyID, int size, boolean isToken) throws TokenException {
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
AESSecretKey response = hsmFunction.genAESKey(keyID, size, session, isToken, true);
//not close session when crate AES-key
session.closeSession();
return response;
}
return null;
}
@Override
public boolean deleteKeyPair(KeyPair keyPair) throws TokenException {
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
hsmFunction.deleteKey(keyPair.getPrivateKey(), session);
hsmFunction.deleteKey(keyPair.getPublicKey(), session);
session.closeSession();
return true;
} else {
return false;
}
}
@Override
public boolean deleteKey(Key key) throws TokenException {
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
hsmFunction.deleteKey(key, session);
session.closeSession();
return true;
} else {
return false;
}
}
@Override
public List getECKeyByID(String keyID) throws Exception {
// TODO Auto-generated method stub
List keys = new ArrayList<>();
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
keys = hsmFunction.getECKeyByID(session, keyID);
session.closeSession();
} else {
throw new Exception("Cannot login to HSM");
}
return keys;
}
@Override
public List getECKeyByLabel(String keyLabel) throws Exception {
// TODO Auto-generated method stub
List keys = new ArrayList<>();
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
keys = hsmFunction.getECKeyByLabel(session, keyLabel);
session.closeSession();
} else {
throw new Exception("Cannot login to HSM");
}
return keys;
}
@Override
public List getPublicECKeyByID(String keyID) throws Exception {
// TODO Auto-generated method stub
List keys = new ArrayList<>();
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
keys = hsmFunction.getPublicECKeyByID(session, keyID);
session.closeSession();
} else {
throw new Exception("Cannot login to HSM");
}
return keys;
}
@Override
public List getPublicECKeyByLabel(String keyLabel) throws Exception {
// TODO Auto-generated method stub
List keys = new ArrayList<>();
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
keys = hsmFunction.getPublicECKeyByLabel(session, keyLabel);
session.closeSession();
} else {
throw new Exception("Cannot login to HSM");
}
return keys;
}
@Override
public List listECKeys() throws Exception {
// TODO Auto-generated method stub
List keys = new ArrayList<>();
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
keys = hsmFunction.listECKeys(session);
session.closeSession();
} else {
throw new Exception("Cannot login to HSM");
}
return keys;
}
@Override
public byte[] sign(long pkcs11MechanismCode, byte[] plaintext, Key privateKey)
throws PKCS11Exception, TokenException, UnsupportedEncodingException {
// TODO Auto-generated method stub
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
if (privateKey == null) {
session.closeSession();
return null;
}
byte[] signed = hsmFunction.sign(pkcs11MechanismCode, plaintext, privateKey, session);
session.closeSession();
return signed;
}
return null;
}
@Override
public boolean idExists(String keyID) throws TokenException {
boolean isExisted = false;
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
isExisted = hsmFunction.idExists(session, keyID);
session.closeSession();
return isExisted;
}
return isExisted;
}
@Override
public boolean labelExists(String keyLabel) throws TokenException {
boolean isExisted = false;
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
isExisted = hsmFunction.labelExists(session, keyLabel);
session.closeSession();
return isExisted;
}
return isExisted;
}
@Override
public KeyPair genECDSAKeyPair(String keyID, String keyLabel, final ASN1ObjectIdentifier curveId) throws TokenException {
KeyPair keyPair = null;
if (!isLogin()) {
loginHSM();
}
if (isLogin()) {
Session session = hsmFunction.openSession(slotNumber);
keyPair = hsmFunction.genECDSAKeyPair(keyID, keyLabel, curveId, session);
session.closeSession();
}
return keyPair;
}
@Override
public int removeObjects(String keyID, String keyLabel) throws TokenException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}