Java tutorial
/* * Portions of this file Copyright 1999-2005 University of Chicago * Portions of this file Copyright 1999-2005 The University of Southern California. * * This file or a portion of this file is licensed under the * terms of the Globus Toolkit Public License, found at * http://www.globus.org/toolkit/download/license.html. * If you redistribute this file, with or without * modifications, you must include this notice in the file. */ package org.globus.gsi.ptls; import java.util.Vector; import java.util.Arrays; import java.io.ByteArrayInputStream; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; import java.security.cert.CertificateFactory; import org.globus.common.ChainedGeneralSecurityException; import org.globus.gsi.GSIConstants; import COM.claymoresystems.cert.X509Cert; import COM.claymoresystems.cert.X509Name; import COM.claymoresystems.sslg.DistinguishedName; import COM.claymoresystems.sslg.CertVerifyPolicyInt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A collection of utility functions for PureTLS library. */ public class PureTLSUtil { private static Log logger = LogFactory.getLog(PureTLSUtil.class.getName()); static { PureTLSContext.init(); } /** * Converts PureTLS specific X509 certificate object * into standard Java X509 certificate object * (right now it is using BouncyCastle provider to * convert). * * @param cert PureTLS X509 certificate object * @return standard Java X509 certificate object * @exception GeneralSecurityException if conversion fails. */ public static X509Certificate convertCert(X509Cert cert) throws GeneralSecurityException { CertificateFactory f = CertificateFactory.getInstance("X.509", "BC"); ByteArrayInputStream in = new ByteArrayInputStream(cert.getDER()); return (X509Certificate) f.generateCertificate(in); } /** * Converts Globus formatted string into a X509Name * object. * * @param globusID Globus-formatted subject to convert. * @return the X509Name object. * @exception if conversion fails. */ public static X509Name getX509Name(String globusID) throws Exception { Vector dn = new Vector(); int off = 0; int start = 0; boolean done = false; while (!done) { int pos1 = globusID.indexOf('=', off); if (pos1 == -1) { throw new Exception("Malformed name, '=' missing in : " + globusID); } Vector rdn = null; start = pos1 + 1; for (;;) { int pos2 = globusID.indexOf('=', pos1 + 1); if (pos2 == -1) { rdn = parseRDN(globusID.substring(off)); done = true; break; } else { int pos3 = globusID.lastIndexOf('/', pos2); if (pos3 != -1) { if (pos3 <= pos1) { pos1 = pos2; } else { rdn = parseRDN(globusID.substring(off, pos3)); off = pos3; break; } } else { throw new Exception("Malformed name, '/' missing in : " + globusID); } } } if (rdn != null) { dn.addElement(rdn); } } return new X509Name(dn); } private static Vector parseRDN(String token) throws Exception { if (token.charAt(0) != '/') { throw new Exception("Token does not start with '/': " + token); } Vector rdn = null; int pos = token.indexOf('+'); if (pos == -1) { rdn = new Vector(1); rdn.addElement(getAVA(token.substring(1))); } else { rdn = new Vector(2); rdn.addElement(getAVA(token.substring(1, pos))); rdn.addElement(getAVA(token.substring(pos + 1))); } return rdn; } private static String[] getAVA(String rdn) throws Exception { int pos = rdn.indexOf('='); if (pos == -1) { throw new Exception("RDN is missing '=': " + rdn); } String[] ava = new String[2]; ava[0] = rdn.substring(0, pos).trim().toUpperCase(); ava[1] = rdn.substring(pos + 1).trim(); return ava; } /** * Returns the base name of a proxy. Strips all * "cn=proxy" or "cn=limited proxy" components. * * @deprecated Only works with Globus legacy proxies. */ public static X509Name getBase(DistinguishedName name) { X509Name nm = dupName(name); Vector dn = nm.getName(); int len = dn.size(); for (int i = len - 1; i >= 0; i--) { Vector rdn = (Vector) dn.elementAt(i); // checks only first ava entry String[] ava = (String[]) rdn.elementAt(0); if (ava[0].equalsIgnoreCase("CN") && (ava[1].equalsIgnoreCase("proxy") || ava[1].equalsIgnoreCase("limited proxy"))) { dn.removeElementAt(i); } else { break; } } return new X509Name(dn); } /** * Returns proxy name. * * @deprecated Only works for Globus legacy proxies. */ public static int checkProxyName(X509Cert cert) { int rs = -1; DistinguishedName subject = dupName(cert.getSubjectName()); Vector subjectDN = subject.getName(); Vector lastAva = (Vector) subjectDN.elementAt(subjectDN.size() - 1); String[] ava = (String[]) lastAva.elementAt(0); if (ava[0].equalsIgnoreCase("CN")) { if (ava[1].equalsIgnoreCase("proxy")) { rs = GSIConstants.GSI_2_PROXY; } else if (ava[1].equalsIgnoreCase("limited proxy")) { rs = GSIConstants.GSI_2_LIMITED_PROXY; } if (rs != -1) { Vector nameDN = dupName(cert.getIssuerName()).getName(); nameDN.addElement(lastAva); X509Name newName = new X509Name(nameDN); return (Arrays.equals(subject.getNameDER(), newName.getNameDER())) ? rs : -1; } } return rs; } /** * Replicates a X509Name object. * * @param name X509Name object to replicate. * @return the replicated object. */ public static X509Name dupName(DistinguishedName name) { return new X509Name(name.getName()); } /** * Converts standard Java X509 certificate array into a Vector * of X509Cert objects (in the reverse order) * * @param certs certificate array to convert. * @return the converted Vector of X509Cert objects. Null if * <code>certs</code> array was null. * @exception GeneralSecurityException if conversion fails. */ public static Vector certificateChainToVector(X509Certificate[] certs) throws GeneralSecurityException { if (certs == null) { return null; } Vector v = new Vector(certs.length); try { for (int i = certs.length - 1; i >= 0; i--) { v.addElement(new X509Cert(certs[i].getEncoded())); } } catch (Exception e) { throw new ChainedGeneralSecurityException("Conversion failed", e); } return v; } /** * Converts a Vector of X509Cert objects into a standard * Java X509 certificate array (in the reverse order). * * @param chain the Vector of X509Cert objects to convert. * @return the converted X509 certificate array * @exception GeneralSecurityException if conversion fails. */ public static X509Certificate[] certificateChainToArray(Vector chain) throws GeneralSecurityException { int size = chain.size(); X509Certificate[] certs = new X509Certificate[size]; for (int i = 0; i < size; i++) { certs[i] = convertCert((X509Cert) chain.elementAt(size - 1 - i)); } return certs; } /** * Returns a default certificate checking policy. * This is not used as much as the certificate checking * was mostly abstracted out from PureTLS code and * moved into {@link org.globus.gsi.proxy.ProxyPathValidator * ProxyPathValidator}. * * @return the default certificate checking policy. */ public static CertVerifyPolicyInt getDefaultCertVerifyPolicy() { CertVerifyPolicyInt certPolicy = new CertVerifyPolicyInt(); // we do validation checking now certPolicy.checkDates(false); certPolicy.requireBasicConstraints(false); certPolicy.requireBasicConstraintsCritical(false); certPolicy.requireKeyUsage(false); return certPolicy; } /** * Returns the Globus formatted representation of the * subject DN of the specified certificate. * * @param cert the encoded certificate * @return the Globus formatted representation of the * subject DN. * @exception Exception if something goes wrong. * @deprecated Only works with Globus legacy proxies. */ public static String getGlobusId(byte[] cert) throws Exception { X509Cert crt = new X509Cert(cert); DistinguishedName subject = PureTLSUtil.getBase(crt.getSubjectName()); return toGlobusID(subject); } /** * Returns the Globus formatted representation of the * subject DN of the specified DN. * * @param subject the DN * @return the Globus formatted representation of the * subject DN. */ public static String toGlobusID(DistinguishedName subject) { Vector dn = subject.getName(); int len = dn.size(); StringBuffer buf = new StringBuffer(); for (int i = 0; i < len; i++) { Vector rdn = (Vector) dn.elementAt(i); // checks only first ava entry String[] ava = (String[]) rdn.elementAt(0); buf.append('/').append(ava[0]).append('=').append(ava[1]); } return buf.toString(); } /* import cryptix.provider.rsa.BaseRSAPrivateKey; import cryptix.provider.rsa.BaseRSAPublicKey; import COM.claymoresystems.cert.X509RSAPublicKey; // Convert Cryptix BaseRSAPrivateKey into RSAPrivateKey new WrappedRSAPrivateKey((BaseRSAPrivateKey)privateKey) // Convert Cryptix BaseRSAPublicKey into X509RSAPublicKey new X509RSAPublicKey(((BaseRSAPublicKey)keyPair.getPublic())), */ }