View Javadoc

1   /**
2    * LICENCIA LGPL:
3    * 
4    * Esta librería es Software Libre; Usted puede redistribuirla y/o modificarla
5    * bajo los términos de la GNU Lesser General Public License (LGPL) tal y como 
6    * ha sido publicada por la Free Software Foundation; o bien la versión 2.1 de 
7    * la Licencia, o (a su elección) cualquier versión posterior.
8    * 
9    * Esta librería se distribuye con la esperanza de que sea útil, pero SIN 
10   * NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o 
11   * ADECUACIÓN A UN PROPÓSITO PARTICULAR. Consulte la GNU Lesser General Public 
12   * License (LGPL) para más detalles
13   * 
14   * Usted debe recibir una copia de la GNU Lesser General Public License (LGPL) 
15   * junto con esta librería; si no es así, escriba a la Free Software Foundation 
16   * Inc. 51 Franklin Street, 5º Piso, Boston, MA 02110-1301, USA o consulte
17   * <http://www.gnu.org/licenses/>.
18   *
19   * Copyright 2011 Agencia de Tecnología y Certificación Electrónica
20   */
21  package es.accv.arangi.base.device;
22  
23  import iaik.pkcs.pkcs11.Mechanism;
24  import iaik.pkcs.pkcs11.MechanismInfo;
25  import iaik.pkcs.pkcs11.Session;
26  import iaik.pkcs.pkcs11.Token;
27  import iaik.pkcs.pkcs11.TokenException;
28  import iaik.pkcs.pkcs11.objects.PrivateKey;
29  import iaik.pkcs.pkcs11.objects.PublicKey;
30  import iaik.pkcs.pkcs11.objects.RSAPrivateKey;
31  import iaik.pkcs.pkcs11.objects.RSAPublicKey;
32  import iaik.pkcs.pkcs11.objects.X509PublicKeyCertificate;
33  
34  import java.io.ByteArrayInputStream;
35  import java.io.File;
36  import java.io.IOException;
37  import java.io.InputStream;
38  import java.lang.reflect.Constructor;
39  import java.lang.reflect.Method;
40  import java.math.BigInteger;
41  import java.security.InvalidKeyException;
42  import java.security.KeyPair;
43  import java.security.KeyStore;
44  import java.security.KeyStoreException;
45  import java.security.NoSuchAlgorithmException;
46  import java.security.Provider;
47  import java.security.Security;
48  import java.security.UnrecoverableKeyException;
49  import java.security.cert.CertificateEncodingException;
50  import java.security.cert.CertificateException;
51  import java.security.cert.X509Certificate;
52  import java.util.ArrayList;
53  import java.util.Arrays;
54  import java.util.HashMap;
55  import java.util.HashSet;
56  import java.util.Iterator;
57  import java.util.List;
58  import java.util.Map;
59  
60  import javax.crypto.BadPaddingException;
61  import javax.crypto.Cipher;
62  import javax.crypto.IllegalBlockSizeException;
63  import javax.crypto.NoSuchPaddingException;
64  
65  import org.apache.log4j.Logger;
66  import org.bouncycastle.asn1.ASN1Encoding;
67  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
68  import org.bouncycastle.asn1.ASN1Set;
69  import org.bouncycastle.asn1.DERBitString;
70  import org.bouncycastle.asn1.pkcs.CertificationRequest;
71  import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
72  import org.bouncycastle.asn1.util.ASN1Dump;
73  import org.bouncycastle.asn1.x500.X500Name;
74  import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
75  import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
76  
77  import sun.security.util.ObjectIdentifier;
78  import es.accv.arangi.base.algorithm.CipherAlgorithm;
79  import es.accv.arangi.base.algorithm.DigitalSignatureAlgorithm;
80  import es.accv.arangi.base.algorithm.HashingAlgorithm;
81  import es.accv.arangi.base.certificate.Certificate;
82  import es.accv.arangi.base.device.model.Pkcs11Device;
83  import es.accv.arangi.base.device.model.Pkcs11Manufacturer;
84  import es.accv.arangi.base.device.util.CSRUtil;
85  import es.accv.arangi.base.device.util.DeviceUtil;
86  import es.accv.arangi.base.device.util.pkcs11.Pkcs11Util;
87  import es.accv.arangi.base.device.util.pkcs11.SignUtil;
88  import es.accv.arangi.base.device.util.pkcs11.TokenPrivateKey;
89  import es.accv.arangi.base.device.util.pkcs11.TokenPublicKey;
90  import es.accv.arangi.base.document.IDocument;
91  import es.accv.arangi.base.document.InputStreamDocument;
92  import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
93  import es.accv.arangi.base.exception.device.AliasNotFoundException;
94  import es.accv.arangi.base.exception.device.AliasNotFreeException;
95  import es.accv.arangi.base.exception.device.CertificateInvalidException;
96  import es.accv.arangi.base.exception.device.CipherException;
97  import es.accv.arangi.base.exception.device.DeletingObjectException;
98  import es.accv.arangi.base.exception.device.DeviceFullException;
99  import es.accv.arangi.base.exception.device.DeviceNotFoundException;
100 import es.accv.arangi.base.exception.device.FormatException;
101 import es.accv.arangi.base.exception.device.IAIKDLLNotFoundException;
102 import es.accv.arangi.base.exception.device.IncorrectPINException;
103 import es.accv.arangi.base.exception.device.IncorrectPUKException;
104 import es.accv.arangi.base.exception.device.InitializeProviderException;
105 import es.accv.arangi.base.exception.device.KeyPairException;
106 import es.accv.arangi.base.exception.device.LoadingObjectException;
107 import es.accv.arangi.base.exception.device.LockedPINException;
108 import es.accv.arangi.base.exception.device.ModuleNotFoundException;
109 import es.accv.arangi.base.exception.device.OpeningDeviceException;
110 import es.accv.arangi.base.exception.device.ReadingStreamException;
111 import es.accv.arangi.base.exception.device.SavingObjectException;
112 import es.accv.arangi.base.exception.device.SearchingException;
113 import es.accv.arangi.base.exception.device.UnlockPINException;
114 import es.accv.arangi.base.exception.document.HashingException;
115 import es.accv.arangi.base.exception.document.InitDocumentException;
116 import es.accv.arangi.base.exception.signature.SignatureException;
117 import es.accv.arangi.base.util.Util;
118 
119 /**
120  * Clase abstracta que utilizarán los managers que sigan el estándar PKCS#11.<br><br>
121  * 
122  * Arangí se encargará de instalar los módulos para trabajar con los
123  * dispositivos PKCS#11. Para ello necesita un fichero XML que le indique
124  * dónde se encuentran los fichero de los módulos. Existen dos opciones:<br>
125  * <ul>
126  * 	<li>Primero Arangí buscará en la raíz del classpath un fichero con el
127  * 		nombre 'pkcs11_device_modules.xml'.</li>
128  * 	<li>Si no lo encuentra lo intentará en la URL de una web. Por defecto
129  * 		irá a http://???. Si se quiere que vaya a otra URL se tendría que
130  * 		arrancar la JVM mediante el siguiente parámetro -Darangi.pkcs11.device.url</li>
131  * </ul><br><br>
132  * 
133  * El fichero XML tendrá el siguiente formato: <br><br>
134  * 
135  * &lt;modules&gt;<br>
136  * &nbsp;&nbsp;&lt;version&gt;...&lt;version&gt;<br>
137  * &nbsp;&nbsp;&lt;module name="..."&gt;<br>
138  * &nbsp;&nbsp;&nbsp;&nbsp;&lt;classpath&gt;...&lt;/classpath&gt;<br>
139  * &nbsp;&nbsp;&lt;/module&gt;<br>
140  * &nbsp;&nbsp;&lt;module name="..."&gt;<br>
141  * &nbsp;&nbsp;&nbsp;&nbsp;&lt;url&gt;...&lt;/url&gt;<br>
142  * &nbsp;&nbsp;&lt;/module&gt;<br>
143  * &lt;/modules&gt;<br><br>
144  * 
145  * Estos ficheros se dejarán en la {@link #getArangiTemporalFolder() carpeta temporal de Arangí}
146  * siempre que en dicha carpeta no exista un fichero de nombre 'pkcs11_device_modules.xml'
147  * o, si existe, su versión es menor que la del fichero que se está usando ahora.
148  * 
149  * @author <a href="mailto:jgutierrez@accv.es">José M Gutiérrez</a>
150  */
151 public abstract class AbstractPkcs11Manager extends DeviceManager {
152 	
153 	/** Logger de clase */
154 	private static Logger logger = Logger.getLogger(AbstractPkcs11Manager.class);
155 	
156 	/*
157 	 * Nombre de la DLL de IAIK para 32 bits
158 	 */
159 	protected static final String IAIK_WINX86_DLL_NAME	= "pkcs11wrapper_3_x86.dll";
160 	
161 	/*
162 	 * Nombre de la DLL de IAIK para 64 bits
163 	 */
164 	protected static final String IAIK_WINX64_DLL_NAME	= "pkcs11wrapper_3_x64.dll";
165 	
166 	/*
167 	 * Path dentro del classpath de la dll de IAIK para 32 bits
168 	 */
169 	protected static final String IAIK_WINX86_DLL_CLASSPATH_PATH	= "es/accv/arangi/base/device/" + IAIK_WINX86_DLL_NAME;
170 	
171 	/*
172 	 * Path dentro del classpath de la dll de IAIK para 64 bits
173 	 */
174 	protected static final String IAIK_WINX64_DLL_CLASSPATH_PATH	= "es/accv/arangi/base/device/" + IAIK_WINX64_DLL_NAME;
175 	
176 	protected static File iaikDLLFile;
177 	
178 	protected String pin;
179 	
180 	protected boolean openWithPuk = false;
181 
182 	protected Pkcs11Device device;
183 	
184 	protected KeyStore keystore;
185 	
186 	protected String sunProviderName;
187 	
188 	protected boolean deleteOrphans = true;
189 	
190 	/* (non-Javadoc)
191 	 * @see es.accv.arangi.base.device.DeviceManager#close()
192 	 */
193 	public void close() {
194 		logger.debug("[CLOSE]::Cerrando dispositivo...");
195 		try {
196 			if (device.getSession() != null){
197 				device.getSession().logout();
198 				device.getSession().closeSession();
199 				logger.debug("[CLOSE]::Sesión cerrada");
200 			}
201 			
202 			if (device.getToken() != null){
203 				//-- TODO Ojo que cerrando todas las sesiones da problemas al 
204 				//-- matar la sesion SSL del navegador 
205 				//token.closeAllSessions();
206 				logger.debug("[CLOSE]::Resto de sesiones cerradas");
207 			}
208 	
209 			if (device.getModule() != null){
210 				device.getModule().finalize(); 
211 				logger.debug("[CLOSE]::Modulo PKCS11 descargado (" + device.getModuleName() + ")");
212 			}
213 			
214 			//-- Eliminar provider de SUN
215 			if (keystore != null) {
216 				logger.debug("[CLOSE]::Eliminando el provider de SUN");
217 				keystore = null;
218 //				((sun.security.pkcs11.SunPKCS11)Security.getProvider(sunProviderName)).logout();
219 				Security.removeProvider(sunProviderName);
220 				logger.debug("[CLOSE]::Eliminado el provider de SUN");
221 			}
222 			
223 			logger.debug("Dispositivo cerrado correctamente");
224 		} catch (Throwable e) {
225 			logger.info("Excepción durante cierre de dispositivo. Ignorando...", e);
226 		}
227 		logger.debug("Cerrando dispositivo...OK");
228 	}
229 	
230 	/**
231 	 * Método que obtiene información de los dispositivos conectados para una fabricante PKCS#11.
232 	 * 
233 	 * @param manufacturer Fabricante del dispositivo
234 	 * 
235 	 * @return Lista de objetos {@link es.accv.arangi.base.device.model.Pkcs11Device Pkcs11Device} 
236 	 * 	con	información de cada uno de los dispositivos encontrados
237 	 * @throws OpeningDeviceException Errores accediendo a los dispositivos
238 	 * @throws LoadingObjectException Errores obteniendo la información propia del dispositivo
239 	 * @throws SearchingException Errores obteniendo los certificados de los dispositivos
240 	 * @throws IAIKDLLNotFoundException No es posible cargar la DLL de IAIK, por 
241 	 * 	lo que no se puede trabajar con dispositivos PKCS#11
242 	 */
243 	public static List<Pkcs11Device> getConnectedDevices (Pkcs11Manufacturer manufacturer) throws OpeningDeviceException, LoadingObjectException, SearchingException, IAIKDLLNotFoundException {
244 		
245 		logger.debug("[Pkcs11Manager.getConnectedDevices]::Entrada::" + manufacturer.getManufacturerName());
246 		
247 		//-- Llamada al método que obtiene la información
248 		return getConnectedDevices(new Pkcs11Manufacturer[] { manufacturer });
249 		
250 	}
251 	
252 	/**
253 	 * Cambia el PIN de un dispositivo PKCS#11
254 	 * 
255 	 * @param manager Manager del dispositivo PKCS#11
256 	 * @param newpin Nuevo PIN
257 	 * @throws SavingObjectException Error cambiando el PIN
258 	 */
259 	public static void changePin(AbstractPkcs11Manager manager, String newpin) throws SavingObjectException {
260 		logger.debug("Cambiando pin...");
261 		
262 		//-- Comprobar que el PIN no es nulo
263 		if (newpin == null || newpin.equals("")) {
264 			logger.info("[AbstractPkcs11Manager.changePin]::El PIN es nulo o está vacío");
265 			throw new SavingObjectException ("El PIN es nulo o está vacío");
266 		}
267 		
268 		//-- Cambiamos pin
269 		try {
270 			manager.getDevice().getSession().setPIN(manager.pin.toCharArray(), newpin.toCharArray());
271 		} catch (TokenException e) {
272 			logger.info ("[AbstractPkcs11Manager.changePin]::No es posible cambiar el PIN", e);
273 			throw new SavingObjectException ("No es posible cambiar el PIN", e);
274 		} 
275 		logger.debug("PIN cambiado");
276 		
277 	}
278 	
279 	/**
280 	 * Realiza un formateado del dispositivo
281 	 * 
282 	 * @param device Dispositivo a formatear
283 	 * @param puk PUK del dispositivo
284 	 * @param newPin Nuevo pin del dispositivo tras la inicialización
285 	 * @param newLabel Nueva etiqueta del dispositivo formateado
286 	 * @throws FormatException Errores durante la inicialización del dispositivo
287 	 */
288 	public static void format (Pkcs11Device device, String puk, String newPin, String newLabel)  throws FormatException {
289 
290 		logger.debug ("[Pkcs11Manager.format]::Entrada");
291 		
292 		//-- Cerrar las sesiones abiertas
293 		logger.debug ("[Pkcs11Manager.format]::Cerrando las sesiones");
294 		try {
295 			device.getToken().closeAllSessions();
296 			logger.debug ("[Pkcs11Manager.format]::Sesiones cerradas");
297 		} catch (TokenException e) {
298 			logger.info ("[Pkcs11Manager.format]::Error durante el proceso de cerrado previo de las sesiones", e);
299 			throw new FormatException("Error durante el proceso de cerrado previo de las sesiones", e);
300 		}
301 
302 		//-- Formatear
303 		logger.debug ("[Pkcs11Manager.format]::Iniciando inicialización");
304 		try {
305 			device.getToken().initToken(puk.toCharArray(), newLabel);
306 			logger.debug ("[Pkcs11Manager.format]::Dispositivo inicializado");
307 		} catch (TokenException e) {
308 			logger.info ("[Pkcs11Manager.format]::Error durante el proceso de inicialización del dispositivo", e);
309 			throw new FormatException("Error durante el proceso de inicialización del dispositivo", e);
310 		} 
311 		
312 		//-- Inicializar el PIN
313 		try {
314 			
315 	        device.setSession(device.getToken().openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION, null, null));
316 	        device.getSession().login(Session.UserType.SO, puk.toCharArray());
317 	        device.getSession().initPIN(newPin.toCharArray());
318 	        device.getToken().closeAllSessions();
319 		} catch (TokenException e) {
320 			logger.info ("[Pkcs11Manager.format]::Error durante el proceso de inicialización del PIN tras el formateo del dispositivo", e);
321 			throw new FormatException("Error durante el proceso de inicialización del PIN tras el formateo del dispositivo", e);
322 		} 
323 		
324 		//-- Finalizar el módulo
325 		if (device.getModule() != null){
326 			try {
327 				device.getModule().finalize();
328 			} catch (Throwable e) {
329 				logger.info ("[Pkcs11Manager.format]::Error durante el proceso de finalización del módulo", e);
330 			} 
331 		}
332 	}
333 	
334 	/* (non-Javadoc)
335 	 * @see es.accv.arangi.base.device.DeviceManager#isAliasFree(java.lang.String)
336 	 */
337 	public boolean isAliasFree(String alias) throws SearchingException{
338 		boolean isFree = false;
339 		X509Certificate cert = getCertificate(alias);
340 		java.security.PrivateKey privateKey;
341 		try {
342 			privateKey = getPrivateKey(alias);
343 		} catch (LoadingObjectException e) {
344 			logger.info("[KeyStoreManager.isAliasFree]::No se puede determinar si existe una clave privada en el alias '" + alias + "' del dispositivo.", e);
345 			throw new SearchingException ("No se puede determinar si existe una clave privada en el alias '" + alias + "' del dispositivo.", e);
346 		}
347 		java.security.PublicKey publicKey;
348 		try {
349 			publicKey = getPublicKey(alias);
350 		} catch (LoadingObjectException e) {
351 			logger.info("[KeyStoreManager.isAliasFree]::No se puede determinar si existe una clave pública en el alias '" + alias + "' del dispositivo.", e);
352 			throw new SearchingException ("No se puede determinar si existe una clave pública en el alias '" + alias + "' del dispositivo.", e);
353 		}
354 		if (cert == null && privateKey == null && publicKey == null) isFree = true;
355 
356 		return isFree;
357 	}
358 
359 	/* (non-Javadoc)
360 	 * @see es.accv.arangi.base.device.DeviceManager#generateKeyPair(java.lang.String)
361 	 */
362 	public KeyPair generateKeyPair(String label) throws KeyPairException, AliasNotFreeException {
363 		return generateKeyPair(label, Util.DEFAULT_KEY_LENGTH);
364 	}
365 	
366 	/*
367 	 * (non-Javadoc)
368 	 * @see es.accv.arangi.base.device.DeviceManager#generateKeyPair(java.lang.String, int)
369 	 */
370 	public KeyPair generateKeyPair(String label, int keySize) throws KeyPairException, AliasNotFreeException {
371 		logger.debug("Generando par de claves...");
372 
373 		//-- Comprobamos si existen objetos con el label 'label"
374 		try {
375 			if (!isAliasFree(label)){
376 				logger.debug("El alias '" + label + "' ya existe en el KeyStore y no puede ser utilizado");
377 				throw new AliasNotFreeException("El alias '" + label + "' ya existe en el KeyStore y no puede ser utilizado");
378 			}
379 		} catch (SearchingException e) {
380 			logger.info("[KeyStoreManager.generateKeyPair]::No se puede determinar si ya existe un alias '" + label + "' en el dispositivo.", e);
381 			throw new AliasNotFreeException ("No se puede determinar si ya existe un alias '" + label + "' en el dispositivo.", e);
382 		}
383 		
384 		//-- Generamos el par de claves
385 		iaik.pkcs.pkcs11.objects.KeyPair kp = Pkcs11Util.generateKeyPair(device.getSession(), device.getToken(), keySize, NUM_RETRIES, label);
386 		logger.debug("Generando par...OK");
387 		logger.debug("Pasando par de claves de IAIK a SUN...");
388 		KeyPair rsaKeyPair = Pkcs11Util.iakKeyPairToSun(kp);
389 		logger.debug("Pasando par de claves de IAIK a SUN...OK");
390 
391 		logger.debug("Generando par de claves...OK");
392 		return rsaKeyPair;
393 	}
394 
395 	/* (non-Javadoc)
396 	 * @see es.accv.arangi.base.device.DeviceManager#generatePKCS10(java.lang.String, java.lang.String, java.security.KeyPair)
397 	 */
398 	public byte[] generatePKCS10(String subjectDN, String subjectAlternativeDN, KeyPair rsaKeyPair) {
399 		logger.debug("Generando PKCS#10...");
400 		
401 		//-- Construimos la instancia de CertificationRequest
402 		CertificationRequest cr = getCertificationRequest(device.getSession(), rsaKeyPair, subjectDN, subjectAlternativeDN);
403 		logger.debug("\n\n=========" + ASN1Dump.dumpAsString(cr) + "\n=========\n\n");
404 		logger.debug("CertificationRequest creada. dn: " + cr.getCertificationRequestInfo().getSubject().toString());
405 		logger.debug("Generando PKCS#10...OK");
406 		try {
407 			return cr.getEncoded(ASN1Encoding.DER);
408 		} catch (IOException e) {
409 			logger.info("[KeyStoreManager.generatePKCS10]::Error codificando el objeto PKCS#10", e);
410 			return null;
411 		}
412 	}
413 
414 	/* (non-Javadoc)
415 	 * @see es.accv.arangi.base.device.DeviceManager#changeLabel(java.lang.String, java.lang.String)
416 	 */
417 	public void changeAlias(String oldLabel, String newLabel) throws SearchingException, AliasNotFoundException, AliasNotFreeException, SavingObjectException{
418 		logger.debug("Renombrando objetos ``" + oldLabel + " ´´ a ``" + newLabel + " ´´...");
419 		
420 		//-- Comprobamos si existen objetos con el label ``oldLabel" 
421 		try {
422 			if (isAliasFree (oldLabel)){
423 				logger.debug("El alias '" + oldLabel + "' no existe en el KeyStore");
424 				throw new AliasNotFoundException ("El alias '" + oldLabel + "' no existe en el KeyStore");
425 			}
426 		} catch (SearchingException e) {
427 			logger.info("[KeyStoreManager.changeAlias]::No se puede determinar si existe un alias '" + oldLabel + "' en el dispositivo.", e);
428 			throw new AliasNotFoundException ("No se puede determinar si existe un alias '" + oldLabel + "' en el dispositivo.", e);
429 		}
430 		
431 		//-- Comprobamos si existen objetos con el label ``newLabel"
432 		try {
433 			if (!isAliasFree(newLabel)){
434 				logger.debug("El alias '" + newLabel + "' ya existe en el KeyStore y no puede ser utilizado");
435 				throw new AliasNotFreeException("El alias '" + newLabel + "' ya existe en el KeyStore y no puede ser utilizado");
436 			}
437 		} catch (SearchingException e) {
438 			logger.info("[KeyStoreManager.changeAlias]::No se puede determinar si ya existe un alias '" + newLabel + "' en el dispositivo.", e);
439 			throw new AliasNotFreeException ("No se puede determinar si ya existe un alias '" + newLabel + "' en el dispositivo.", e);
440 		}
441 		
442 		Pkcs11Util.changeLabel(device.getModule(), device.getSession(), oldLabel, newLabel);
443 		logger.debug("Renombrando objetos...OK");
444 	}
445 	
446 	/*
447 	 * (non-Javadoc)
448 	 * @see es.accv.arangi.base.device.DeviceManager#changePin(java.lang.String)
449 	 */
450 	public void changePin(String newpin) throws SavingObjectException, OpeningDeviceException {
451 		logger.debug("Cambiando pin...");
452 		
453 		//-- Cambiar el PIN
454 		AbstractPkcs11Manager.changePin(this, newpin);
455 		
456 		//-- Cerramos las sesiones abiertas dispositivo
457 		try {
458 			if (device.getSession() != null){
459 				device.getSession().closeSession();
460 				logger.debug("Sesión cerrada");
461 			}
462 			
463 			if (device.getToken() != null){
464 				device.getToken().closeAllSessions();
465 				logger.debug("Resto de sesiones cerradas");
466 			}
467 			
468 		} catch (TokenException e) {
469 			logger.info ("[Pkcs11Manager.changePin]::No se han podido cerrar las sesiones abiertas en el dispositivo tras el " +
470 					"cambio de PIN", e);
471 			throw new SavingObjectException("No se han podido cerrar las sesiones abiertas en el dispositivo tras el " +
472 					"cambio de PIN", e);
473 		} 
474 		
475 		//-- Lo abrimos con el nuevo pin
476 		try {
477 			this.device = this.device.getManufacturer().open(this.device, newpin, this.openWithPuk);
478 		} catch (IncorrectPINException e) {
479 			//-- No se dará porque acabamos de cambiar el PIN
480 			logger.info ("[Pkcs11Manager.changePin]::No se ha podido abrir una nueva sesión con el nuevo PIN", e);
481 		} catch (LockedPINException e) {
482 			//-- No se dará porque acabamos de cambiar el PIN y no estaba bloqueado
483 			logger.info ("[Pkcs11Manager.changePin]::El nuevo PIN está bloqueado en el dispositivo", e);
484 		} catch (IncorrectPUKException e) {
485 			//-- No se va a dar el caso ya que no se abre con PUK
486 		}
487 		
488 		logger.debug("Cambiando pin...OK");
489 	}
490 	
491 	/* (non-Javadoc)
492 	 * @see es.accv.arangi.base.device.DeviceManager#getCertificates(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
493 	 */
494 	public List<X509Certificate> getCertificates(String findInAlias, String findInSubjectDn, String findInIssuerDn, String findSerialNumber) throws SearchingException {
495 
496 		logger.debug("[Pkcs11Manager.getCertificates]::Entrada::" + Arrays.asList(new Object [] { findInAlias, findInSubjectDn, findInIssuerDn, findSerialNumber }));
497 		
498 		List<Object> objectList = new ArrayList<Object>();
499 		List<X509Certificate> result = new ArrayList<X509Certificate>();
500 		X509PublicKeyCertificate template = new X509PublicKeyCertificate();
501 		try {
502 			objectList = Pkcs11Util.findAllObjects(device.getSession(), template);
503 			logger.debug("Nº certificados en tarjeta: " + objectList.size());
504 		} catch (SearchingException e) {
505 			logger.info("[Pkcs11Manager.getCertificates]::ERROR::" + e.getMessage(), e);
506 			throw e;
507 		}
508 		
509 		//-- Cogemos todos los certificados y vamos quitando los que no cumplan
510 		//-- alguno de los criterios proporcionados
511 		X509PublicKeyCertificate iaikCert = null;
512 		X509Certificate x509cert = null;
513 		for (int i = 0; i < objectList.size(); i++) {
514 			iaikCert = (X509PublicKeyCertificate)objectList.get(i);
515 			try {
516 				x509cert = Util.getCertificate(iaikCert.getValue().getByteArrayValue());
517 			} catch (Exception e) {
518 				continue;
519 			}
520 
521 			//-- Búsqueda en Label
522 			if (findInAlias != null){
523 				String label = iaikCert.getLabel().toString();
524 				if (label != null && label.indexOf(findInAlias) == -1){
525 					logger.debug("Quitando cert de label:" + label);
526 					continue;
527 				}
528 			}
529 	
530 			//-- Búsqueda en SubjectDN
531 			if (findInSubjectDn != null){
532 				String subjectDn = x509cert.getSubjectDN().toString();
533 				if (subjectDn != null && subjectDn.indexOf(findInSubjectDn) == -1){
534 					logger.debug("Quitando cert de SubjectDN:" + subjectDn);
535 					continue;
536 				}
537 			}
538 			
539 			//-- Búsqueda en IssuerDN
540 			if (findInIssuerDn != null){
541 				String issuerDn = x509cert.getIssuerDN().getName();
542 				logger.debug("Encontrado issuerDn: " + issuerDn);
543 				if (issuerDn != null && issuerDn.indexOf(findInIssuerDn) == -1){
544 					logger.debug("Quitando cert de IssuerDN:" + issuerDn);
545 					continue;
546 				}
547 			}
548 
549 			//-- Búsqueda en Nº de serie
550 			if (findSerialNumber != null){
551 				String serialNumber = x509cert.getSerialNumber().toString(16);
552 				if (serialNumber != null && !serialNumber.equalsIgnoreCase(findSerialNumber)){
553 					logger.debug("Quitando cert con Nº serie:" + serialNumber);
554 					continue;
555 				}
556 			}
557 			
558 			//-- >Todo ok -> añado el certificado a la lista
559 			result.add(x509cert);
560 		}
561 		logger.debug("Nº certificados en tarjeta COINCIDENTES: " + result.size());
562 		logger.debug("getCertificates...OK");
563 		return result;
564 	}
565 	
566 	/*
567 	 * (non-Javadoc)
568 	 * @see es.accv.arangi.base.device.DeviceManager#getCertificate(java.lang.String)
569 	 */
570 	public X509Certificate getCertificate(String alias) throws SearchingException {
571 		logger.debug ("[Pkcs11Manager.getCertificate]::Obteniendo el certificado en '" + alias + "'");
572 
573 		//-- Obtener el certificado
574 		X509PublicKeyCertificate iaikCert;
575 		try {
576 			iaikCert = getIAIKCertificate(alias);
577 		} catch (LoadingObjectException e) {
578 			logger.info("[Pkcs11Manager.getCertificate]::Error buscando el certificado para el alias '" + alias + "'", e);
579 			throw new SearchingException ("Error buscando el certificado para el alias '" + alias + "'", e);
580 		}
581 		if (iaikCert != null) {
582 			//-- Pasamos a X509Certificate de Sun
583 			try {
584 				logger.debug("Se va a devolver una clave pública para el alias '" + alias + "'");
585 				return Util.getCertificate(iaikCert.getValue().getByteArrayValue());
586 			} catch (Exception e) {
587 				logger.info("[Pkcs11Manager.getCertificate]::Error transformando el certificado de IAIK a X509Certificate de Sun", e);
588 				throw new SearchingException ("Error transformando el certificado de IAIK a X509Certificate de Sun", e);
589 			}
590 		}
591 		
592 		//-- Si estamos aquí es porque no se ha obtenido ningún certificado
593 		logger.debug("No se ha encontrado el certificado para el alias '" + alias + "'");
594 		return null;
595 	}
596 
597 
598 	
599 	/*
600 	 * (non-Javadoc)
601 	 * @see es.accv.arangi.base.device.DeviceManager#importCertificate(java.security.cert.X509Certificate, java.lang.String)
602 	 */
603 	public void importCertificate(X509Certificate cert, String theLabel) throws DeviceFullException, CertificateInvalidException, SavingObjectException  {
604 		importCertificate(cert, theLabel, true);
605 	}
606 
607 	/**
608 	 * Importa un certificado en la tarjeta.
609 	 * 
610 	 * @param cert Certificado a importar
611 	 * @param theLabel Alias donde se realizará la importación
612 	 * @param deletePublicKey Tras la importación se elimina o no la clave pública
613 	 * @throws DeviceFullException Dispositivo lleno
614 	 * @throws CertificateInvalidException Certificado no válido
615 	 * @throws SavingObjectException Error importando el certificado
616 	 */
617 	public void importCertificate(X509Certificate cert, String theLabel, boolean deletePublicKey) throws DeviceFullException, CertificateInvalidException, SavingObjectException  {
618 		logger.debug("Importando certificado...");
619 		logger.debug("Certificado: " + theLabel);
620 
621 	    //-- Validacion de espacio en tarjeta
622 	    if (!validateFreeMemory (device.getFreeMemory())) {
623 	    	logger.info ("[Pkcs11Manager.importCertificate]::La memoria de la tarjeta está llena.");
624 	    	throw new DeviceFullException("La memoria de la tarjeta está llena.");
625 	    }
626 		
627 	    //-- Importar
628 		Pkcs11Util.importX509Cert(device.getSession(), device.getToken(), cert, theLabel, deletePublicKey);
629 		logger.debug("Importando certificado...OK");
630 	}
631 
632 	/*
633 	 * (non-Javadoc)
634 	 * @see es.accv.arangi.base.device.DeviceManager#importAliasFromKeystore(java.io.InputStream, java.lang.String, java.lang.String, java.lang.String)
635 	 */
636 	public void importAliasFromKeystore(InputStream is, String password, String labelOrigen, String labelDestino) 
637 		throws DeviceFullException, DeviceNotFoundException, ReadingStreamException, AliasNotFoundException, LoadingObjectException, SavingObjectException, OpeningDeviceException, IncorrectPINException {
638 		
639 	    logger.debug("[Pkcs11Manager.importAliasFromKeystore]::Entrada::" + Arrays.asList(new Object[] {is, password, labelOrigen, labelDestino}));
640 		
641 		//-- Obtener el manager del keystore
642     	KeyStoreManager keystoreManager;
643 		keystoreManager = new KeyStoreManager (is, password);
644     	
645 		//-- Llamar al método
646 		importAliasFromKeystore(keystoreManager, labelOrigen, labelDestino);
647 	}
648 
649 	/*
650 	 * (non-Javadoc)
651 	 * @see es.accv.arangi.base.device.DeviceManager#importFromKeystore(es.accv.arangi.base.device.DeviceManager)
652 	 */
653 	public void importFromKeystore(DeviceManager deviceManager) throws DeviceFullException, DeviceNotFoundException, LoadingObjectException, SavingObjectException  {
654 		
655 	    logger.debug("[Pkcs11Manager.importAliasFromKeystore]::Entrada::" + Arrays.asList(new Object[] { deviceManager }));
656 
657 		//-- Llamar al método
658 		try {
659 			importAliasFromKeystore(deviceManager, null, null);
660 		} catch (AliasNotFoundException e) {
661 			//-- No se dará ya que no se hace la llamada con alias
662 		}
663 	    
664 	}
665 
666 	/*
667 	 * (non-Javadoc)
668 	 * @see es.accv.arangi.base.device.DeviceManager#importAliasFromKeystore(es.accv.arangi.base.device.DeviceManager, java.lang.String, java.lang.String)
669 	 */
670 	public void importAliasFromKeystore(DeviceManager deviceManager, String labelOrigen, String labelDestino)  
671 	throws DeviceFullException, DeviceNotFoundException, AliasNotFoundException, LoadingObjectException, SavingObjectException {
672 	    logger.debug("[Pkcs11Manager.importAliasFromKeystore]::Entrada::" + Arrays.asList(new Object[] {deviceManager, labelOrigen, labelDestino}));
673 
674 		//-- Verificaciones
675 	    if (deviceManager == null) {
676 	    	logger.info("[Pkcs11Manager.importAliasFromKeystore]::El dispositivo origen es nulo");
677 	    	throw new DeviceNotFoundException("El dispositivo origen es nulo.");
678 	    }
679 	    
680 	    // Comprobar que el label a importar existe en el dispositivo
681 	    try {
682 			if (labelOrigen != null && deviceManager.isAliasFree(labelOrigen)) {
683 				logger.info ("[Pkcs11Manager.importAliasFromKeystore]::El alias '" + labelOrigen + "' no existe en el dispositivo origen de la importación.");
684 				throw new AliasNotFoundException("El alias '" + labelOrigen + "' no existe en el dispositivo origen de la importación.");
685 			}
686 		} catch (SearchingException e) {
687 			logger.info("[KeyStoreManager.importAliasFromKeystore]::No se puede determinar si existe un alias '" + labelOrigen + "' en el dispositivo origen.", e);
688 			throw new AliasNotFoundException ("No se puede determinar si existe un alias '" + labelOrigen + "' en el dispositivo origen.", e);
689 		}
690 	    
691 	    // -- Validacion de espacio en tarjeta
692 	    if (!validateFreeMemory (device.getFreeMemory())) {
693 	    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::La memoria de la tarjeta está llena.");
694 	    	throw new DeviceFullException("La memoria de la tarjeta está llena.");
695 	    }
696 
697 	    //-- Iniciamos el proceso de importacion: si labelOrigen es nulo importamos todo	    
698 	    String[] aliasToImport;
699 	    if (labelOrigen != null) {
700 	    	aliasToImport = new String [] {labelOrigen};
701 	    } else {
702 	    	try {
703 				aliasToImport = deviceManager.getAliasNamesList();
704 			} catch (SearchingException e) {
705 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::No se ha podido leer la información del dispositivo origen.", e);
706 		    	throw new LoadingObjectException("No se ha podido leer la información del dispositivo origen.", e);
707 			}
708 	    }
709     	
710 	    //-- Recorrer todos los elementos e ir importando
711     	for (int i = 0; i < aliasToImport.length; i++) {
712 			String alias = aliasToImport [i];
713 			
714 			//-- Buscar alias destino
715 			String nombreEnDestino = labelDestino;
716 			if (labelOrigen != null && labelDestino == null) {
717 				nombreEnDestino = labelOrigen;
718 			}
719 			if (labelOrigen == null) {
720 				nombreEnDestino = alias;
721 			}
722 			
723 			//-- Si el alias ya existe buscar otro nombre
724 			int aliasNumber = 0;
725 			while (true) {
726 				try {
727 					if (isAliasFree(nombreEnDestino)) {
728 						break;
729 					}
730 				} catch (SearchingException e) {
731 					logger.debug("[KeyStoreManager.importAliasFromKeystore]::No se puede determinar si existe un alias '" + nombreEnDestino + "' en el dispositivo.", e);
732 				}
733 				nombreEnDestino += aliasNumber;
734 				aliasNumber++;
735 			}
736 			
737 		    try {
738 		    	
739 				//-- Obtener el certificado
740 				Certificate userCertificate = new Certificate(deviceManager.getCertificate (alias));
741 				
742 				//-- Obtener el objectID que identificará tanto a la clave privada como al certificado en la tarjeta
743 				byte[] newObjectID = getObjectID (userCertificate);
744 				
745 				//-- Obtener clave privada, si existe, y comprobar que sea RSA
746 				java.security.PrivateKey jcaPrivateKey = (java.security.PrivateKey) deviceManager.getPrivateKey(alias);
747 			    if (jcaPrivateKey != null && jcaPrivateKey.getAlgorithm().equals("RSA")) {
748 			    	
749 			    	//-- Importar la clave al dispositivo
750 					logger.debug("Creando el objeto clave privada en la tarjeta... ");
751 			    	PrivateKey iaikPrivateKey = getIaikPrivateKey (jcaPrivateKey, nombreEnDestino, newObjectID, userCertificate.toX509Certificate(), ((java.security.interfaces.RSAPublicKey) userCertificate.getPublicKey()).getPublicExponent());
752 			    	device.getSession().createObject(iaikPrivateKey);
753 					logger.debug("Creado el objeto clave privada en la tarjeta... ");
754 			    	
755 			    }
756 
757 				logger.debug("Creando el objeto certificado en la tarjeta... ");
758 
759 				// create certificate object template
760 				X509PublicKeyCertificate pkcs11X509PublicKeyCertificate = new X509PublicKeyCertificate();
761 
762 				pkcs11X509PublicKeyCertificate.getToken().setBooleanValue(Boolean.TRUE);
763 				pkcs11X509PublicKeyCertificate.getPrivate().setBooleanValue(Boolean.FALSE);
764 				pkcs11X509PublicKeyCertificate.getLabel().setCharArrayValue(nombreEnDestino.toCharArray());
765 				pkcs11X509PublicKeyCertificate.getSubject().setByteArrayValue(userCertificate.toX509Certificate().getSubjectX500Principal().getEncoded());
766 				pkcs11X509PublicKeyCertificate.getId().setByteArrayValue(newObjectID);
767 				pkcs11X509PublicKeyCertificate.getIssuer().setByteArrayValue(userCertificate.toX509Certificate().getIssuerX500Principal().getEncoded());
768 
769 				// Netscape deviates from the standard here, for use with Netscape rather
770 				// use
771 //				pkcs11X509PublicKeyCertificate.getSerialNumber().setByteArrayValue(userCertificate.getSerialNumber().toByteArray());
772 				pkcs11X509PublicKeyCertificate.getValue().setByteArrayValue(userCertificate.toDER());
773 
774 				// logger.debug(pkcs11X509PublicKeyCertificate);
775 				device.getSession().createObject(pkcs11X509PublicKeyCertificate);
776 
777 		    } catch (SearchingException e) {
778 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::Error al obtener el certificado para el alias '" + alias + "'", e);
779 		    	throw new SavingObjectException("Error al obtener el certificado para el alias '" + alias + "'", e);
780 			} catch (CertificateEncodingException e) {
781 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::Ha ocurrido una excepción manejando el certificado", e);
782 		    	throw new SavingObjectException("Ha ocurrido una excepción manejando el certificado", e);
783 			} catch (InitDocumentException e) {
784 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::No se puede obtener un ID para el dispositivo en base al certificado", e);
785 		    	throw new SavingObjectException("No se puede obtener un ID para el dispositivo en base al certificado", e);
786 			} catch (HashingException e) {
787 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::No se puede obtener un ID para el dispositivo en base al certificado", e);
788 		    	throw new SavingObjectException("No se puede obtener un ID para el dispositivo en base al certificado", e);
789 			} catch (LoadingObjectException e) {
790 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::Error obteniendo la clave privada del alias '" + alias + "'", e);
791 		    	throw new SavingObjectException("Error obteniendo la clave privada del alias '" + alias + "'", e);
792 			} catch (TokenException e) {
793 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::No se puede guardar el certificado o no se puede asociar a una clave privada existente " +
794 		    			"para el alias '" + alias + "'", e);
795 		    	throw new SavingObjectException("No se puede guardar el certificado o no se puede asociar a una clave privada existente " +
796 		    			"para el alias '" + alias + "'", e);
797 			} catch (NormalizeCertificateException e) {
798 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::Error normalizando el certificado del alias '" + alias + "'", e);
799 		    	throw new SavingObjectException("Error normalizando el certificado del alias '" + alias + "'", e);
800 			} catch (NoSuchAlgorithmException e) {
801 		    	logger.info ("[Pkcs11Manager.importAliasFromKeystore]::No existe el algoritmo " + HashingAlgorithm.getDefault(), e);
802 		    	throw new SavingObjectException("No existe el algoritmo " + HashingAlgorithm.getDefault(), e);
803 			} 
804 		}
805     	
806     	if (this.deleteOrphans) {
807 	    	//-- Eliminar huerfanos y objetos extraños (GyD)
808 	    	Pkcs11Util.deleteOrphans(device.getSession());
809     	}
810 	}
811 
812 	/*
813 	 * (non-Javadoc)
814 	 * @see es.accv.arangi.base.device.DeviceManager#decrypt(byte[], java.lang.String, java.lang.String)
815 	 */
816 	public byte[] decrypt(byte[] encryptedDocument, String label, String cipherAlgorithm) throws AliasNotFoundException, LoadingObjectException, CipherException {
817 		
818 		logger.debug("[Pkcs11Manager.decrypt]::Entrada:: " + Arrays.asList(new Object[] { encryptedDocument, label, cipherAlgorithm }));
819 		
820 		//-- Comprobar que la etiqueta existe
821 		try {
822 			if (isAliasFree(label)) {
823 				logger.info("[Pkcs11Manager.decrypt]::La etiqueta '" + label + "' no se encuentra en el dispositivo");
824 				throw new AliasNotFoundException ("La etiqueta '" + label + "' no se encuentra en el dispositivo");
825 			}
826 		} catch (SearchingException e) {
827 			logger.debug("[Pkcs11Manager.decrypt]::No se puede determinar si existe un alias '" + label + "' en el dispositivo.", e);		
828 			throw new AliasNotFoundException ("No se puede determinar si existe un alias '" + label + "' en el dispositivo.", e);
829 		}
830 		
831 		//-- Comprobar que existe el mecanismo
832 		Mechanism cipherMechanism;
833 		try {
834 			cipherMechanism = getMechanism (cipherAlgorithm);
835 			if (cipherMechanism == null) {
836 				logger.info("[Pkcs11Manager.decrypt]::Arangi no acepta el algoritmo " + cipherAlgorithm + " para cifrar en el dispositivo");
837 				throw new CipherException("Arangi no acepta el algoritmo " + cipherAlgorithm + " para cifrar en el dispositivo");
838 			}
839 			List supportedMechanisms = Arrays.asList(device.getToken().getMechanismList());
840 			if (!supportedMechanisms.contains(cipherMechanism)) {
841 				logger.info("[Pkcs11Manager.decrypt]::El dispositivo no acepta el encriptado " + cipherAlgorithm);
842 				throw new CipherException("El dispositivo no acepta el encriptado " + cipherAlgorithm);
843 			} else {
844 				MechanismInfo rsaMechanismInfo = device.getToken().getMechanismInfo(cipherMechanism);
845 				if (!rsaMechanismInfo.isSign()) {
846 					logger.info("[Pkcs11Manager.decrypt]::El mechanismo " + cipherAlgorithm + " no es aceptado por el dispositivo para cifrar");
847 					throw new CipherException( "El mechanismo " + cipherAlgorithm + " no es aceptado por el dispositivo para cifrar");
848 				}
849 			}
850 		} catch (TokenException e1) {
851 			logger.info("[Pkcs11Manager.decrypt]::No se pueden obtener los mecanismos de cifrado del dispositivo", e1);
852 			throw new CipherException("No se pueden obtener los mecanismos de cifrado del dispositivo", e1);
853 		}
854 		
855 		//-- Obtener la clave privada
856 		java.security.PrivateKey privateKey = getPrivateKey(label);
857 		if (privateKey == null) {
858 			logger.info("[Pkcs11Manager.decrypt]::No existe una clave privada asociada al alias '" + label + "'");
859 			throw new LoadingObjectException("No existe una clave privada asociada al alias '" + label + "'");
860 		}
861 		
862 	    //-- Desencriptar
863 		byte[] desencriptado = null;
864 	    try {
865 	    	Cipher cipher = Cipher.getInstance(cipherAlgorithm, keystore.getProvider());
866 	    	cipher.init(Cipher.DECRYPT_MODE, privateKey);
867 	    	desencriptado = cipher.doFinal(encryptedDocument);
868 		} catch (NoSuchAlgorithmException e) {
869 			logger.info("[KeyStoreManager.encrypt]::No existe el algoritmo de cifrado '" + cipherAlgorithm + "'", e);
870 			throw new CipherException ("No existe el algoritmo de cifrado '" + cipherAlgorithm + "'", e);
871 		} catch (InvalidKeyException e) {
872 			logger.info("[KeyStoreManager.encrypt]::La clave privada no es válida", e);
873 			throw new CipherException ("La clave privada no es válida", e);
874 		} catch (IllegalBlockSizeException e) {
875 			logger.info("[KeyStoreManager.encrypt]::El tamaño de la información de un bloque de cifrado es incorrecta", e);
876 			throw new CipherException ("El tamaño de la información de un bloque de cifrado es incorrecta", e);
877 		} catch (BadPaddingException e) {
878 			logger.info("[KeyStoreManager.encrypt]::El relleno de la información no es el adecuado para el algoritmo de relleno", e);
879 			throw new CipherException ("El relleno de la información no es el adecuado para el algoritmo de relleno", e);
880 		} catch (NoSuchPaddingException e) {
881 			logger.info("[KeyStoreManager.encrypt]::No existe el algoritmo de relleno", e);
882 			throw new CipherException ("No existe el algoritmo de relleno", e);
883 		} 
884     	
885 		logger.debug("Desencriptando...OK");
886     	return desencriptado;
887 	}
888 
889 	/*
890 	 * (non-Javadoc)
891 	 * @see es.accv.arangi.base.device.DeviceManager#encrypt(byte[], java.lang.String, java.lang.String)
892 	 */
893 	public byte[] encrypt(byte[] document, String label, String cipherAlgorithm) throws AliasNotFoundException, LoadingObjectException, CipherException {
894 		
895 		logger.debug("Encriptando:: " + Arrays.asList(new Object[] { document, label, cipherAlgorithm }));
896 		
897 		//-- Comprobar que la etiqueta existe
898 		try {
899 			if (isAliasFree(label)) {
900 				logger.info("[Pkcs11Manager.encrypt]::La etiqueta '" + label + "' no se encuentra en el dispositivo");
901 				throw new AliasNotFoundException ("La etiqueta '" + label + "' no se encuentra en el dispositivo");
902 			}
903 		} catch (SearchingException e) {
904 			logger.debug("[KeyStoreManager.encrypt]::No se puede determinar si existe un alias '" + label + "' en el dispositivo.", e);		
905 			throw new AliasNotFoundException ("No se puede determinar si existe un alias '" + label + "' en el dispositivo.", e);
906 		}
907 		
908 		//-- Comprobar que existe el mecanismo
909 		Mechanism cipherMechanism;
910 		try {
911 			cipherMechanism = getMechanism (cipherAlgorithm);
912 			if (cipherMechanism == null) {
913 				logger.info("[Pkcs11Manager.encrypt]::Arangi no acepta el algoritmo " + cipherAlgorithm + " para cifrar en el dispositivo");
914 				throw new CipherException("Arangi no acepta el algoritmo " + cipherAlgorithm + " para cifrar en el dispositivo");
915 			}
916 			List supportedMechanisms = Arrays.asList(device.getToken().getMechanismList());
917 			if (!supportedMechanisms.contains(cipherMechanism)) {
918 				logger.info("[Pkcs11Manager.encrypt]::El dispositivo no acepta el encriptado " + cipherAlgorithm);
919 				throw new CipherException("El dispositivo no acepta el encriptado " + cipherAlgorithm);
920 			} else {
921 				MechanismInfo rsaMechanismInfo = device.getToken().getMechanismInfo(cipherMechanism);
922 				if (!rsaMechanismInfo.isSign()) {
923 					logger.info("[Pkcs11Manager.encrypt]::El mechanismo " + cipherAlgorithm + " no es aceptado por el dispositivo para cifrar");
924 					throw new CipherException( "El mechanismo " + cipherAlgorithm + " no es aceptado por el dispositivo para cifrar");
925 				}
926 			}
927 		} catch (TokenException e1) {
928 			logger.info("[Pkcs11Manager.encrypt]::No se pueden obtener los mecanismos de cifrado del dispositivo", e1);
929 			throw new CipherException("No se pueden obtener los mecanismos de cifrado del dispositivo", e1);
930 		}
931 		
932 		//-- Obtener la clave
933 		java.security.PublicKey publicKey = getPublicKey(label);
934 		
935 		//-- Encriptar
936 		return encrypt(document, publicKey, cipherAlgorithm);
937 		
938 	}
939 
940 	/**
941 	 * Cifra un documento con la clave privada pasada como parámetro.
942 	 * 
943 	 * @param document Documento a cifrar
944 	 * @param key Clave privada que cifrará el documento
945 	 * @param cipherAlgorithm Algoritmo de cifrado 
946 	 * @return Documento cifrado
947 	 * @throws CipherException Error durante el cifrado
948 	 */
949 	public byte[] encrypt(byte[] document, java.security.PrivateKey key, String cipherAlgorithm) throws CipherException {
950 		logger.debug ("[KeyStoreManager.encrypt]::Entrada::" + Arrays.asList(new Object[] { document, key, cipherAlgorithm }));
951 		
952 		//-- Cifrar
953 		try {
954 			byte[] bytesSignature = null;
955         	int i=0;
956         	while (i<=NUM_RETRIES && bytesSignature==null) {
957         		try {
958 					Cipher cipher = Cipher.getInstance(cipherAlgorithm, keystore.getProvider());
959 					cipher.init(Cipher.ENCRYPT_MODE, key);
960 					bytesSignature = cipher.doFinal(document);
961 					logger.debug("[KeyStoreManager.encrypt]::Se ha completado el cifrado");
962         		} catch (RuntimeException e) {
963         			//-- Error al firmar, volver a intentar (probablemente problema con el provider de SUN)
964         			if (i == NUM_RETRIES) {
965         				logger.info("[XAdESSignature.signXAdES]::Runtime error realizando el cifrado", e);
966         				throw new CipherException ("Error interno del dispositivo durante el proceso de cifrado", e);
967         			}
968         		}
969         		i++;
970         	}
971         	
972 	        return bytesSignature;
973 	        
974 		} catch (NoSuchAlgorithmException e) {
975 			logger.info("[KeyStoreManager.encrypt]::No existe el algoritmo de cifrado '" + cipherAlgorithm + "'", e);
976 			throw new CipherException ("No existe el algoritmo de cifrado '" + cipherAlgorithm + "'", e);
977 		} catch (InvalidKeyException e) {
978 			logger.info("[KeyStoreManager.encrypt]::La clave privada no es válida", e);
979 			throw new CipherException ("La clave privada no es válida", e);
980 		} catch (IllegalBlockSizeException e) {
981 			logger.info("[KeyStoreManager.encrypt]::El tamaño de la información de un bloque de cifrado es incorrecta", e);
982 			throw new CipherException ("El tamaño de la información de un bloque de cifrado es incorrecta", e);
983 		} catch (BadPaddingException e) {
984 			logger.info("[KeyStoreManager.encrypt]::El relleno de la información no es el adecuado para el algoritmo de relleno", e);
985 			throw new CipherException ("El relleno de la información no es el adecuado para el algoritmo de relleno", e);
986 		} catch (NoSuchPaddingException e) {
987 			logger.info("[KeyStoreManager.encrypt]::No existe el algoritmo de relleno", e);
988 			throw new CipherException ("No existe el algoritmo de relleno", e);
989 		} 
990 	}
991 
992 	/*
993 	 * (non-Javadoc)
994 	 * @see es.accv.arangi.base.device.DeviceManager#signDocument(java.io.InputStream, java.lang.String)
995 	 */
996 	public byte[] signDocument(InputStream document, String label) throws AliasNotFoundException, HashingException, LoadingObjectException, SignatureException {
997 		return signDocument(document, label, DigitalSignatureAlgorithm.SHA1_RSA);
998 	}
999 
1000 	/*
1001 	 * (non-Javadoc)
1002 	 * @see es.accv.arangi.base.device.DeviceManager#signDocument(java.io.InputStream, java.lang.String, java.lang.String)
1003 	 */
1004 	public byte[] signDocument(InputStream document, String label,
1005 			String signatureAlgorithm) throws AliasNotFoundException, HashingException, LoadingObjectException, SignatureException {
1006 		
1007 		return signDocument (new InputStreamDocument (document), label, signatureAlgorithm);
1008 	}
1009 
1010 	/*
1011 	 * (non-Javadoc)
1012 	 * @see es.accv.arangi.base.device.DeviceManager#signDocument(es.accv.arangi.base.document.IDocument, java.lang.String)
1013 	 */
1014 	public byte[] signDocument(IDocument document, String label) throws AliasNotFoundException, HashingException, LoadingObjectException, SignatureException {
1015 		return signDocument(document, label, DigitalSignatureAlgorithm.SHA1_RSA);
1016 	}
1017 
1018 	/*
1019 	 * (non-Javadoc)
1020 	 * @see es.accv.arangi.base.device.DeviceManager#signDocument(es.accv.arangi.base.document.IDocument, java.lang.String, java.lang.String)
1021 	 */
1022 	public byte[] signDocument(IDocument document, String label, String signatureAlgorithm) 
1023 		throws AliasNotFoundException, HashingException, LoadingObjectException, SignatureException {
1024 		
1025 		logger.debug("[Pkcs11Manager.signDocument]::Entrada::" + Arrays.asList(new Object[] { document, label, signatureAlgorithm }));
1026 		
1027 		// Se obtiene el hash y se cifra. Se podría firmar directamente mediante un mecanismo, pero
1028 		// si el documento es grande la tarjeta acaba saturándose.
1029 		
1030 		//-- Obtener los altoritmos de hashing y firma
1031 		String hashingAlgorithm;
1032 		String encryptAlgorithm;
1033 		try {
1034 			hashingAlgorithm = DigitalSignatureAlgorithm.getHashingAlgorithm(signatureAlgorithm);
1035 			encryptAlgorithm = DigitalSignatureAlgorithm.getCipherAlgorithm(signatureAlgorithm);
1036 			logger.debug("[Pkcs11Manager.signDocument]::Algorimo de hashing: " + hashingAlgorithm + "::Algoritmo" +
1037 					" de encriptado: " + encryptAlgorithm);
1038 		} catch (NoSuchAlgorithmException e) {
1039 			logger.info("[Pkcs11Manager.signDocument]::El algoritmo de firma no existe en Arangi", e);
1040 			throw new SignatureException ("El algoritmo de firma no existe en Arangi", e);
1041 		}
1042 		
1043 		//-- Obtener el hash
1044 		byte[] hash = document.getHash(hashingAlgorithm);
1045 		
1046 		//-- Cifrar el hash
1047 		try {
1048 			return signBytesHash (hash, label, encryptAlgorithm);
1049 		} catch (CipherException e) {
1050 			logger.info("[Pkcs11Manager.signDocument]::No ha sido posible cifrar el hash para obtener la firma", e);
1051 			throw new SignatureException ("No ha sido posible cifrar el hash para obtener la firma", e);
1052 		}
1053 	}
1054 
1055 	/*
1056 	 * (non-Javadoc)
1057 	 * @see es.accv.arangi.base.device.DeviceManager#signHash(byte[], java.lang.String, java.lang.String)
1058 	 */
1059 	public byte[] signBytesHash(byte[] hash, String label) throws HashingException, AliasNotFoundException, LoadingObjectException, CipherException {
1060 		return signBytesHash(hash, label, CipherAlgorithm.RSA);
1061 	}
1062 
1063 	/*
1064 	 * (non-Javadoc)
1065 	 * @see es.accv.arangi.base.device.DeviceManager#signHash(byte[], java.lang.String, java.lang.String, java.lang.String)
1066 	 */
1067 	public byte[] signBytesHash(byte[] hash, String label, String cipherAlgorithm) 
1068 			throws HashingException, AliasNotFoundException, LoadingObjectException, CipherException {
1069 		
1070 		logger.debug("Firmando hash (=cifrando hash):: " + Arrays.asList(new Object[] { hash, label, cipherAlgorithm }));
1071 		
1072 		//-- Algoritmo de hashing
1073 		String hashingAlgorithm = HashingAlgorithm.getAlgorithmNameFromHash(hash);
1074 		
1075 		//-- Obtener el hash a cifrar
1076 		try {
1077 			hash = DeviceUtil.getSignData(new ObjectIdentifier(HashingAlgorithm.getOID(hashingAlgorithm)), hash);
1078 		} catch (IOException e) {
1079 			logger.info("[KeyStoreManager.signHash]::No es posible obtener el objeto DER que contiene el hash", e);
1080 			throw new HashingException ("No es posible obtener el objeto DER que contiene el hash", e);
1081 		} catch (NoSuchAlgorithmException e) {
1082 			logger.info("[KeyStoreManager.signHash]::El algoritmo de hashing '" + hashingAlgorithm + "' provoca una excepción", e);
1083 			throw new HashingException ("El algoritmo de hashing '" + hashingAlgorithm + "' provoca una excepción", e);
1084 		}
1085 		
1086 		//-- Comprobar que la etiqueta existe
1087 		try {
1088 			if (isAliasFree(label)) {
1089 				logger.info("[KeyStoreManager.signHash]::La etiqueta '" + label + "' no se encuentra en el dispositivo");
1090 				throw new AliasNotFoundException ("La etiqueta '" + label + "' no se encuentra en el dispositivo");
1091 			}
1092 		} catch (SearchingException e) {
1093 			logger.debug("[KeyStoreManager.signHash]::No se puede determinar si existe un alias '" + label + "' en el dispositivo.", e);		
1094 			throw new AliasNotFoundException ("No se puede determinar si existe un alias '" + label + "' en el dispositivo.", e);
1095 		}
1096 		
1097 		//-- Comprobar que existe el mecanismo
1098 		Mechanism cipherMechanism;
1099 		try {
1100 			cipherMechanism = getMechanism (cipherAlgorithm);
1101 			if (cipherMechanism == null) {
1102 				logger.info("[KeyStoreManager.signHash]::Arangi no acepta el algoritmo " + cipherAlgorithm + " para cifrar en el dispositivo");
1103 				throw new CipherException("Arangi no acepta el algoritmo " + cipherAlgorithm + " para cifrar en el dispositivo");
1104 			}
1105 			List supportedMechanisms = Arrays.asList(device.getToken().getMechanismList());
1106 			if (!supportedMechanisms.contains(cipherMechanism)) {
1107 				logger.info("[KeyStoreManager.signHash]::El dispositivo no acepta el encriptado " + cipherAlgorithm);
1108 				throw new CipherException("El dispositivo no acepta el encriptado " + cipherAlgorithm);
1109 			} else {
1110 				MechanismInfo rsaMechanismInfo = device.getToken().getMechanismInfo(cipherMechanism);
1111 				if (!rsaMechanismInfo.isSign()) {
1112 					logger.info("[KeyStoreManager.signHash]::El mechanismo " + cipherAlgorithm + " no es aceptado por el dispositivo para cifrar");
1113 					throw new CipherException( "El mechanismo " + cipherAlgorithm + " no es aceptado por el dispositivo para cifrar");
1114 				}
1115 			}
1116 		} catch (TokenException e1) {
1117 			logger.info("[KeyStoreManager.signHash]::No se pueden obtener los mecanismos de cifrado del dispositivo", e1);
1118 			throw new CipherException("No se pueden obtener los mecanismos de cifrado del dispositivo", e1);
1119 		}
1120 		
1121 		//-- Obtener la clave privada
1122 		java.security.PrivateKey privateKey = getPrivateKey(label);
1123 		if (privateKey == null) {
1124 			logger.info("[KeyStoreManager.signHash]::No existe una clave privada asociada al alias '" + label + "'");
1125 			throw new LoadingObjectException("No existe una clave privada asociada al alias '" + label + "'");
1126 		}
1127 		
1128 	    //-- Firmar (cifrar)
1129 		byte[] firma = encrypt(hash, privateKey, cipherAlgorithm);
1130     	
1131 		logger.debug("Firmando hash...OK");
1132     	return firma;
1133 	}
1134 
1135 	/*
1136 	 * (non-Javadoc)
1137 	 * @see es.accv.arangi.base.device.DeviceManager#deleteObjects(java.lang.String)
1138 	 */
1139 	public int deleteObjects(String label) throws DeletingObjectException {
1140 		logger.debug("Borrando objetos...");
1141 		int deleted = 0;
1142 		logger.debug("Label: " + label);
1143 		deleted = Pkcs11Util.deleteObjectsByLabel(device.getSession(), label, this.deleteOrphans);
1144 		logger.debug("Borrando objetos...OK");
1145 		return deleted;
1146 	}
1147 	
1148 	/*
1149 	 * (non-Javadoc)
1150 	 * @see es.accv.arangi.base.device.DeviceManager#getAliasList()
1151 	 */
1152 	public String[] getAliasNamesList() throws SearchingException {
1153 		
1154 		logger.debug("Obteniendo lista de alias...");
1155 		
1156 		List<String> result = new ArrayList<String>();
1157 		List<Object> lObjects = Pkcs11Util.findAllObjects(device.getSession(), null);
1158 		for (Iterator<Object> iterator = lObjects.iterator(); iterator.hasNext();) {
1159 			iaik.pkcs.pkcs11.objects.Storage iaikObject = (iaik.pkcs.pkcs11.objects.Storage) iterator.next();
1160 			if (!result.contains(iaikObject.getLabel().toString())) {
1161 				result.add(iaikObject.getLabel().toString());
1162 			}
1163 		}
1164 		
1165 		return (String[]) result.toArray(new String[0]);
1166 			
1167 	}
1168 	 
1169 	/**
1170 	 * Obtiene la clave privada asociada al alias. El password para recuperar la
1171 	 * clave será el PIN del dispositivo (caso por defecto).La clave se obtiene utilizando el 
1172 	 * provider PKCS#11 de Sun.<br><br>
1173 	 * 
1174 	 * Importante: no funciona con pares de claves sueltas, es decir necesita que las claves 
1175 	 * estén asociadas a un certificado.
1176 	 * 
1177 	 * @param alias Alias donde se encuentra la clave
1178 	 * @return Clave privada asociada al alias o null si no existe el alias o éste
1179 	 * no contiene una clave privada
1180 	 * 
1181 	 * @throws LoadingObjectException No se puede obtener la clave. Una posible causa 
1182 	 * podría ser que el password de la misma no coincide con el PIN del dispositivo.
1183 	 */
1184 	public java.security.PrivateKey getPrivateKey(String alias) throws LoadingObjectException {
1185 		return getPrivateKey (alias, pin);
1186 	}
1187 
1188 	/**
1189 	 * Busca la clave privada asociada al alias. La clave se obtiene utilizando el 
1190 	 * provider PKCS#11 de Sun.<br><br>
1191 	 * 
1192 	 * Importante: no funciona con pares de claves sueltas, es decir necesita que las claves 
1193 	 * estén asociadas a un certificado.
1194 	 * 
1195 	 * @param alias Alias donde se encuentra la clave
1196 	 * @param keyPassword Password de la clave privada
1197 	 * @return Clave privada asociada al alias o null si no existe el alias o éste
1198 	 * 	no contiene una clave privada
1199 	 * 
1200 	 * @throws LoadingObjectException No se puede obtener la clave. Probáblemente el 
1201 	 * 	password pasado como parámetro no sea correcto.
1202 	 */
1203 	public java.security.PrivateKey getPrivateKey(String alias,	String keyPassword) throws LoadingObjectException {
1204 		logger.debug("getPrivateKeys...");
1205 		logger.debug("findInAlias: " + alias);
1206 		
1207 		//-- Obtener la clave privada
1208 		logger.debug("[AbstractPkcs11Manager.getPrivateKey]::Entrada::" + Arrays.asList(new Object [] { alias }));
1209 		
1210 		//-- Lo normal será abrir la clave privada de SUN para firmar. Si no hay keystore
1211 		//-- se obtiene una clave privada en base a IAIK que sirve para que no aparezcan
1212 		//-- NullPointerExceptions
1213 		if (this.keystore != null) {
1214 			try {
1215 				//-- Devolver la clave privada con el proveedor de sun
1216 				logger.debug("[AbstractPkcs11Manager.getPrivateKey]::Encontrada clave privada con alias '" + alias + "'");
1217 				
1218 				java.security.PrivateKey privateKey = (java.security.PrivateKey) keystore.getKey(alias, keyPassword.toCharArray());
1219 				if (privateKey == null) {
1220 					logger.debug("No se ha encontrado la clave privada para el alias '" + alias + "'");
1221 				}
1222 				
1223 				return privateKey;
1224 		
1225 			} catch (KeyStoreException e) {
1226 				//-- Este error sólo se produce si no se ha inicializado la clase, lo que
1227 				//-- ya se comprueba y no puede ocurrir
1228 				logger.debug("[AbstractPkcs11Manager.getPrivateKey]::Keystore no inicializado", e);
1229 				return null;
1230 			} catch (NoSuchAlgorithmException e) {
1231 				//-- Este error sólo se produce si no se ha cargado Bouncy, con lo que
1232 				//-- el error se habría producido mucho antes
1233 				logger.debug("[AbstractPkcs11Manager.getPrivateKey]::No se encuentra el algoritmo para alguno de los certificados de la cadena", e);
1234 				return null;
1235 			} catch (UnrecoverableKeyException e) {
1236 				logger.info("[AbstractPkcs11Manager.getPrivateKey]::La clave privada del alias '" + alias + "' no ha podido ser recuperada. " +
1237 						"Compruebe que su password coincide con el PIN del dispositivo.", e);
1238 				throw new LoadingObjectException("La clave privada del alias '" + alias + "' no ha podido ser recuperada. Compruebe " +
1239 						"que su password coincide con el PIN del dispositivo.", e);
1240 			} 
1241 		} else {
1242 			//-- Sin keystore -> devolver clave basada en IAIK
1243 			//-- Obtener la clave privada
1244 			RSAPrivateKey iaikKey = (RSAPrivateKey) getIAIKPrivateKey(alias);
1245 			if (iaikKey == null) {
1246 				logger.debug("No se ha encontrado la clave privada para el alias '" + alias + "'");
1247 				return null;
1248 			}
1249 			
1250 			//-- Pasamos a PrivateKey de Sun
1251 			try {
1252 				logger.debug("Se va a devolver una clave privada para el alias '" + alias + "'");
1253 				return new TokenPrivateKey(iaikKey).getSunPrivateKey();
1254 			} catch (Exception e) {
1255 				logger.info("Error transformando clave privada a RSAPrivateKey de Sun...");
1256 				throw new LoadingObjectException ("Error transformando clave privada a RSAPrivateKey de Sun", e);
1257 			}
1258 
1259 		}
1260 	}
1261 	
1262 	/*
1263 	 * (non-Javadoc)
1264 	 * @see es.accv.arangi.base.device.DeviceManager#getPublicKey(java.lang.String)
1265 	 */
1266 	public java.security.PublicKey getPublicKey(String alias) throws LoadingObjectException {
1267 		logger.debug("getPublicKey...");
1268 
1269 		//-- Obtener la clave pública en un par de claves
1270 		PublicKey iaikKey = getIAIKPublicKey(alias);
1271 		if (iaikKey != null) {
1272 			//-- Pasamos a PublicKey de Sun
1273 			try {
1274 				logger.debug("Se va a devolver una clave pública para el alias '" + alias + "'");
1275 				return new TokenPublicKey(iaikKey).getSunPublicKey();
1276 			} catch (Exception e) {
1277 				logger.info("Error transformando clave publica a RSAPublicKey de Sun...", e);
1278 				throw new LoadingObjectException ("Error transformando clave publica a RSAPublicKey de Sun", e);
1279 			}
1280 		}
1281 		
1282 		//-- Obtener la clave pública dentro de un certificado
1283 		X509PublicKeyCertificate iaikCert = getIAIKCertificate(alias);
1284 		if (iaikCert != null) {
1285 			//-- Pasamos a PublicKey de Sun
1286 			try {
1287 				logger.debug("Se va a devolver una clave pública para el alias '" + alias + "'");
1288 				X509Certificate certificate = Util.getCertificate(iaikCert.getValue().getByteArrayValue());
1289 				return certificate.getPublicKey();
1290 			} catch (Exception e) {
1291 				logger.info("Error transformando clave publica a RSAPublicKey de Sun...", e);
1292 				throw new LoadingObjectException ("Error transformando clave publica a RSAPublicKey de Sun", e);
1293 			}
1294 		}
1295 		
1296 		//-- Si estamos aquí es porque no se ha obtenido ninguna clave pública
1297 		logger.debug("No se ha encontrado la clave pública para el alias '" + alias + "'");
1298 		return null;
1299 		
1300 	}
1301 	
1302 
1303 	/*
1304 	 * (non-Javadoc)
1305 	 * @see es.accv.arangi.base.device.DeviceManager#deletePrivateKey(java.lang.String)
1306 	 */
1307 	public int deletePrivateKey(String alias) throws DeletingObjectException {
1308 		logger.debug("[Pkcs11Manager.deletePrivateKey]::Entrada::" + alias);
1309 		int deleted = 0;
1310 		try {
1311 			//-- Obtener la clave privada
1312 			RSAPrivateKey iaikKey = (RSAPrivateKey) getIAIKPrivateKey(alias);
1313 			if (iaikKey == null) {
1314 				logger.debug("[Pkcs11Manager.deletePrivateKey]::No se ha encontrado una clave privada para el alias '" + alias + "'");
1315 				return 0;
1316 			}
1317 			
1318 			//-- Eliminar la clave privada
1319 			device.getSession().destroyObject(iaikKey);
1320 			
1321 		} catch (Exception e) {
1322 			logger.info("Borrando objetos...ERROR", e);
1323 			throw new DeletingObjectException("Error borrando objetos con la etiqueta ``" + alias + "´´", e);
1324 		}
1325 		logger.debug("Borrando objetos...OK");
1326 		return deleted;
1327 	}
1328 
1329 	public int deleteCertificate (String alias) throws DeletingObjectException {
1330 		logger.debug("[Pkcs11Manager.deletePrivateKey]::Entrada::" + alias);
1331 		int deleted = 0;
1332 		try {
1333 			//-- Obtener el certificado
1334 			X509PublicKeyCertificate iaikCert;
1335 			try {
1336 				iaikCert = getIAIKCertificate(alias);
1337 			} catch (LoadingObjectException e) {
1338 				logger.info("[Pkcs11Manager.getCertificate]::Error buscando el certificado para el alias '" + alias + "'", e);
1339 				throw new SearchingException ("Error buscando el certificado para el alias '" + alias + "'", e);
1340 			}
1341 			if (iaikCert != null) {
1342 				//-- Eliminar la clave privada
1343 				device.getSession().destroyObject(iaikCert);
1344 				deleted++;
1345 			}
1346 			
1347 		} catch (Exception e) {
1348 			logger.info("Borrando objetos...ERROR", e);
1349 			throw new DeletingObjectException("Error borrando objetos con la etiqueta ``" + alias + "´´", e);
1350 		}
1351 		logger.debug("Borrando objetos...OK");
1352 		return deleted;
1353 	}
1354 
1355 	/*
1356 	 * (non-Javadoc)
1357 	 * @see es.accv.arangi.base.device.DeviceManager#format()
1358 	 */
1359 	public void clear() throws DeletingObjectException {
1360 
1361 		logger.debug ("[Pkcs11Manager.clear]::Entrada");
1362 
1363 		//-- Recorrer todos los alias y eliminar los objetos que hay en ellos
1364 		int counter = 0;
1365 		List<Object> lObjects;
1366 		try {
1367 			lObjects = Pkcs11Util.findAllObjects(device.getSession(), null);
1368 		} catch (SearchingException e) {
1369 			logger.info("[Pkcs11Manager.clear]::No se pueden obtener los elementos a formatear", e);
1370 			throw new DeletingObjectException ("No se pueden obtener los elementos a formatear", e);
1371 		}
1372 		
1373 		try {
1374 			for (Iterator<Object> iterator = lObjects.iterator(); iterator.hasNext();) {
1375 				iaik.pkcs.pkcs11.objects.Object iaikObject = (iaik.pkcs.pkcs11.objects.Object) iterator.next();
1376 				logger.debug ("[Pkcs11Manager.clear]::Procediendo a eliminar objeto");
1377 				device.getSession().destroyObject(iaikObject);
1378 				logger.debug ("[Pkcs11Manager.clear]::Objeto eliminado");
1379 				counter++;
1380 			}
1381 		} catch (TokenException e) {
1382 			logger.info("[Pkcs11Manager.clear]::No se ha podido eliminar un objeto", e);
1383 			
1384 			//-- Tratar de no dejar huerfanos
1385 			logger.debug("[Pkcs11Manager.clear]::Tratando de eliminar huérfanos tras fracaso en el formateo");
1386 			Pkcs11Util.deleteOrphans(device.getSession());
1387 			logger.debug("[Pkcs11Manager.clear]::Huérfanos eliminados");
1388 			
1389 			logger.info("[Pkcs11Manager.clear]::Error eliminando un elemento del dispositivo", e);
1390 			throw new DeletingObjectException ("Error eliminando un elemento del dispositivo", e);
1391 		}
1392 
1393 		logger.debug ("[Pkcs11Manager.clear]::Fin::Se han eliminado " + counter + " objetos");
1394 
1395 	}
1396 
1397 	/**
1398 	 * Realiza un formateado del dispositivo
1399 	 * 
1400 	 * @param puk PUK del dispositivo
1401 	 * @param newPin Nuevo pin del dispositivo tras la inicialización
1402 	 * @param newLabel Nueva etiqueta del dispositivo formateado
1403 	 * @throws FormatException Errores durante la inicialización del dispositivo
1404 	 */
1405 	public void format (String puk, String newPin, String newLabel)  throws FormatException {
1406 
1407 		logger.debug ("[Pkcs11Manager.format]::Entrada");
1408 		
1409 		//-- Cerrar las sesiones abiertas
1410 		logger.debug ("[Pkcs11Manager.format]::Cerrando las sesiones");
1411 		try {
1412 			device.getToken().closeAllSessions();
1413 			logger.debug ("[Pkcs11Manager.format]::Sesiones cerradas");
1414 		} catch (TokenException e) {
1415 			logger.info ("[Pkcs11Manager.format]::Error durante el proceso de cerrado previo de las sesiones", e);
1416 			throw new FormatException("Error durante el proceso de cerrado previo de las sesiones", e);
1417 		}
1418 
1419 		//-- Formatear
1420 		logger.debug ("[Pkcs11Manager.format]::Iniciando inicialización");
1421 		try {
1422 			this.device.getToken().initToken(puk.toCharArray(), newLabel);
1423 			logger.debug ("[Pkcs11Manager.format]::Dispositivo inicializado");
1424 		} catch (TokenException e) {
1425 			logger.info ("[Pkcs11Manager.format]::Error durante el proceso de inicialización del dispositivo", e);
1426 			throw new FormatException("Error durante el proceso de inicialización del dispositivo", e);
1427 		} 
1428 		
1429 		//-- Inicializar el PIN
1430 		try {
1431 			
1432 	        device.setSession(device.getToken().openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION, null, null));
1433 	        device.getSession().login(Session.UserType.SO, puk.toCharArray());
1434 	        device.getSession().initPIN(newPin.toCharArray());
1435 	        device.getToken().closeAllSessions();
1436 	        this.pin = newPin;
1437 		} catch (TokenException e) {
1438 			logger.info ("[Pkcs11Manager.format]::Error durante el proceso de inicialización del PIN tras el formateo del dispositivo", e);
1439 			throw new FormatException("Error durante el proceso de inicialización del PIN tras el formateo del dispositivo", e);
1440 		} 
1441 		
1442 		//-- Volver a inicializar el manager
1443 		try {
1444 			initialize(pin, false, this.device.getManufacturer());
1445 		} catch (Exception e) {
1446 			logger.info ("[Pkcs11Manager.format]::No ha sido posible volver a abrir el dispositivo tras la inicialización", e);
1447 			throw new FormatException("No ha sido posible volver a abrir el dispositivo tras la inicialización", e);
1448 		}
1449 	}
1450 	
1451 	/**
1452 	 * Obtiene el objeto dispositivo que hay tras el manager.
1453 	 * 
1454 	 * @return Dispositivo
1455 	 */
1456 	public Pkcs11Device getDevice() {
1457 		return device;
1458 	}
1459 
1460 	/**
1461 	 * Obtiene el nombre del módulo que está gestionando el dispositivo
1462 	 * 
1463 	 * @return Nombre de módulo de gestión PKCS#11
1464 	 */
1465 	public String getDeviceModuleName(){
1466 		logger.debug("getDeviceModuleName(): " + device.getModuleName());
1467 		return this.device.getModuleName();
1468 	}
1469 	
1470 	/**
1471 	 * Obtiene el nombre del fabricante del dispositivo
1472 	 * 
1473 	 * @return Nombre del fabricante
1474 	 */
1475 	public String getManufacturerName () {
1476 		logger.debug("getManufacturerName(): " + device.getManufacturer().getManufacturerName());
1477 		return this.device.getManufacturer().getManufacturerName();
1478 	}
1479 	
1480 	/**
1481 	 * Obtiene el nombre del fabricante del dispositivo tal y como aparece
1482 	 * en los campos del propio dispositivo
1483 	 * 
1484 	 * @return ID del fabricante
1485 	 */
1486 	public String getManufacturerID () {
1487 		logger.debug("getManufacturerID(): " + device.getManufacturerId());
1488 		return this.device.getManufacturerId();
1489 	}
1490 	
1491 	/**
1492 	 * Obtiene el identificador del dispositivo.
1493 	 * 
1494 	 * @return ID del dispositivo
1495 	 */
1496 	public long getId() {
1497 		logger.debug("getId(): " + device.getId());
1498 		return this.device.getId();
1499 	}
1500 	
1501 	/**
1502 	 * Obtiene la etiqueta del dispositivo, normalmente relacionada con el módulo
1503 	 * con el que se abrió.
1504 	 * 
1505 	 * @return Etiqueta del dispositivo
1506 	 */
1507 	public String getLabel() {
1508 		logger.debug("getLabel(): " + device.getLabel());
1509 		return this.device.getLabel();
1510 	}
1511 	
1512 	/**
1513 	 * Obtiene el modelo del dispositivo
1514 	 * 
1515 	 * @return Modelo del dispostivo
1516 	 */
1517 	public String getModel() {
1518 		logger.debug("getModel(): " + device.getModel());
1519 		return this.device.getModel();
1520 	}
1521 	
1522 	/**
1523 	 * Obtiene el número de serie del dispositivo
1524 	 * 
1525 	 * @return Número de serie del dispositivo
1526 	 */
1527 	public String getSerialNumber() {
1528 		logger.debug("getSerialNumber(): " + device.getSerialNumber());
1529 		return this.device.getSerialNumber();
1530 	}
1531 	
1532 	/**
1533 	 * Obtiene el tamaño total de la memoria de la tarjeta
1534 	 * 
1535 	 * @return Tamaño total de la memoria de la tarjeta
1536 	 */
1537 	public long getTotalMemory () {
1538 		logger.debug("getTotalMemory(): " + device.getTotalMemory());
1539 		return this.device.getTotalMemory();
1540 	}
1541 	
1542 	/**
1543 	 * Obtiene la memoria que queda libre en la tarjeta
1544 	 * 
1545 	 * @return Tamaño de la memoria que queda libre en la tarjeta
1546 	 */
1547 	public long getFreeMemory () {
1548 		logger.debug("getAvailableMemory(): " + device.getFreeMemory());
1549 		return this.device.getFreeMemory();
1550 	}
1551 	
1552 	/**
1553 	 * Obtiene el objeto fabricante que abrió el dispositivo
1554 	 * 
1555 	 * @return Objeto fabricante que abrió el dispositivo
1556 	 */
1557 	public Pkcs11Manufacturer getManufacturer() {
1558 		logger.debug("getManufacturer(): " + device.getManufacturer());
1559 		return this.device.getManufacturer();
1560 	}
1561 	
1562 	/**
1563 	 * Desbloquea el PIN de la tarjeta. Para entrar habrá que hacerlo con el PUK
1564 	 * 
1565 	 * @param newPIN Nuevo PIN
1566 	 * @throws UnlockPINException No ha sido posible desbloquear el PIN
1567 	 */
1568 	public void unlockPIN (String newPIN) throws UnlockPINException {
1569 		logger.debug("[AbstractPKCS11Manager.unlockPIN]::Entrada");
1570 		try {
1571 			device.getSession().initPIN(newPIN.toCharArray());
1572 		} catch (TokenException e) {
1573 			logger.info("[AbstractPKCS11Manager.unlockPIN]::No se tienen permisos para desbloquear el PIN del dispositivo", e);
1574 			throw new UnlockPINException ("No se tienen permisos para desbloquear el PIN del dispositivo", e);
1575 		}
1576 	}
1577 
1578 	/**
1579 	 * Carga la dll de IAIK en la carpeta temporal de Arangi y devuelve
1580 	 * el fichero.
1581 	 */
1582 	public static File loadIAIKDllFile () throws IAIKDLLNotFoundException {
1583 		//-- Obtener valores dependiendo de si estamos en un JRE de 32 o 64 bits
1584 		String dllName = IAIK_WINX86_DLL_NAME;
1585 		String dllClasspath = IAIK_WINX86_DLL_CLASSPATH_PATH;
1586 		if (System.getProperty("os.arch").indexOf("64") > -1) {
1587 			dllName = IAIK_WINX64_DLL_NAME;
1588 			dllClasspath = IAIK_WINX64_DLL_CLASSPATH_PATH;
1589 		}
1590 		
1591 		//-- Comprobar si la dll ya está en la carpeta temporal
1592 		File file = new File (getArangiTemporalFolder(), dllName);
1593 		if (!file.exists() || file.length() == 0) {
1594 			//-- No está, así que guardarla
1595 			try {
1596 				saveToArangiTemporalFolder(new Util().getClass().getClassLoader().getResourceAsStream(dllClasspath), dllName);
1597 			} catch (IOException e) {
1598 				logger.debug("[AbstractPkcs11Manager.loadIAIKDllFile]::No ha sido posible guardar la DLL de IAIK en el path: " + file.getAbsolutePath(), e);
1599 				
1600 				//-- No se ha podido guardar. Comprobar si ya existe en el path (windows/system32). Si es así devolver null
1601 				//-- para que no se utilice un fichero en una ubicación específica.
1602 				try {
1603 					System.loadLibrary(dllName);
1604 					return null;
1605 				} catch (Throwable t) {				
1606 					logger.info("[AbstractPkcs11Manager.loadIAIKDllFile]::No existe la DLL de IAIK en el sistema y no puede ser guardada en el path: " + file.getAbsolutePath(), e);
1607 					throw new IAIKDLLNotFoundException ("No existe la DLL de IAIK en el sistema", t);
1608 				}
1609 			}
1610 		}
1611 		
1612 		//-- devolver el fichero
1613 		return file;
1614 	}
1615 	
1616 	/**
1617 	 * Da valor al flag que indica si se quiere que se borren las
1618 	 * claves huerfanas (claves sin certificado)
1619 	 * 
1620 	 * @param deleteOrphans Flag
1621 	 */
1622 	public void setDeleteOrphans (boolean deleteOrphans) {
1623 		this.deleteOrphans = deleteOrphans;
1624 	}
1625 
1626 	//-- Métodos privados
1627 	
1628 	/*
1629 	 * Obtiene la clave privada en formato IAIK
1630 	 */
1631 	private PrivateKey getIAIKPrivateKey(String alias) throws LoadingObjectException {
1632 		logger.debug("getIAIKPrivateKey...");
1633 		logger.debug("alias: " + alias);
1634 
1635 		List<Object> lPKs = new ArrayList<Object>();
1636 		PrivateKey privateKeyTemplate = new iaik.pkcs.pkcs11.objects.PrivateKey();
1637 		privateKeyTemplate.getLabel().setCharArrayValue(alias.toCharArray());
1638 		try {
1639 			lPKs = Pkcs11Util.findAllObjects(device.getSession(), privateKeyTemplate);
1640 		} catch (SearchingException e) {
1641 			throw new LoadingObjectException ("Se ha producido un error buscando la clave privada en el dispositivo", e);
1642 		}
1643 		
1644 		if (lPKs.isEmpty()) {
1645 			logger.info("El alias '" + alias + "' no contiene una clave privada");
1646 			return null;
1647 		}
1648 		
1649 		return (RSAPrivateKey) lPKs.get(0);
1650 	}
1651 
1652 	/*
1653 	 * Obtiene la clave pública en formato IAIK 
1654 	 */
1655 	private PublicKey getIAIKPublicKey(String alias) throws LoadingObjectException {
1656 		logger.debug("getIAIKPublicKey...");
1657 		logger.debug("alias: " + alias);
1658 
1659 		List<Object> lPKs = new ArrayList<Object>();
1660 		PublicKey publicKeyTemplate = new iaik.pkcs.pkcs11.objects.PublicKey();
1661 		publicKeyTemplate.getLabel().setCharArrayValue(alias.toCharArray());
1662 		try {
1663 			lPKs = Pkcs11Util.findAllObjects(device.getSession(), publicKeyTemplate);
1664 		} catch (SearchingException e) {
1665 			throw new LoadingObjectException ("Se ha producido un error buscando la clave pública en el dispositivo", e);
1666 		}
1667 		
1668 		if (lPKs.isEmpty()) {
1669 			logger.info("El alias '" + alias + "' no contiene una clave pública");
1670 			return null;
1671 		}
1672 		
1673 		return (PublicKey) lPKs.get(0);
1674 	}
1675 	
1676 	/*
1677 	 * Obtiene el Certificado en formato IAIK 
1678 	 */
1679 	private X509PublicKeyCertificate getIAIKCertificate (String alias) throws LoadingObjectException {
1680 		logger.debug("getIAIKCertificate...");
1681 		logger.debug("alias: " + alias);
1682 
1683 		List<Object> lCerts = new ArrayList<Object>();
1684 		X509PublicKeyCertificate certificateTemplate = new X509PublicKeyCertificate();
1685 		certificateTemplate.getLabel().setCharArrayValue(alias.toCharArray());
1686 		try {
1687 			lCerts = Pkcs11Util.findAllObjects(device.getSession(), certificateTemplate);
1688 		} catch (SearchingException e) {
1689 			throw new LoadingObjectException ("Se ha producido un error buscando el certificado en el dispositivo", e);
1690 		}
1691 		
1692 		if (lCerts.isEmpty()) {
1693 			logger.info("El alias '" + alias + "' no contiene certificados");
1694 			return null;
1695 		}
1696 		
1697 		return (X509PublicKeyCertificate) lCerts.get(0);
1698 	}
1699 
1700 	/*
1701 	 * Devuelve el mecanismo que se corresponde con el algoritmo
1702 	 */
1703 	private static Mechanism getMechanism(String algorithm) {
1704 		
1705 		if (algorithm.equals (CipherAlgorithm.RSA)) {
1706 			return Mechanism.RSA_PKCS;
1707 		}
1708 		if (algorithm.equals (CipherAlgorithm.DSA)) {
1709 			return Mechanism.DSA;
1710 		}
1711 		
1712 		return null;
1713 	}
1714 	
1715 	/*
1716 	 * Valida si hay espacio suficiente en la tarjeta (<5kb)
1717 	 */
1718 	private boolean validateFreeMemory(long freeMemory) {
1719 		return freeMemory > 5120;
1720 	}
1721 
1722 	  /*
1723 	   * Obtiene una peticion de certificado (PKCS#10) asociada a partir de los parametros.
1724 	   * 
1725 	   * @param session Sesión en el dispositivo
1726 	   * @param kp Clave privada con la que se firmará el PKCS#10
1727 	   * @param subjectDN Nombre del sujeto
1728 	   * @param subjectAlternativeDN Nombre alternativo del sujeto
1729 	   * @return Objeto que representa el PKCS#10
1730 	   * 
1731 	   * @throws Exception Error durante el proceso 
1732 	   */
1733 	  private static CertificationRequest getCertificationRequest(Session session, KeyPair kp, String subjectDN, String subjectAlternativeDN) {
1734 
1735 	    logger.debug("[Pkcs11Manager.getCertificationRequest]::" + Arrays.asList(new Object[] { "<rsaKeys>", subjectDN, subjectAlternativeDN }));
1736 	    
1737 	    if (subjectDN == null) {
1738 	      throw new IllegalArgumentException("El campo SubjectDN no puede ser nulo.");
1739 	    }
1740 	    
1741 	    if (kp == null) {
1742 	      throw new IllegalArgumentException("El par de claves no puede ser nulo.");
1743 	    }
1744 	    
1745 	    try {
1746 			    // -- Obtenemos el nombre estandar
1747 			    X500Name x509Name = Certificate.stringToBcX500Name( subjectDN );
1748 			    logger.debug("[Pkcs11Manager.getCertificationRequest]::::x509Name: " + x509Name);
1749 			      
1750 				    //-- Parametros para la creacion del bloque de extensiones
1751 		    Map<String,String> extensionsMap = new HashMap<String,String>();
1752 		    extensionsMap.put("subjectAlternativeNameDN", subjectAlternativeDN);
1753 	
1754 		    //-- Generamos el set de extensiones del certificado
1755 		    ASN1Set pkcs10AttributeSet = CSRUtil.getPKCS10Set(kp.getPublic(), kp.getPublic(), extensionsMap);
1756 	
1757 		    // Generate PKCS10 certificate request
1758 		    byte[]                  bytes = kp.getPublic().getEncoded();
1759 	
1760 		    CertificationRequestInfo cri = null;
1761 	        logger.debug("[Pkcs11Manager.getCertificationRequest]::" + ASN1Dump.dumpAsString(pkcs10AttributeSet) + "\n");
1762 	        
1763 	        SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(bytes);
1764 	        cri = new CertificationRequestInfo(x509Name, spki, pkcs10AttributeSet);
1765 		      
1766 		    logger.debug("[Pkcs11Manager.getCertificationRequest]::CertificationRequestInfo creado.");
1767 		    
1768 		    //-- Creacion del buffer de datos a firmar
1769 		    byte[] buffer = cri.getEncoded(ASN1Encoding.DER);
1770 	
1771 		    ASN1ObjectIdentifier sigOID = new ASN1ObjectIdentifier(DigitalSignatureAlgorithm.getOID(DigitalSignatureAlgorithm.SHA1_RSA));
1772 		    AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID);
1773 		    
1774 		    logger.debug("[Pkcs11Manager.getCertificationRequest]::Array a firmar: " + buffer.length);
1775 		    byte[] abFirma = null;
1776 		    int i=0;
1777 		    while (i<=NUM_RETRIES && abFirma==null) {
1778 		    	try {
1779 		    		abFirma = SignUtil.generateSignature(session, kp.getPrivate(), buffer);
1780 		    	} catch (Exception e) {
1781 		    		//-- Si es el último intento lanzar la excepción
1782 		    		if (i==NUM_RETRIES) {
1783 		    			logger.debug ("[Pkcs11Manager.getCertificationRequest]::No ha sido posible firmar la petición", e);
1784 		    			throw e;
1785 		    		}
1786 		    	}
1787 		    	i++;
1788 		    }
1789 		    
1790 		    logger.debug("[Pkcs11Manager.getCertificationRequest]::firma length: " + abFirma.length );
1791 		    
1792 		    DERBitString derBitStr = new DERBitString(abFirma);
1793 		    
1794 		    //-- Creamos la certification request
1795 		    return new CertificationRequest(cri, sigAlgId, derBitStr);
1796 		    
1797 		} catch (Exception e) {
1798 			// No se llega
1799 			return null;
1800 		}
1801 		    
1802 	  }
1803 	  
1804 	  /*
1805 	   * Método que obtiene el identificador que tendrá un certificado y su clave privada asociada
1806 	   */
1807 	  protected byte[] getObjectID(Certificate userCertificate) throws CertificateEncodingException, InitDocumentException, HashingException, NoSuchAlgorithmException {
1808 		  byte[] certificateFingerprint = userCertificate.getDigest(DEFAULT_HASHING_ALGORITHM);
1809 		  
1810 		  byte[] subjectKeyIdentifier = Util.decodeBase64(userCertificate.getSubjectKeyIdentifier());
1811 		  
1812 		  logger.debug("Obtenido certificado de usuario.");
1813 		  logger.debug("Creando la clave privada en la tarjeta... ");
1814 		  
1815 		  //-- Obtener el ID que asocia clave y certificado
1816 		  if (subjectKeyIdentifier != null) {
1817 			  // we take the key identifier from the certificate
1818 			  return subjectKeyIdentifier;
1819 		  } else {
1820 			  // then we simply take the fingerprint of the certificate
1821 			  return certificateFingerprint;
1822 		  }
1823 	  }
1824 
1825 	 /**
1826 	 * Obtiene una clave privada IAIK en base a la clave privada de SUN pasada como
1827 	 * parámetro
1828 	 * 
1829 	 * @param jcaPrivateKey 
1830 	 * @param nombreEnDestino 
1831 	 * @param newObjectID 
1832 	 * @param userCertificate 
1833 	 * @return Clave privada de IAIK
1834 	 * @throws TokenException 
1835 	   */
1836 	  protected PrivateKey getIaikPrivateKey (java.security.PrivateKey jcaPrivateKey, String nombreEnDestino, byte[] newObjectID, 
1837 			  X509Certificate userCertificate, BigInteger publicExponent) throws TokenException {
1838 	    	
1839 	    	java.security.interfaces.RSAPrivateKey jcaRsaPrivateKey = (java.security.interfaces.RSAPrivateKey)jcaPrivateKey;
1840 		
1841 			// create private key object template
1842 			RSAPrivateKey pkcs11RsaPrivateKey = new RSAPrivateKey();
1843 
1844 			pkcs11RsaPrivateKey.getSensitive().setBooleanValue(Boolean.TRUE);
1845 			pkcs11RsaPrivateKey.getToken().setBooleanValue(Boolean.TRUE);
1846 			pkcs11RsaPrivateKey.getPrivate().setBooleanValue(Boolean.TRUE);
1847 			pkcs11RsaPrivateKey.getLabel().setCharArrayValue(nombreEnDestino.toCharArray());
1848 
1849 			pkcs11RsaPrivateKey.getId().setByteArrayValue(newObjectID);
1850 			
1851 			//-- Obtener el mecanismo de firma
1852 			MechanismInfo signatureMechanismInfo = getSignatureMechanismInfo (device.getToken());
1853 			
1854 			//-- Obtener keyUsage
1855 			boolean[] keyUsage = null;
1856 			if (userCertificate != null) {
1857 				pkcs11RsaPrivateKey.getSubject().setByteArrayValue(userCertificate.getSubjectX500Principal().getEncoded());
1858 				keyUsage = userCertificate.getKeyUsage();
1859 			}
1860 			
1861 			if (keyUsage != null) {
1862 
1863 				logger.debug("Tenemos KeyUsage");
1864 	        
1865 				// set the attributes in a way netscape does, this should work with most
1866 				// tokens
1867 				if (signatureMechanismInfo != null) {
1868 					
1869 					logger.debug("Tenemos signatureMechanismInfo");
1870 					logger.debug("KeyUsage.dataEncipherment : " + keyUsage[DeviceUtil.KEYUSAGE_DATAENCIPHERMENT]);
1871 					logger.debug("KeyUsage.keyCertSign      : " + keyUsage[DeviceUtil.KEYUSAGE_KEYCERTSIGN]);
1872 					logger.debug("KeyUsage.encipherOnly      : " + keyUsage[DeviceUtil.KEYUSAGE_ENCIPHERONLY]);
1873 					logger.debug("KeyUsage.digitalSignature: " + keyUsage[DeviceUtil.KEYUSAGE_DIGITALSIGNATURE]);
1874 					logger.debug("KeyUsage.cRLSign          : " + keyUsage[DeviceUtil.KEYUSAGE_CRLSIGN]);
1875 					logger.debug("KeyUsage.nonRepudiation  : " + keyUsage[DeviceUtil.KEYUSAGE_NONREPUDIATION]);
1876 					logger.debug("KeyUsage.keyAgreement    : " + keyUsage[DeviceUtil.KEYUSAGE_KEYAGREEMENT]);
1877 					logger.debug("KeyUsage.keyEncipherment  : " + keyUsage[DeviceUtil.KEYUSAGE_KEYENCIPHERMENT]);
1878 					logger.debug("signatureMechanismInfo.isDecrypt(): " + signatureMechanismInfo.isDecrypt());
1879 					logger.debug("signatureMechanismInfo.isSign(): " + signatureMechanismInfo.isSign());
1880 					logger.debug("signatureMechanismInfo.isSignRecover(): " + signatureMechanismInfo.isSignRecover());
1881 					logger.debug("signatureMechanismInfo.isDerive(): " + signatureMechanismInfo.isDerive());
1882 					logger.debug("signatureMechanismInfo.isUnwrap(): " + signatureMechanismInfo.isUnwrap());
1883 
1884 	          
1885 					//-- Para evitar problemas CKA_DECRYPT = TRUE
1886 					pkcs11RsaPrivateKey.getDecrypt().setBooleanValue(Boolean.TRUE);
1887 	          
1888 					pkcs11RsaPrivateKey.getSign().setBooleanValue(
1889 							new Boolean((keyUsage[DeviceUtil.KEYUSAGE_DIGITALSIGNATURE] || keyUsage[DeviceUtil.KEYUSAGE_KEYCERTSIGN]
1890 	                           || keyUsage[DeviceUtil.KEYUSAGE_CRLSIGN] || keyUsage[DeviceUtil.KEYUSAGE_NONREPUDIATION])
1891 	                          && signatureMechanismInfo.isSign()));
1892 
1893 					pkcs11RsaPrivateKey.getSignRecover().setBooleanValue(
1894 							new Boolean((keyUsage[DeviceUtil.KEYUSAGE_DIGITALSIGNATURE] || keyUsage[DeviceUtil.KEYUSAGE_KEYCERTSIGN]
1895 	                           || keyUsage[DeviceUtil.KEYUSAGE_CRLSIGN] || keyUsage[DeviceUtil.KEYUSAGE_NONREPUDIATION])
1896 	                          && signatureMechanismInfo.isSignRecover()));
1897 
1898 					pkcs11RsaPrivateKey.getDerive().setBooleanValue(new Boolean(keyUsage[DeviceUtil.KEYUSAGE_KEYAGREEMENT] && signatureMechanismInfo.isDerive()));
1899 					pkcs11RsaPrivateKey.getUnwrap().setBooleanValue(new Boolean(keyUsage[DeviceUtil.KEYUSAGE_KEYENCIPHERMENT] && signatureMechanismInfo.isUnwrap()));
1900 
1901 				} else {
1902 
1903 					// if we have no mechanism information, we try to set the flags
1904 					// according to the key usage only
1905 					pkcs11RsaPrivateKey.getDecrypt().setBooleanValue(
1906 							new Boolean(keyUsage[DeviceUtil.KEYUSAGE_DATAENCIPHERMENT] || keyUsage[DeviceUtil.KEYUSAGE_KEYCERTSIGN]));
1907 
1908 					pkcs11RsaPrivateKey.getSign().setBooleanValue(
1909 							new Boolean(keyUsage[DeviceUtil.KEYUSAGE_DIGITALSIGNATURE] || keyUsage[DeviceUtil.KEYUSAGE_KEYCERTSIGN]
1910 	                          || keyUsage[DeviceUtil.KEYUSAGE_CRLSIGN] || keyUsage[DeviceUtil.KEYUSAGE_NONREPUDIATION]));
1911 
1912 					pkcs11RsaPrivateKey.getSignRecover().setBooleanValue(
1913 							new Boolean(keyUsage[DeviceUtil.KEYUSAGE_DIGITALSIGNATURE] || keyUsage[DeviceUtil.KEYUSAGE_KEYCERTSIGN]
1914 	                          || keyUsage[DeviceUtil.KEYUSAGE_CRLSIGN] || keyUsage[DeviceUtil.KEYUSAGE_NONREPUDIATION]));
1915 
1916 					pkcs11RsaPrivateKey.getDerive().setBooleanValue(new Boolean(keyUsage[DeviceUtil.KEYUSAGE_KEYAGREEMENT]));
1917 					pkcs11RsaPrivateKey.getUnwrap().setBooleanValue(new Boolean(keyUsage[DeviceUtil.KEYUSAGE_KEYENCIPHERMENT]));
1918 
1919 				}
1920 				
1921 			} else {
1922 	        
1923 				logger.debug("NO tenemos KeyUsage");
1924 
1925 				// if there is no keyusage extension in the certificate, try to set all
1926 				// flags according to the mechanism info
1927 				if (signatureMechanismInfo != null) {
1928 
1929 					pkcs11RsaPrivateKey.getSign().setBooleanValue(new Boolean(signatureMechanismInfo.isSign()));
1930 					pkcs11RsaPrivateKey.getSignRecover().setBooleanValue(new Boolean(signatureMechanismInfo.isSignRecover()));
1931 					pkcs11RsaPrivateKey.getDecrypt().setBooleanValue(new Boolean(signatureMechanismInfo.isDecrypt()));
1932 					pkcs11RsaPrivateKey.getDerive().setBooleanValue(new Boolean(signatureMechanismInfo.isDerive()));
1933 					pkcs11RsaPrivateKey.getUnwrap().setBooleanValue(new Boolean(signatureMechanismInfo.isUnwrap()));
1934 
1935 				} else {
1936 
1937 					// if we have neither mechanism info nor key usage we just try all
1938 					pkcs11RsaPrivateKey.getSign().setBooleanValue(Boolean.TRUE);
1939 					pkcs11RsaPrivateKey.getSignRecover().setBooleanValue(Boolean.TRUE);
1940 					pkcs11RsaPrivateKey.getDecrypt().setBooleanValue(Boolean.TRUE);
1941 					pkcs11RsaPrivateKey.getDerive().setBooleanValue(Boolean.TRUE);
1942 					pkcs11RsaPrivateKey.getUnwrap().setBooleanValue(Boolean.TRUE);
1943 				}
1944 
1945 			}
1946 
1947 			pkcs11RsaPrivateKey.getModulus().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(jcaRsaPrivateKey.getModulus()));
1948 			pkcs11RsaPrivateKey.getPrivateExponent().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(jcaRsaPrivateKey.getPrivateExponent()));
1949 			pkcs11RsaPrivateKey.getPublicExponent().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(publicExponent));
1950 
1951 			if (jcaRsaPrivateKey instanceof java.security.interfaces.RSAPrivateCrtKey) {
1952 
1953 				// if we have the CRT field, we write it to the card
1954 				// e.g. gemsafe seems to need it
1955 				java.security.interfaces.RSAPrivateCrtKey crtKey = (java.security.interfaces.RSAPrivateCrtKey) jcaRsaPrivateKey;
1956 				pkcs11RsaPrivateKey.getPrime1().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(crtKey.getPrimeP()));
1957 				pkcs11RsaPrivateKey.getPrime2().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(crtKey.getPrimeQ()));
1958 				pkcs11RsaPrivateKey.getExponent1().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(crtKey.getPrimeExponentP()));
1959 				pkcs11RsaPrivateKey.getExponent2().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(crtKey.getPrimeExponentQ()));
1960 				pkcs11RsaPrivateKey.getCoefficient().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray(crtKey.getCrtCoefficient()));
1961 
1962 			}
1963 
1964 			return pkcs11RsaPrivateKey;
1965 	  }
1966 	  
1967 	 /**
1968 	 * Obtiene una clave publica IAIK en base a la clave pública de SUN pasada como
1969 	 * parámetro
1970 	 * 
1971 	 * @param jcaPrivateKey 
1972 	 * @param nombreEnDestino 
1973 	 * @param newObjectID 
1974 	 * @param userCertificate 
1975 	 * @return Clave privada de IAIK
1976 	 * @throws TokenException 
1977 	   */
1978 	  protected PublicKey getIaikPublicKey (java.security.PublicKey jcaPublicKey, String nombreEnDestino, byte[] newObjectID) throws TokenException {
1979 		  
1980 		  //-- Obtener el mecanismo de firma
1981 		  MechanismInfo signatureMechanismInfo = getSignatureMechanismInfo (device.getToken());
1982 		  
1983 		  //-- Obtener la clave pública
1984 		  RSAPublicKey pkcs11RsaPublicKey = new RSAPublicKey();
1985 		  pkcs11RsaPublicKey.getId().setByteArrayValue(newObjectID);
1986 		  pkcs11RsaPublicKey.getLabel().setCharArrayValue(nombreEnDestino.toCharArray());
1987 		  pkcs11RsaPublicKey.getToken().setBooleanValue(Boolean.TRUE);
1988 		  pkcs11RsaPublicKey.getPrivate().setBooleanValue(Boolean.FALSE);
1989 		  pkcs11RsaPublicKey.getModifiable().setBooleanValue(Boolean.TRUE);
1990 		  if (signatureMechanismInfo != null) {
1991 			  pkcs11RsaPublicKey.getVerify().setBooleanValue(new Boolean(signatureMechanismInfo.isVerify()));
1992 			  pkcs11RsaPublicKey.getVerifyRecover().setBooleanValue(new Boolean(signatureMechanismInfo.isVerifyRecover()));
1993 			  pkcs11RsaPublicKey.getEncrypt().setBooleanValue(new Boolean(signatureMechanismInfo.isEncrypt()));
1994 			  pkcs11RsaPublicKey.getDerive().setBooleanValue(new Boolean(signatureMechanismInfo.isDerive()));
1995 			  pkcs11RsaPublicKey.getWrap().setBooleanValue(new Boolean(signatureMechanismInfo.isWrap()));
1996 		  } else {
1997 			  pkcs11RsaPublicKey.getVerify().setBooleanValue(Boolean.TRUE);
1998 			  pkcs11RsaPublicKey.getEncrypt().setBooleanValue(Boolean.TRUE);
1999 		  }
2000 //		  pkcs11RsaPublicKey.getKeyType().setPresent(false);
2001 //		  pkcs11RsaPublicKey.getObjectClass().setPresent(false);
2002 		  
2003 		  //-- Añadir valores de la clave pública de SUN
2004 		  java.security.interfaces.RSAPublicKey sunRsaPublicKey = (java.security.interfaces.RSAPublicKey)jcaPublicKey;
2005 		  pkcs11RsaPublicKey.getPublicExponent().setByteArrayValue(iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray (sunRsaPublicKey.getPublicExponent()));
2006 		  byte [] modulus = iaik.pkcs.pkcs11.Util.unsignedBigIntergerToByteArray (sunRsaPublicKey.getModulus());
2007 		  pkcs11RsaPublicKey.getModulusBits().setLongValue(new Long (modulus.length * 8));
2008 		  pkcs11RsaPublicKey.getModulus().setByteArrayValue(modulus);
2009 		  
2010 		  return pkcs11RsaPublicKey;
2011 	  }
2012 	  
2013 	/*
2014 	 * Método que obtiene información de los dispositivos conectados para una
2015 	 * serie de modulos PKCS#11 asociados a sus fabricantes
2016 	 * 
2017 	 * @param manufacturers Fabricantes de dispositivos
2018 	 * @return Lista de objetos de tipo Pkcs11Device
2019 	 * @throws IAIKDLLNotFoundException No es posible cargar la DLL de IAIK, por 
2020 	 * 	lo que no se puede trabajar con dispositivos PKCS#11
2021 	 */
2022 	protected static List<Pkcs11Device> getConnectedDevices (Pkcs11Manufacturer[] manufacturers) throws IAIKDLLNotFoundException   {
2023 		
2024 		logger.debug("[Pkcs11Manager.getConnectedDevices]::Entrada::" + manufacturers);
2025 		
2026 		//-- Al ser estático hay que mirar que exista la dll de IAIK
2027 		loadIAIKDllFile();
2028 		
2029 		//-- Buscar elementos para cada fabricante
2030 		List<Pkcs11Device> lDevices = new ArrayList<Pkcs11Device>();
2031 		for (int i=0;i<manufacturers.length;i++) {
2032 			try {
2033 				lDevices.addAll(manufacturers[i].getConnectedDevices());
2034 			} catch (Throwable e) {
2035 				logger.debug ("[Pkcs11Manager.getConnectedDevices]::No se han podido obtener los dispositivos para el " +
2036 						"fabricante " + manufacturers[i].getManufacturerName() +": " + e.getMessage());
2037 			} 
2038 		}
2039 			
2040 		//-- Devolver tabla
2041 		return lDevices;
2042 			
2043 	}
2044 
2045 	protected static MechanismInfo getSignatureMechanismInfo (Token token) throws TokenException  {
2046 		// check out what attributes of the keys we may set using the mechanism
2047 		// info
2048 		HashSet supportedMechanisms = new HashSet(Arrays.asList(token.getMechanismList()));
2049 
2050 		if (supportedMechanisms.contains(Mechanism.RSA_PKCS)) {
2051 			logger.debug("Mechanism.RSA_PKCS");
2052 			return token.getMechanismInfo(Mechanism.RSA_PKCS);
2053       
2054 		} else if (supportedMechanisms.contains(Mechanism.RSA_X_509)) {
2055 			logger.debug("Mechanism.RSA_X_509");
2056 			return token.getMechanismInfo(Mechanism.RSA_X_509);
2057       
2058 		} else if (supportedMechanisms.contains(Mechanism.RSA_9796)) {
2059 			logger.debug("Mechanism.RSA_9796");
2060 			return token.getMechanismInfo(Mechanism.RSA_9796);
2061       
2062 		} else if (supportedMechanisms.contains(Mechanism.RSA_PKCS_OAEP)) {
2063 			logger.debug("Mechanism.RSA_PKCS_OAEP");
2064 			return token.getMechanismInfo(Mechanism.RSA_PKCS_OAEP);
2065       
2066 		} else {
2067 			logger.debug("Mechanism --> null");
2068 			return null;
2069 		}
2070 		
2071 
2072 	}
2073 	
2074 	/**
2075 	 * Obtiene un keystore con el proveedor PKCS#11 de Sun para tratar con
2076 	 * el mismo dispositivo que está gestionando este manager.
2077 	 * 
2078 	 * @return Keystore Keystore PKCS#11
2079 	 * @throws InitializeProviderException No es posible inicializar el proveedor PKCS#11
2080 	 * @throws OpeningDeviceException Error abriendo el dispositivo con el proveedor PKCS11
2081 	 * @throws IncorrectPINException PIN incorrecto
2082 	 */
2083 	protected KeyStore getKeyStore () throws InitializeProviderException, OpeningDeviceException, IncorrectPINException {
2084 		logger.debug("[Pkcs11Manager.getKeyStore]::Entrada");
2085 		
2086 		//-- Nombre del provider de SUN
2087 		sunProviderName = this.device.getModuleName() + "-" + this.device.getToken().getSlot().getSlotID();
2088 		
2089 		//-- Obtener el path al fichero de la librería
2090 		int javaVersion = 6;
2091 		if (System.getProperty("java.version").indexOf(".") > -1) {
2092 			try {
2093 				javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[1]);
2094 			} catch (Exception e) {
2095 				logger.info("No se puede determinar la versión de Java: " + System.getProperty("java.version"));
2096 			}
2097 		} else {
2098 			try {
2099 				javaVersion = Integer.parseInt(System.getProperty("java.version"));
2100 			} catch (Exception e) {
2101 				logger.info("No se puede determinar la versión de Java: " + System.getProperty("java.version"));
2102 			}
2103 		}
2104 
2105 		String pathLibrary = new File (this.device.getManufacturer().getPkcs11LibPath()).getAbsolutePath();
2106 		if (javaVersion > 7) {
2107 			pathLibrary = "\"" + new File (this.device.getManufacturer().getPkcs11LibPath()).getAbsolutePath().replace('\\', '/') + "\"";
2108 		}
2109 		
2110 		//-- Obtener la configuración del provider de SUN
2111 		String configFile = "name=" + sunProviderName +
2112 			"\nlibrary=" + pathLibrary + 
2113 			"\nslot=" + this.device.getToken().getSlot().getSlotID() +
2114 			"\nshowInfo=true\n"; 
2115 		logger.debug("[Pkcs11Manager.getKeyStore]::Configuración::" + configFile);
2116 
2117 		//-- Iniciando proveedor
2118 		Provider provider;
2119 		try {
2120 			System.out.println (javaVersion);
2121 			if (javaVersion < 9) {
2122 				Class sunClass = Class.forName("sun.security.pkcs11.SunPKCS11");
2123 				Constructor constructor = sunClass.getConstructor(new Class[] { InputStream.class });
2124 				provider = (Provider)constructor.newInstance(new ByteArrayInputStream(configFile.getBytes()));
2125 			} else {
2126 				//-- Java 9
2127 				provider = Security.getProvider("SunPKCS11");
2128 				File file = File.createTempFile("sunpkcs11", ".xml");
2129 				Util.saveFile(file, configFile.getBytes());
2130 				Method method = Provider.class.getMethod("configure", String.class);
2131 				provider = (Provider) method.invoke(provider, new Object[] { file.getAbsolutePath() });
2132 				file.delete();
2133 			}
2134 			
2135 			sunProviderName = provider.getName();
2136 			if (Security.getProvider(provider.getName()) != null) {
2137 				Security.removeProvider(provider.getName());
2138 			}
2139 			Security.addProvider(provider);
2140 
2141 		} catch (Exception e) {
2142 			logger.info ("[Pkcs11Manager.getKeyStore]::No se ha podido iniciar el provider del módulo " + this.device.getModuleName() + ". Versión Java: " + System.getProperty("java.version") + "\nConfigFile:\n" + configFile, e);
2143 			throw new InitializeProviderException("No ha sido posible iniciar el proveedor de SUN", e);
2144 		} 
2145 		
2146 		//-- Abriendo el keystore
2147 	    try {
2148 		    KeyStore ks = KeyStore.getInstance("PKCS11", provider);
2149 		    ks.load(null, pin.toCharArray()); 
2150 			logger.debug("[Pkcs11Manager.getKeyStore]::Keystore abierto");
2151 			
2152 			return ks;
2153 		} catch (NoSuchAlgorithmException e1) {
2154 			logger.info("[Pkcs11Manager.getKeyStore]::No existe el algoritmo que comprueba la integridad del dispositivo", e1);
2155 			throw new OpeningDeviceException ("No existe el algoritmo que comprueba la integridad del dispositivo", e1);
2156 		} catch (CertificateException e1) {
2157 			logger.info("[Pkcs11Manager.getKeyStore]::Alguno de los certificados del dispositivo no puede ser guardado", e1);
2158 			throw new OpeningDeviceException ("Alguno de los certificados del dispositivo no puede ser guardado", e1);
2159 		} catch (IOException e1) {
2160 			logger.info("[Pkcs11Manager.getKeyStore]::El PIN introducido no es correcto", e1);
2161 			throw new IncorrectPINException ("El PIN introducido no es correcto", e1);
2162 		} catch (KeyStoreException e1) {
2163 			logger.info("[Pkcs11Manager.getKeyStore]::Error de keystore", e1);
2164 			throw new OpeningDeviceException ("Error de keystore", e1);
2165 		} catch (Exception e1) {
2166 			logger.info("[Pkcs11Manager.getKeyStore]::Error desconocido creando y abriendo el keystore PKCS11", e1);
2167 			throw new OpeningDeviceException ("Error desconocido creando y abriendo el keystore PKCS11", e1);
2168 		}
2169 
2170 	}
2171 
2172 	/*
2173 	 * Inicializa un gestor de PKCS#11 realizando previamente un proceso de 
2174 	 * autodetección de la tarjeta insertada el lector. En caso de que
2175 	 * hayan varios dispositivos conectados se elegirá el primero de ellos.
2176 	 * Este método se puede usar para el caso más habitual: que sólo exista
2177 	 * un dispositivo PKCS#11 conectado.
2178 	 * 
2179 	 * @param deviceType Lista de tipos de dispositivo a detectar por Arangi.
2180 	 * @throws ModuleNotFoundException No se ha encontrado ningún módulo PKCS#11
2181 	 */
2182 	protected void initialize(String pin, boolean isPUK, Pkcs11Manufacturer[] manufacturers) throws ModuleNotFoundException, IAIKDLLNotFoundException, InitializeProviderException, OpeningDeviceException, IncorrectPINException, IncorrectPUKException, LockedPINException {
2183 		initialize(pin, isPUK, manufacturers, true);
2184 	}
2185 	
2186 	/*
2187 	 * Inicializa un gestor de PKCS#11 realizando previamente un proceso de 
2188 	 * autodetección de la tarjeta insertada el lector. En caso de que
2189 	 * hayan varios dispositivos conectados se elegirá el primero de ellos.
2190 	 * Este método se puede usar para el caso más habitual: que sólo exista
2191 	 * un dispositivo PKCS#11 conectado.
2192 	 * 
2193 	 * El parámetro withKeystore indica si se quiere cargar el keystore de
2194 	 * SUN. Si no se va a utilizar funciones como la firma no es necesario
2195 	 * cargarlo.
2196 	 * 
2197 	 * @param deviceType Lista de tipos de dispositivo a detectar por Arangi.
2198 	 * @throws ModuleNotFoundException No se ha encontrado ningún módulo PKCS#11
2199 	 */
2200 	protected void initialize(String pin, boolean isPUK, Pkcs11Manufacturer[] manufacturers, boolean withKeyStore) throws ModuleNotFoundException, IAIKDLLNotFoundException, InitializeProviderException, OpeningDeviceException, IncorrectPINException, IncorrectPUKException, LockedPINException {
2201 
2202 		//-- Autodetección de PKCS#11
2203 		logger.debug("Autodetectando fabricantes PKCS11...");
2204 		List<String> lManufacturers = new ArrayList<String> ();
2205 		List<Throwable> lExceptions = new ArrayList<Throwable> ();
2206 		for (int i = 0; i < manufacturers.length; i++) {
2207 			try {
2208 				logger.debug("Probando con " + manufacturers[i].getManufacturerName() + "...");
2209 				
2210 				this.device = manufacturers[i].getInstance(pin, isPUK);
2211 				
2212 				logger.debug("Probando con " + manufacturers[i].getManufacturerName() + "... OK.");
2213 				break;
2214 			} catch (ModuleNotFoundException e) {
2215 				lManufacturers.add(manufacturers[i].getManufacturerName());
2216 				lExceptions.add (e);
2217 			} catch (DeviceNotFoundException e) {
2218 				lManufacturers.add(manufacturers[i].getManufacturerName());
2219 				lExceptions.add (e);
2220 			} catch (IncorrectPINException e) {
2221 				logger.info("PIN Incorrecto", e);
2222 				throw e;
2223 			} catch (IncorrectPUKException e) {
2224 				logger.info("PUK Incorrecto", e);
2225 				throw e;
2226 			} catch (LockedPINException e) {
2227 				logger.info("PIN bloqueado", e);
2228 				throw e;
2229 			} catch (Throwable t) {
2230 				// Probablemente no estemos en Windows y no se pueda linkar la dll de IAIK
2231 				lManufacturers.add(manufacturers[i].getManufacturerName());
2232 				lExceptions.add (t);
2233 			}
2234 		}
2235 		if (this.device == null){
2236 			for (int i=0;i<lManufacturers.size();i++) {
2237 				logger.debug("Excepción cargando módulo del fabricante '" + lManufacturers.get(i) + "'", (Throwable) lExceptions.get(i));
2238 			}
2239 			logger.info("Token nulo tras autodetección. ¡ERROR! ¡Ningún fabricante de la lista por defecto ha sido encontrado!");
2240 			throw new ModuleNotFoundException("Ha fallado la la autodetección de un módulo PKCS#11 conectado al equipo");
2241 		}
2242 		
2243 		this.pin = pin;
2244 		this.openWithPuk = isPUK;
2245 
2246 		logger.debug("Autodetectando fabricantes PKCS11...OK");
2247 		
2248 		//-- Obtener el keystore
2249 		if (!isPUK && withKeyStore) {
2250 			this.keystore = getKeyStore();
2251 		}
2252 
2253 	}
2254 	
2255 	/*
2256 	 * Inicializa un gestor de PKCS#11 usando la implementación del PKCS#11 
2257  	 * indicado. En caso de que hayan varios dispositivos conectados se 
2258  	 * elegirá el primero de ellos. Este método se puede usar para el caso 
2259  	 * más habitual: que sólo exista un dispositivo PKCS#11 conectado.
2260 	 * 
2261 	 * @param pkcs11LibPath Path a la librería PKCS#11
2262 	 * 
2263 	 * @throws DeviceNotFoundException No existen dispositivos para la 
2264 	 * 	libería PKCS#11 o no existe un dispositivo para el valor de 'tokenID'.
2265 	 * @throws ModuleNotFoundException No se ha encontrado ningún módulo PKCS#11
2266 	 * 	de la lista.
2267 	 */
2268 	protected void initialize (String pin, boolean isPUK, Pkcs11Manufacturer manufacturer) throws DeviceNotFoundException, ModuleNotFoundException, IAIKDLLNotFoundException, IncorrectPINException, IncorrectPUKException, LockedPINException, OpeningDeviceException, InitializeProviderException {
2269 		initialize(pin, isPUK, manufacturer, true);
2270 	}
2271 	
2272 	/*
2273 	 * Inicializa un gestor de PKCS#11 usando la implementación del PKCS#11 
2274  	 * indicado. En caso de que hayan varios dispositivos conectados se 
2275  	 * elegirá el primero de ellos. Este método se puede usar para el caso 
2276  	 * más habitual: que sólo exista un dispositivo PKCS#11 conectado.
2277 	 * 
2278 	 * El parámetro withKeystore indica si se quiere cargar el keystore de
2279 	 * SUN. Si no se va a utilizar funciones como la firma no es necesario
2280 	 * cargarlo.
2281 	 * 
2282 	 * @param pkcs11LibPath Path a la librería PKCS#11
2283 	 * 
2284 	 * @throws DeviceNotFoundException No existen dispositivos para la 
2285 	 * 	libería PKCS#11 o no existe un dispositivo para el valor de 'tokenID'.
2286 	 * @throws ModuleNotFoundException No se ha encontrado ningún módulo PKCS#11
2287 	 * 	de la lista.
2288 	 */
2289 	protected void initialize (String pin, boolean isPUK, Pkcs11Manufacturer manufacturer, boolean withKeyStore) throws DeviceNotFoundException, ModuleNotFoundException, IAIKDLLNotFoundException, IncorrectPINException, IncorrectPUKException, LockedPINException, OpeningDeviceException, InitializeProviderException {
2290 
2291 		//-- Carga explícita
2292 		this.device = manufacturer.getInstance(pin, isPUK);
2293 		
2294 		this.pin = pin;
2295 		this.openWithPuk = isPUK;
2296 		logger.debug("Cargando módulo para el fabricante PKCS#11 ``" + manufacturer + "´´... OK");
2297 		
2298 		//-- Obtener el keystore si se accede con PIN. Con PUK no se puede firmar, así
2299 		//-- que no se necesita acceder a claves privadas
2300 		if (!isPUK && withKeyStore) {
2301 			this.keystore = getKeyStore();
2302 		}
2303 		
2304 	}
2305 
2306 	/*
2307 	 * Inicializa un gestor de PKCS#11 usando un dispositivo concero. 
2308 	 * 
2309 	 * @param device Dispositivo a inicializar
2310 	 * @param password
2311 	 * @param isPUK Cierto si se abre con el PUK
2312 	 * 
2313 	 * @throws DeviceNotFoundException No existen dispositivos para la 
2314 	 * 	libería PKCS#11 o no existe un dispositivo para el valor de 'tokenID'.
2315 	 * @throws ModuleNotFoundException No se ha encontrado ningún módulo PKCS#11
2316 	 * 	de la lista.
2317 	 */
2318 	protected void initialize (Pkcs11Device device, String password, boolean isPUK) throws DeviceNotFoundException, ModuleNotFoundException, IAIKDLLNotFoundException, IncorrectPINException, IncorrectPUKException, LockedPINException, OpeningDeviceException, InitializeProviderException {
2319 		initialize(device, password, isPUK, true);
2320 	}
2321 	
2322 	/*
2323 	 * Inicializa un gestor de PKCS#11 usando un dispositivo concero. 
2324 	 * 
2325 	 * El parámetro withKeystore indica si se quiere cargar el keystore de
2326 	 * SUN. Si no se va a utilizar funciones como la firma no es necesario
2327 	 * cargarlo.
2328 	 * 
2329 	 * @param device Dispositivo a inicializar
2330 	 * @param password
2331 	 * @param isPUK Cierto si se abre con el PUK
2332 	 * 
2333 	 * @throws DeviceNotFoundException No existen dispositivos para la 
2334 	 * 	libería PKCS#11 o no existe un dispositivo para el valor de 'tokenID'.
2335 	 * @throws ModuleNotFoundException No se ha encontrado ningún módulo PKCS#11
2336 	 * 	de la lista.
2337 	 */
2338 	protected void initialize (Pkcs11Device device, String password, boolean isPUK, boolean withKeyStore) throws DeviceNotFoundException, ModuleNotFoundException, IAIKDLLNotFoundException, IncorrectPINException, IncorrectPUKException, LockedPINException, OpeningDeviceException, InitializeProviderException {
2339 
2340 		//-- Abrir el dispositivo
2341 		this.device = device.getManufacturer().getInstance(device.getId(), password, isPUK);
2342 		this.pin = password;
2343 		this.openWithPuk = isPUK;
2344 		if (!isPUK && withKeyStore) {
2345 			this.keystore = getKeyStore();
2346 		}
2347 		
2348 	}
2349 
2350 }