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