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