001// Copyright (C) 2002 IAIK 002// https://sic.tech/ 003// 004// Copyright (C) 2003 - 2025 Stiftung Secure Information and 005// Communication Technologies SIC 006// https://sic.tech/ 007// 008// All rights reserved. 009// 010// This source is provided for inspection purposes and recompilation only, 011// unless specified differently in a contract with IAIK. This source has to 012// be kept in strict confidence and must not be disclosed to any third party 013// under any circumstances. Redistribution in source and binary forms, with 014// or without modification, are <not> permitted in any case! 015// 016// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 017// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 018// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 019// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 020// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 021// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 022// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 023// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 024// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 025// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 026// SUCH DAMAGE. 027// 028// $Header: /IAIK-CMS/current/src/demo/cms/pkcs11/PKCS11Demo.java 11 12.02.25 17:58 Dbratko $ 029// $Revision: 11 $ 030 031package demo.cms.pkcs11; 032 033import iaik.cms.SecurityProvider; 034import iaik.pkcs.pkcs11.provider.Constants; 035import iaik.pkcs.pkcs11.provider.IAIKPkcs11; 036import iaik.security.provider.IAIK; 037 038import java.io.IOException; 039import java.security.GeneralSecurityException; 040import java.security.KeyStore; 041import java.security.NoSuchAlgorithmException; 042import java.security.NoSuchProviderException; 043import java.security.Provider; 044import java.security.Security; 045import java.util.Properties; 046 047/** 048 * Base class for PKCS#11 Demos. 049 */ 050public abstract class PKCS11Demo { 051 052 /** 053 * Module name (native PKCS#11 module of the cryptographic hardware. 054 * It may be necessary to provide the file with the full path, if the 055 * module is not in the search path of the system). 056 */ 057 protected String moduleName_ ; 058 059 /** 060 * The user pin for the token key store. 061 */ 062 protected char[] userPin_; 063 064 /** 065 * The PKCS#11 JCE provider. 066 */ 067 protected IAIKPkcs11 iaikPkcs11Provider_; 068 069 /** 070 * The IAIK JCE software provider. 071 */ 072 protected IAIK iaikSoftwareProvider_; 073 074 /** 075 * The key store that represents the token (smart card) contents. 076 */ 077 protected KeyStore tokenKeyStore_; 078 079 /** 080 * Creates a PKCS11Demo object that has to be explicitly 081 * {@link #init(String, char[]) initialized} with a module name. 082 */ 083 protected PKCS11Demo() { 084 085 } 086 087 /** 088 * Creates a PKCS11Demo object for the given module name. 089 * 090 * @param moduleName the name of the module 091 * @param userPin the user-pin (password) for the TokenKeyStore 092 * (may be <code>null</code> to pop-up a dialog asking for the pin) 093 */ 094 public PKCS11Demo(String moduleName, 095 char[] userPin) { 096 097 init(moduleName, userPin); 098 } 099 100 /** 101 * Inits this PKCS11Demo object for the given module name. 102 * 103 * @param moduleName the name of the module 104 * @param userPin the user-pin (password) for the TokenKeyStore 105 * (may be <code>null</code> to pou-up a dialog asking for the pin) 106 */ 107 public void init(String moduleName, 108 char[] userPin) { 109 110 if (moduleName == null) { 111 throw new NullPointerException("moduleName must not be null!"); 112 } 113 114 moduleName_ = moduleName; 115 userPin_ = userPin; 116 117 118 // check if we already have an installed provider for the requested module 119 int count = IAIKPkcs11.getProviderInstanceCount(); 120 for (int i = 1; i <= count; i++) { 121 IAIKPkcs11 pkcs11Prov = IAIKPkcs11.getProviderInstance(i); 122 if (pkcs11Prov != null) { 123 String module = pkcs11Prov.getProperties().getProperty(Constants.PKCS11_NATIVE_MODULE); 124 if ((module != null) && (moduleName.equalsIgnoreCase(module))) { 125 iaikPkcs11Provider_ = pkcs11Prov; 126 break; 127 } 128 } 129 } 130 131 if (iaikPkcs11Provider_ == null) { 132 // install IAIK PKCS#11 Provider 133 Properties pkcs11ProviderConfig = new Properties(); 134 pkcs11ProviderConfig.put(Constants.PKCS11_NATIVE_MODULE, moduleName_); 135 iaikPkcs11Provider_ = new IAIKPkcs11(pkcs11ProviderConfig); 136 } 137 138 //IAIKPkcs11.insertProviderAtForJDK14(iaikPkcs11Provider__, 1); // add IAIK PKCS#11 JCE provider as first, use JDK 1.4 bug workaround 139 Security.addProvider(iaikPkcs11Provider_); 140 141 // set CMS security provider 142 IaikPkcs11SecurityProvider pkcs11CmsSecurityProvider = new IaikPkcs11SecurityProvider(iaikPkcs11Provider_); 143 SecurityProvider.setSecurityProvider(pkcs11CmsSecurityProvider); 144 145 System.out.println("Installed crypto providers:"); 146 System.out.println(); 147 Provider[] providers = Security.getProviders(); 148 for (int i = 0; i < providers.length; i++) { 149 Provider provider = providers[i]; 150 System.out.println("Provider " + (i +1) + ": " + provider.getName() + " version: " + provider.getVersion()); 151 } 152 } 153 154 /** 155 * This method gets the key store of the PKCS#11 provider and stores 156 * a reference at<code>pkcs11ClientKeystore_</code>. 157 * 158 * @throws GeneralSecurityException If anything with the provider fails. 159 * @throws IOException If loading the key store fails. 160 */ 161 public void getKeyStore() throws GeneralSecurityException, IOException 162 { 163 // with this call we just get an uninitialized PKCS#11 key store, it is not bound to a 164 // specific IAIKPkcs11 provider instance after this call, even if you specify the provider 165 // at this call. this is a limitation of JCA KeyStore concept. the KeyStoreSPI object 166 // has no chance to get its own provider instance. 167 KeyStore tokenKeyStore = null; 168 try { 169 tokenKeyStore = KeyStore.getInstance("PKCS11KeyStore", iaikPkcs11Provider_.getName()); 170 } catch (NoSuchProviderException ex) { 171 throw new GeneralSecurityException(ex.toString()); 172 } 173 174 if (tokenKeyStore == null) { 175 System.out.println("Got no key store. Ensure that the provider is properly configured and installed."); 176 System.exit(0); 177 } 178 try { 179 tokenKeyStore.load(null, userPin_); // this call binds the keystore to the first instance of the IAIKPkcs11 provider 180 } catch (NoSuchAlgorithmException ex) { 181 throw new GeneralSecurityException(ex.toString()); 182 } 183 184 185 tokenKeyStore_ = tokenKeyStore; 186 } 187 188} 189 190