Java tutorial
/** * LICENCIA LGPL: * * Esta librera es Software Libre; Usted puede redistribuirlo y/o modificarlo * bajo los trminos de la GNU Lesser General Public License (LGPL) * tal y como ha sido publicada por la Free Software Foundation; o * bien la versin 2.1 de la Licencia, o (a su eleccin) cualquier versin posterior. * * Esta librera se distribuye con la esperanza de que sea til, pero SIN NINGUNA * GARANT?A; tampoco las implcitas garantas de MERCANTILIDAD o ADECUACIN A UN * PROPSITO PARTICULAR. Consulte la GNU Lesser General Public License (LGPL) para ms * detalles * * Usted debe recibir una copia de la GNU Lesser General Public License (LGPL) * junto con esta librera; si no es as, escriba a la Free Software Foundation Inc. * 51 Franklin Street, 5 Piso, Boston, MA 02110-1301, USA o consulte * <http://www.gnu.org/licenses/>. * * Copyright 2008 Ministerio de Industria, Turismo y Comercio * */ package es.mityc.firmaJava.libreria.utilidades; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.x509.PolicyInformation; import es.mityc.firmaJava.libreria.ConstantesXADES; /** * Funciones de utilidades varias * * @author Ministerio de Industria, Turismo y Comercio * @version 0.9 beta */ public class UtilidadFirmaElectronica implements ConstantesXADES { static Log log = LogFactory.getLog(UtilidadFirmaElectronica.class); /** * Decodifica una cadena a UTF-8 * @param input Cadena a decodificar * @return cadena en UTF-8 */ public static String decodeUTF(byte[] input) { int longitud = input.length; char[] output = new char[longitud]; int i = 0; int j = 0; while (i < longitud) { int b = input[i++] & 0xff; // clasificado segn el alto orden de 3 bits switch (b >>> 5) { default: // codificacin del 1 byte // 0xxxxxxx // uso justo de orden bajo de 7 bits // 00000000 0xxxxxxx output[j++] = (char) (b & 0x7f); break; case 6: // codificacin del 2 byte // 110yyyyy 10xxxxxx // uso bajo de orden de 6 bits int y = b & 0x1f; // uso del orden bajo de 6 bits del byte siguiente // debe tener un orden alto de 10 bits, el cual no comprobaremos int x = input[i++] & 0x3f; // 00000yyy yyxxxxxx output[j++] = (char) (y << 6 | x); break; case 7: // codificacin del 3 byte // 1110zzzz 10yyyyyy 10xxxxxx // assert ( b & 0x10 ) // == 0 : "UTF8Decoder does not handle 32-bit characters"; if ((b & 0x10) == 0) { throw new RuntimeException(UTF8DECODER_ERROR); } // uso del orden bajo de 4 bits int z = b & 0x0f; // uso del orden bajo de 6 bits del siguiente byte // debera tener un orden alto de 10 bits, el cual no comprobaremos y = input[i++] & 0x3f; // uso bajo del orden de 6 bits del siguiente byte // debera tener un orden alto de 10 bits, el cual no comprobaremos x = input[i++] & 0x3f; // zzzzyyyy yyxxxxxx int asint = (z << 12 | y << 6 | x); output[j++] = (char) asint; break; } } return new String(output, 0, j); } /** * @param listaCertificadosTemp Lista de certificados temporales * @param emisorDN * @return */ public static Vector<X509Certificate> filtraCertificados(Vector<X509Certificate> listaCertificadosTemp, String emisorDN) { String[] allIssuers = emisorDN.split(ALMOHADILLA); Vector<X509Certificate> devuelveCertificados = new Vector<X509Certificate>(); int longitudCertificados = listaCertificadosTemp.size(); for (int a = 0; a < longitudCertificados; a++) { X509Certificate certTemp = listaCertificadosTemp.get(a); int longitudIssuers = allIssuers.length; for (int b = 0; b < longitudIssuers; b++) { if (certTemp.getIssuerDN().toString().indexOf(allIssuers[b]) >= 0) { devuelveCertificados.add(certTemp); break; } } } return devuelveCertificados; } /** * * @param listaCertificadosTemp Lista de certificados temporales * @return */ public static Vector<X509Certificate> filtraDNIe(Vector<X509Certificate> listaCertificadosTemp) { if (log.isTraceEnabled()) log.trace("Filtrando certificados del DNIe..."); Vector<X509Certificate> returnCertificates = new Vector<X509Certificate>(); ASN1InputStream asn1IS = null; int longitudCertificados = listaCertificadosTemp.size(); for (int a = 0; a < longitudCertificados; a++) { X509Certificate certTemp = listaCertificadosTemp.get(a); if (UtilidadDNIe.isCertDNIe(certTemp.getIssuerDN().toString())) { try { // El certificado de autenticacin tiene una certificate policy 2.16.724.1.2.2.2.4 // El certificado de firma tiene una certificate policy 2.16.724.1.2.2.2.3 // Recupera la certificate policy de este certificado byte[] policies = certTemp.getExtensionValue(CERTIFICATE_POLICIES_OID); if (policies != null) { //Falsos positivos asn1IS = new ASN1InputStream(policies); // Una extensin de certificado va como DER-encoded OCTET (ver getExtensionValue de X509Extension) ASN1OctetString ext = (ASN1OctetString) ((ASN1InputStream) asn1IS).readObject(); //asn1IS.close(); asn1IS = new ASN1InputStream(ext.getOctets()); ASN1Sequence seq = (ASN1Sequence) asn1IS.readObject(); // Solo hay una PolicyInformation para el DNIe PolicyInformation pi = new PolicyInformation((ASN1Sequence) seq.getObjectAt(0)); if (UtilidadDNIe.POLICY_OID_CERTIFICADO_AUTENTICACION_DNIE .equals(pi.getPolicyIdentifier().getId())) continue; } returnCertificates.add(certTemp); } catch (Exception ex) { returnCertificates.add(certTemp); } finally { if (asn1IS != null) { try { asn1IS.close(); } catch (IOException e) { log.error(e); } } } } else returnCertificates.add(certTemp); } return returnCertificates; } public static String obtenerTipoReference(String esquema) { String tipoEsquema = null; if ((SCHEMA_XADES_132).equals(esquema)) tipoEsquema = SCHEMA_XADES + SIGNED_PROPERTIES; else if ((SCHEMA_XADES_122).equals(esquema)) tipoEsquema = SCHEMA_XADES_122 + SIGNED_PROPERTIES; else if ((SCHEMA_XADES_111).equals(esquema)) tipoEsquema = SCHEMA_XADES_111 + SIGNED_PROPERTIES; else { log.error(I18n.getResource(LIBRERIAXADES_VALIDARFIRMA_ERROR1)); return null; } return tipoEsquema; } // TODOLARGO: incluir tambin los OIDs private static final String DIGEST_ALG_SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1"; private static final String DIGEST_ALG_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#sha256"; private static final String DIGEST_ALG_SHA256_enc = "http://www.w3.org/2001/04/xmlenc#sha256"; private static final String DIGEST_ALG_SHA256_hmac = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"; private static final String DIGEST_ALG_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#sha512"; private static final String DIGEST_ALG_SHA512_enc = "http://www.w3.org/2001/04/xmlenc#sha512"; private static final String DIGEST_ALG_SHA512_hmac = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"; private static final String DIGEST_ALG_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#sha224"; private static final String DIGEST_ALG_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384"; private static final String DIGEST_ALG_MD2 = "http://www.w3.org/2001/04/xmldsig-more#md2"; private static final String DIGEST_ALG_MD4 = "http://www.w3.org/2001/04/xmldsig-more#md4"; private static final String DIGEST_ALG_MD5 = "http://www.w3.org/2001/04/xmldsig-more#md5"; private static final String DIGEST_ALG_RIPEMD128 = "http://www.w3.org/2001/04/xmldsig-more#ripemd128"; private static final String DIGEST_ALG_RIPEMD160 = "http://www.w3.org/2001/04/xmldsig-more#ripemd160"; private static final String DIGEST_ALG_RIPEMD256 = "http://www.w3.org/2001/04/xmldsig-more#ripemd256"; private static final String DIGEST_ALG_RIPEMD320 = "http://www.w3.org/2001/04/xmldsig-more#ripemd320"; private static final String DIGEST_ALG_TIGER = "http://www.w3.org/2001/04/xmldsig-more#tiger"; private static final String DIGEST_ALG_WHIRLPOOL = "http://www.w3.org/2001/04/xmldsig-more#whirlpool"; private static final String DIGEST_ALG_GOST3411 = "http://www.w3.org/2001/04/xmldsig-more#gost3411"; /** * Devuelve el MessageDigest asociado a la uri (segn la rfc 3275 y la rfc 4051). * * @param uri Uri que define el algoritmo de digest (segn las rfc 3275 y 4051). * @return MessageDigest asociado o null si no hay ninguno disponible para el algoritmo indicado. */ public static MessageDigest getMessageDigest(String uri) { MessageDigest md = null; if (uri != null) { try { if (uri.equals(DIGEST_ALG_SHA1)) md = MessageDigest.getInstance("SHA-1"); else if (uri.equals(DIGEST_ALG_SHA256) || uri.equals(DIGEST_ALG_SHA256_enc) || uri.equals(DIGEST_ALG_SHA256_hmac)) md = MessageDigest.getInstance("SHA-256"); else if (uri.equals(DIGEST_ALG_SHA512) || uri.equals(DIGEST_ALG_SHA512_enc) || uri.equals(DIGEST_ALG_SHA512_hmac)) md = MessageDigest.getInstance("SHA-512"); else if (uri.equals(DIGEST_ALG_SHA224)) md = MessageDigest.getInstance("SHA-224"); else if (uri.equals(DIGEST_ALG_SHA384)) md = MessageDigest.getInstance("SHA-384"); else if (uri.equals(DIGEST_ALG_MD2)) md = MessageDigest.getInstance("MD2"); else if (uri.equals(DIGEST_ALG_MD4)) md = MessageDigest.getInstance("MD4"); else if (uri.equals(DIGEST_ALG_MD5)) md = MessageDigest.getInstance("MD5"); else if (uri.equals(DIGEST_ALG_RIPEMD128)) md = MessageDigest.getInstance("RIPEDM128"); else if (uri.equals(DIGEST_ALG_RIPEMD160)) md = MessageDigest.getInstance("RIPEMD160"); else if (uri.equals(DIGEST_ALG_RIPEMD256)) md = MessageDigest.getInstance("RIPEMD256"); else if (uri.equals(DIGEST_ALG_RIPEMD320)) md = MessageDigest.getInstance("RIPEMD320"); else if (uri.equals(DIGEST_ALG_TIGER)) md = MessageDigest.getInstance("Tiger"); else if (uri.equals(DIGEST_ALG_WHIRLPOOL)) md = MessageDigest.getInstance("WHIRLPOOL"); else if (uri.equals(DIGEST_ALG_GOST3411)) md = MessageDigest.getInstance("GOST3411"); } catch (NoSuchAlgorithmException ex) { log.info("Algoritmo de digest no disponible para: " + uri, ex); } } return md; } }