View Javadoc

1   package org.eparapher.core.crypto.keystore;
2   
3   import java.io.FileNotFoundException;
4   import java.io.IOException;
5   import java.security.KeyStore;
6   import java.security.KeyStoreException;
7   import java.security.NoSuchAlgorithmException;
8   import java.security.ProviderException;
9   import java.security.cert.CertificateException;
10  
11  import org.apache.log4j.Logger;
12  import org.eparapher.core.EParapherManager;
13  import org.eparapher.core.crypto.EPCryptoProviderManager;
14  import org.eparapher.core.crypto.KeystoreEntry;
15  import org.eparapher.core.crypto.keystore.smartcard.MyGUICallbackHandler;
16  
17  import sun.security.pkcs11.wrapper.PKCS11Exception;
18  
19  
20  //http://java.sun.com/j2se/1.6.0/docs/guide/security/p11guide.html#P11Provider
21  //http://www.ibm.com/developerworks/java/jdk/security/50/secguides/pkcs11implDocs/IBMJavaPKCS11ImplementationProvider.html#Initialize
22  //FIXME : Ask PIN Code for Signing operation
23  
24  public class HardwareKeyStore extends GenericKeystore {
25  
26  	private static Logger log = Logger.getLogger(HardwareKeyStore.class);
27  
28  	protected KeyStore.Builder builder;
29  	private MyGUICallbackHandler smartcardguipopups;
30  	
31  	//Flag that tell if Token is reachable through PKCS11
32  	private boolean removed;
33  	private boolean pkcs11BridgeLoaded;
34  
35  	public HardwareKeyStore() {
36  		super();
37  		pkcs11BridgeLoaded = EPCryptoProviderManager.InitPKCS11Provider();
38  		smartcardguipopups = new MyGUICallbackHandler();
39  		if (pkcs11BridgeLoaded)
40  			builder =  KeyStore.Builder.newInstance(EPCryptoProviderManager.getKSImpl(), EPCryptoProviderManager.getPKCS11Provider(), new KeyStore.CallbackHandlerProtection(smartcardguipopups));
41  		setRemoved(true);
42  	}
43  
44  	public void getKeyStore(){
45  		try {
46  			if (builder==null)
47  				return;
48  			log.debug("PKCS11 -> Recuperation du keystore");
49  			ks = builder.getKeyStore();
50  			setRemoved(false);
51  		} catch (KeyStoreException e) {
52  			//EVENT : Smart Card not detected, Bad PIN, PIN Blocked, ...
53  			fireMessage(e);
54  		} catch (ProviderException pe) {
55  			// EVENT : SmartCard has been removed
56  			log.info("SmartCard has been removed",pe);
57  			EParapherManager.getInstance().getUI().refreshCertificateList();
58  		}
59  	}
60  
61  	public boolean loadKeyStore() {
62  		if (ks==null)
63  			getKeyStore();
64  		if (ks!=null) {
65  			try {
66  				ks.load(null,null);
67  				//log.debug("SmartCard is Present");
68  				this.loadPublicInformation();
69  				this.loadedKeystore = true;
70  				setRemoved(false);
71  				return true;
72  			} catch (NoSuchAlgorithmException nsae) {
73  				log.error("PKCS11 Login failed : " + nsae.getMessage());
74  			} catch (CertificateException ce) {
75  				log.error("PKCS11 Login failed : " + ce.getMessage());
76  			} catch (IOException ioe) {
77  				log.debug("PKCS11 Keystore loading failed : " + ioe.getMessage(),ioe);
78  				log.error("PKCS11 Keystore loading failed, try to rebuild the keystore.");
79  				ks = null;
80  			} catch (ProviderException pe) {
81  				log.info( pe.getMessage());
82  				ks = null;
83  				setRemoved(true);
84  			} catch (NullPointerException npe) {
85  				log.debug("!!!Please Insert Your SmartCard!!! ",npe);
86  				ks = null;
87  			}
88  		}
89  		return false;		
90  	}
91  
92  	private boolean validatePIN(String mpin) {
93  		if (mpin==null || mpin.equals(""))
94  			return false;
95  		if (ks==null)
96  			getKeyStore();
97  		if (ks!=null) {
98  			try {
99  				ks.load(null,mpin.toCharArray());
100 				return true;
101 			} catch (NoSuchAlgorithmException nsae) {
102 				log.error("PKCS11 Login failed : " + nsae.getMessage());
103 			} catch (CertificateException ce) {
104 				log.error("PKCS11 Login failed : " + ce.getMessage());
105 			} catch (IOException ioe) {
106 				log.error("PKCS11 Keystore loading failed, try to rebuild the keystore.");
107 				log.debug("" + ioe.getMessage(),ioe);
108 				ks = null;
109 			} catch (ProviderException pe) {
110 				log.debug("SmartCard has been removed : " + pe.getMessage());
111 				ks = null;
112 				setRemoved(true);
113 			} catch (NullPointerException npe) {
114 				log.debug("!!!Please Insert Your SmartCard!!! ",npe);
115 				ks = null;
116 			}
117 		}
118 		return false;
119 	}
120 
121 	private void fireMessage(Exception e) {
122 		Throwable PKCS11cause = e;
123 		if (e!=null && e.getCause()!=null && e.getCause().getMessage().equals("PKCS11 not found")) {
124 			log.debug("Please Insert Your SmartCard");
125 			return;
126 		}
127 		while (PKCS11cause!=null && !(PKCS11cause instanceof PKCS11Exception))
128 			PKCS11cause = PKCS11cause.getCause();
129 		if (PKCS11cause!=null) {
130 			String PKCS11_MSG = PKCS11cause.getMessage();
131 			if (PKCS11_MSG.indexOf("CKR_PIN_LOCKED")>=0)
132 				EParapherManager.getInstance().getUI().errorMessage("Your smartcard PIN is blocked!");
133 			else if (PKCS11_MSG.indexOf("CKR_PIN_INCORRECT")>=0)
134 				EParapherManager.getInstance().getUI().errorMessage("Your PIN is incorrect");
135 			else if (PKCS11_MSG.indexOf("CKR_PIN_INVALID")>=0)
136 				EParapherManager.getInstance().getUI().errorMessage("Your PIN is invalid");
137 			else if (PKCS11_MSG.indexOf("CKR_TOKEN_NOT_PRESENT")>=0)
138 				EParapherManager.getInstance().getUI().errorMessage("Card not detected");
139 			else log.warn("Keystore error while accessing PKCS11 Token ",e);
140 		} else log.warn("Keystore error while accessing PKCS11 Token ",e);
141 	}
142 	
143 	public KeystoreEntry[] getKeystoreEntries() {
144 		if (loadKeyStore())
145 			return super.getKeystoreEntries();
146 		else return null;
147 	}
148 
149 	public boolean isRemoved() {
150 		return removed;
151 	}
152 
153 	public void setRemoved(boolean mremoved) {
154 		if ( this.removed == true && mremoved==false ) 
155 			log.info("SmartCard has been replugged");
156 		this.removed = removed;
157 	}
158 	
159 	public boolean loadPrivateKey() {
160 		if (this.removed)
161 			return false;
162 		
163 		return super.loadPrivateKey(null);
164 	}
165 
166 	public boolean loadKeyStore(String secret) {
167 		// Nothing to do here : managed by the callback handler
168 		return true;
169 	}
170 
171 	public boolean saveKeyStore() {
172 		if (loadKeyStore()) {
173 			try {
174 				ks.store(null, null);
175 				return true;
176 			} catch (FileNotFoundException e) {
177 				log.error("Error Saving Keystore on smartCard",e);
178 			} catch (KeyStoreException e) {
179 				log.error("Error Saving Keystore on smartCard",e);
180 			} catch (NoSuchAlgorithmException e) {
181 				log.error("Error Saving Keystore on smartCard",e);
182 			} catch (CertificateException e) {
183 				log.error("Error Saving Keystore on smartCard",e);
184 			} catch (IOException e) {
185 				log.error("Error Saving Keystore on smartCard",e);
186 			}
187 			return false;
188 		}
189 		return false;
190 	}
191 
192 	public boolean isPkcs11BridgeLoaded() {
193 		return pkcs11BridgeLoaded;
194 	}
195 
196 	public boolean exists() {
197 		if (!pkcs11BridgeLoaded)
198 			EParapherManager.getInstance().getUI().showKeystoreSettings();
199 		return true;
200 	}
201 
202 	public boolean initialize() {
203 		if (!pkcs11BridgeLoaded) {
204 			EParapherManager.getInstance().getUI().warnMessage("Error while loading PKCS11 Bridge. Please check your PKCS11 configuration.");
205 			EParapherManager.getInstance().getUI().showKeystoreSettings();
206 		}
207 		return true;
208 	}
209 }