📄 pkcs11signer.java
字号:
/** * j4sign - an open, multi-platform digital signature solution * Copyright (c) 2004 Roberto Resoli - Servizio Sistema Informativo - Comune di Trento. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *//* * $Header: /cvsroot/j4sign/j4sign/src/java/core/it/trento/comune/j4sign/pkcs11/PKCS11Signer.java,v 1.4 2005/02/08 15:53:08 resoli Exp $ * $Revision: 1.4 $ * $Date: 2005/02/08 15:53:08 $ */package it.trento.comune.j4sign.pkcs11;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.security.cert.CertificateException;import java.util.ArrayList;import java.util.Arrays;import java.util.Iterator;import java.util.Set;import iaik.pkcs.pkcs11.TokenException;import iaik.pkcs.pkcs11.wrapper.CK_ATTRIBUTE;import iaik.pkcs.pkcs11.wrapper.CK_INFO;import iaik.pkcs.pkcs11.wrapper.CK_MECHANISM;import iaik.pkcs.pkcs11.wrapper.CK_MECHANISM_INFO;import iaik.pkcs.pkcs11.wrapper.CK_SLOT_INFO;import iaik.pkcs.pkcs11.wrapper.CK_TOKEN_INFO;import iaik.pkcs.pkcs11.wrapper.Functions;import iaik.pkcs.pkcs11.wrapper.PKCS11;import iaik.pkcs.pkcs11.wrapper.PKCS11Connector;import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;/** * This class uses the PKCS#11 Java api provieded by <a * href="http://jce.iaik.tugraz.at/products/14_PKCS11_Wrapper/index.php">IAIK * pkcs11 wrapper </a> to perform PKCS#11 digital signature operations. <br> * The IAIK wrapper is released in open source under an Apache-style license. * <br> * Here we use only a low-level subset of the wrapper's api (distributed in the * j4sign installer package), so to minimize the weight of the relative jar * files in an applet signing environment. * <p> * Several methods are designed to ease object retrieval during an italian style * digital signature process. See * {@link PKCS11Signer#findCertificateWithNonRepudiationCritical()}for details. * * * @author Roberto Resoli */public class PKCS11Signer { /** * The <code>cryptokiLibrary</code> is the native library implementing the * <code>PKCS#11</code> specification. */ private java.lang.String cryptokiLibrary = null; /** * The PKCS#11 session identifier returned when a session is opened. Value * is -1 if no session is open. */ private long sessionHandle = -1L; /** * The PKCS#11 token identifier. Value is -1 if there is no current token. */ private long tokenHandle = -1L;; /** * The java object wrapping criptoki library functionalities. */ private PKCS11 pkcs11Module = null; /** * PKCS#11 identifier for the signature algorithm. */ private CK_MECHANISM signatureMechanism = null; /** * The <code>PrintStream</code> where logging messages are written. * */ private java.io.PrintStream log = null; public PKCS11Signer(String cryptokiLib, long mechanism, java.io.PrintStream out) throws IOException, TokenException { this(cryptokiLib, out); initializeTokenAndMechanism(mechanism); } public PKCS11Signer(String cryptokiLib, java.io.PrintStream out) throws IOException, TokenException { super(); log = out; cryptokiLibrary = cryptokiLib; log.println("\n\nInitializing PKCS11Signer...\n"); log.println("Trying to connect to PKCS#11 module: '" + cryptokiLibrary + "' ..."); pkcs11Module = PKCS11Connector.connectToPKCS11Module(cryptokiLibrary); log.println("connected.\n"); initializeLibrary(); } /** * Initializes cryptoki library operations. * * @throws PKCS11Exception */ private void initializeLibrary() throws PKCS11Exception { log.println("\ninitializing module ... "); pkcs11Module.C_Initialize(null); log.println("initialized.\n"); } private void initializeTokenAndMechanism(long mechanism) throws PKCS11Exception { tokenHandle = getTokenSupportingMechanism(mechanism); if (tokenHandle >= 0) { log.println("\nSetting signing token handle: " + tokenHandle); log.println("\nSetting signing mechanism id: " + mechanism + " -> " + Functions.mechanismCodeToString(mechanism)); setMechanism(mechanism); } } public void setMechanism(long mechanism, Object pParameter) { this.signatureMechanism = new CK_MECHANISM(); this.signatureMechanism.mechanism = mechanism; this.signatureMechanism.pParameter = pParameter; } public void setMechanism(long mechanism) { this.setMechanism(mechanism, null); } /** * Closes the default PKCS#11 session. * * @throws PKCS11Exception */ public void closeSession() throws PKCS11Exception { if (getSession() == -1L) return; log.println("\nClosing session ..."); pkcs11Module.C_CloseSession(getSession()); setSession(-1L); } /** * Closes a specific PKCS#11 session. * * @param sessionHandle * handle of the session to close. * @throws PKCS11Exception */ public void closeSession(long sessionHandle) throws PKCS11Exception { log.println("\nClosing session with handle: " + sessionHandle + " ..."); pkcs11Module.C_CloseSession(sessionHandle); } /** * Error decoding function. Currently not implemented (returns 'Unknown * error' everytime). * * * @param errorCode * id of the error. * @return the decription corresponding to error code. */ public static String decodeError(int errorCode) { String errorString = "Unknown error."; /* * switch (errorCode) { case PKCS11Exception. : errorString = "PIN * errato."; break; case PKCS11Exception.PIN_INVALID : errorString = * "PIN non valido."; break; case PKCS11Exception.TOKEN_NOT_PRESENT : * errorString = "Inserire la carta."; break; } */ return errorString; } /** * Returns the private key handle, on current token, corresponding to the * given textual label. * * @param label * the string label to search. * @return the integer identifier of the private key, or -1 if no key was * found. * @throws PKCS11Exception */ public long findSignatureKeyFromLabel(String label) throws PKCS11Exception { long signatureKeyHandle = -1L; if (getSession() < 0) return -1L; log.println("finding signature key with label: '" + label + "'"); CK_ATTRIBUTE[] attributeTemplateList = new CK_ATTRIBUTE[2]; //CK_ATTRIBUTE[] attributeTemplateList = new CK_ATTRIBUTE[1]; attributeTemplateList[0] = new CK_ATTRIBUTE(); attributeTemplateList[0].type = PKCS11Constants.CKA_CLASS; attributeTemplateList[0].pValue = new Long( PKCS11Constants.CKO_PRIVATE_KEY); attributeTemplateList[1] = new CK_ATTRIBUTE(); attributeTemplateList[1].type = PKCS11Constants.CKA_LABEL; attributeTemplateList[1].pValue = label.toCharArray(); pkcs11Module.C_FindObjectsInit(getSession(), attributeTemplateList); long[] availableSignatureKeys = pkcs11Module.C_FindObjects( getSession(), 100); //maximum of 100 at once if (availableSignatureKeys == null) { log.println("null returned - no signature key found"); } else { log.println("found " + availableSignatureKeys.length + " signature keys, picking first."); for (int i = 0; i < availableSignatureKeys.length; i++) { if (i == 0) { // the first we find, we take as our signature key signatureKeyHandle = availableSignatureKeys[i]; log .println("for signing we use signature key with handle: " + signatureKeyHandle); } } } pkcs11Module.C_FindObjectsFinal(getSession()); return signatureKeyHandle; } /** * Returns the private key handle, on current token, corresponding to the * given byte[]. ID is often the byte[] version of the label. * * @param id * the byte[] id to search. * @return the integer identifier of the private key, or -1 if no key was * found. * @throws PKCS11Exception * @see PKCS11Signer#findSignatureKeyFromLabel(String) */ public long findSignatureKeyFromID(byte[] id) throws PKCS11Exception { long signatureKeyHandle = -1L; if (getSession() < 0) return -1L; log.println("finding signature key from id."); CK_ATTRIBUTE[] attributeTemplateList = new CK_ATTRIBUTE[2]; attributeTemplateList[0] = new CK_ATTRIBUTE(); attributeTemplateList[0].type = PKCS11Constants.CKA_CLASS; attributeTemplateList[0].pValue = new Long( PKCS11Constants.CKO_PRIVATE_KEY); attributeTemplateList[1] = new CK_ATTRIBUTE(); attributeTemplateList[1].type = PKCS11Constants.CKA_ID; attributeTemplateList[1].pValue = id; pkcs11Module.C_FindObjectsInit(getSession(), attributeTemplateList); long[] availableSignatureKeys = pkcs11Module.C_FindObjects( getSession(), 100); //maximum of 100 at once if (availableSignatureKeys == null) { log .println("null returned - no signature key found with matching ID"); } else { log.println("found " + availableSignatureKeys.length + " signature keys, picking first."); for (int i = 0; i < availableSignatureKeys.length; i++) { if (i == 0) { // the first we find, we take as our signature key signatureKeyHandle = availableSignatureKeys[i]; log.println("returning signature key with handle: " + signatureKeyHandle); } } } pkcs11Module.C_FindObjectsFinal(getSession()); return signatureKeyHandle; } /** * Returns the first private key handle found on current token. * * @return a private key handle, or -1 if no key is found. * @throws PKCS11Exception */ public long findSignatureKey() throws PKCS11Exception { long signatureKeyHandle = -1L;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -