Java tutorial
/* * Copyright (c) Members of the EGEE Collaboration. 2004. See * http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.glite.security.delegation; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; //import java.security.cert.CRLException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; import org.apache.log4j.Logger; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.jce.provider.JDKKeyPairGenerator; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.glite.security.SecurityContext; import org.glite.security.delegation.storage.GrDPStorageFactory; import org.glite.security.util.PrivateKeyReader; import org.italiangrid.voms.VOMSAttribute; //import org.glite.voms.PKIStore; //import org.glite.voms.ac.ACValidator; import org.italiangrid.voms.VOMSValidators; /** * Utility to manage X509 certificates * * @author Mehran Ahsant * @author Akos Frohner <Akos.Frohner@cern.ch> * @author Joni Hahkala */ public class GrDPX509Util { private final static Logger LOGGER = Logger.getLogger(GrDPX509Util.class); public static final String CERT_CHAIN_CONTENT_TYPE = "application/x-x509-user-cert-chain"; public static final String CERT_REQ_CONTENT_TYPE = "application/x-x509-cert-request"; private static MessageDigest s_digester = null; /** static PKIStore to avoid initializing it for every request */ // private static PKIStore s_trustStore; /** The path to the CA trust directory.*/ // private static final String CA_PATH_PROPERTY = "CA_PATH"; /** the default CA trust directory. */ // private static final String CA_PATH_DEFAULT = "/etc/grid-security/certificates/"; static { LOGGER.info("initalizing ACValidator"); try { s_digester = MessageDigest.getInstance("SHA-1"); } catch (Exception e) { LOGGER.fatal("Message digester implementation not found: " + e.getMessage(), e); throw new RuntimeException("Delegation utilities code initialization failed: " + e.getMessage(), e); } /* String location = System.getProperty(CA_PATH_PROPERTY, CA_PATH_DEFAULT); try { LOGGER.info("initalizing pkistore"); s_trustStore = new PKIStore(location, PKIStore.TYPE_CADIR, true); LOGGER.info("initalized"); } catch (CertificateException e) { LOGGER.fatal("Voms trustStore initialization failed: " + e.getMessage(), e); throw new RuntimeException("Voms trust anchors loading failed: " + e.getMessage()); } catch (CRLException e) { LOGGER.fatal("Voms trustStore initialization failed: " + e.getMessage(), e); throw new RuntimeException("Voms trust anchors loading failed: " + e.getMessage()); } catch (IOException e) { LOGGER.fatal("Voms trustStore initialization failed: " + e.getMessage(), e); throw new RuntimeException("Voms trust anchors loading failed: " + e.getMessage()); } */ } //------------------- following code is deprecated and will be removed // TODO: marker /** * Generate a PEM encoded string of certificate from a header and a footer * @param bytes input stream * @param hdr Header delimeter of certificate * @param ftr footer delimeter of certificate * @return encoded byte in pem * @throws IOException * @deprecated Use org.bouncycastle.openssl.PEMWriter */ public static String writePEM(byte[] bytes, String hdr, String ftr) { StringBuffer buff = new StringBuffer(); byte[] pemBytes = Base64.encode(bytes); buff.append(hdr); int n = 0; while (n < pemBytes.length) { if ((pemBytes.length - n) < 64) { buff.append(new String(pemBytes, n, pemBytes.length - n)); } else { buff.append(new String(pemBytes, n, 64)); } buff.append("\n"); n = n + 64; } buff.append(ftr); return buff.toString(); } /** * Read a PEM encoded base64 stream and decode it * @param is Base64 PEM encoded stream * @param hdr Header delimeter * @param ftr Footer delimeter * @return decoded DER bytes * @throws IOException if a read error occurs * @deprecated Use org.glite.security.util.FileCertReader */ public static byte[] readPEM(InputStream is, String hdr, String ftr) throws IOException { InputStreamReader irr = new InputStreamReader(is); BufferedReader r = new BufferedReader(irr); StringBuffer buff = new StringBuffer(); String line; boolean read = false; while ((line = r.readLine()) != null) { if (line.equals(hdr)) { read = true; continue; } if (line.equals(ftr)) { read = false; } if (read) { buff.append(line); } } return Base64.decode(buff.toString().getBytes()); } /** * Read a PEM encoded base64 stream and decode it * @param in Base64 PEM encoded string * @param hdr Header delimeter * @param ftr Footer delimeter * @return decoded DER bytes * @throws IOException if a read error occurs * @deprecated Use org.bouncycastle.openssl.PEMWriter */ public static byte[] readPEM(String in, String hdr, String ftr) { int hdrIndex = in.indexOf(hdr); hdrIndex += hdr.length(); int ftrIndex = in.indexOf(ftr, hdrIndex); return Base64.decode(in.substring(hdrIndex, ftrIndex).getBytes()); } /** * Create an X509 Certificate DN * @param organization Organization * @param orgUnit Organization Unit * @param commonName X509 Common Name * @param country Country * @param email Email address * @return X509Name of generated DN * @deprecated Use org.glite.security.util.proxy.ProxyCertificateGenerator */ public static X509Name makeGridCertDN(String organization, String orgUnit, String commonName, String country, String email) { Hashtable attrs = new Hashtable(); attrs.put(X509Name.O, organization); attrs.put(X509Name.OU, orgUnit); attrs.put(X509Name.C, country); attrs.put(X509Name.EmailAddress, email); attrs.put(X509Name.CN, commonName); X509Name x509Name = new X509Name(attrs); LOGGER.debug("GrDPX509Util : " + x509Name.toString()); return x509Name; } /** * Create an X509 Certificate DN * @param DN The client's distiungished name. * @return X509Name of DN * @deprecated Use org.glite.security.util.proxy.ProxyCertificateGenerator */ public static X509Name makeGridCertDN(String DN) { X509Name x509Name = new X509Name(DN); LOGGER.debug("GrDPX509Util : " + x509Name.toString()); return x509Name; } /** * Save a certificate request in specific location * @param certReq given certificate request to save * @param fileLocation location of certificare request * @throws IOException * @deprecated Use delegation storage, don't write to file. */ public static void saveCertReqToFile(String certReq, String fileLocation) throws IOException { FileOutputStream os = new FileOutputStream(fileLocation); os.write(certReq.getBytes()); os.close(); } /** * save a proxy certificate in specific location * @param certProxy Given proxy certificate to save * @param fileLocation location of proxy certificate * @deprecated use org.glite.security.util.proxy.ProxyCertificateGenerator */ public static void saveCertProxyTofile(X509Certificate certProxy, String fileLocation) { try { OutputStream os = new FileOutputStream(fileLocation); if (!changeFileMode(fileLocation, 600)) { LOGGER.error("Warning: Please check file permissions for your proxy file."); } String s = GrDPX509Util.writePEM(certProxy.getEncoded(), GrDPConstants.CH + GrDPConstants.NEWLINE, GrDPConstants.CF + GrDPConstants.NEWLINE); os.write(s.getBytes()); os.close(); } catch (IOException ie) { LOGGER.error("Error saving certt to file" + ie.getMessage()); } catch (CertificateEncodingException e) { LOGGER.error("Error writePEM " + e.getMessage()); } } /** * save a proxy certificate in specific location * @param certProxy Given proxy certificate to save * @param fileLocation location of proxy certificate * @param delegationID * @param userDN * @deprecated use org.glite.security.util.proxy.ProxyCertificateGenerator. */ public static void saveCertProxyTofile(String inCertProxy, String fileLocation, String delegationID, String userDN, @SuppressWarnings("unused") boolean append) { String crt = null; String certProxyChain = null; String ENDCERT = GrDPConstants.CF; String certProxy = inCertProxy; try { RandomAccessFile f = new RandomAccessFile(fileLocation, "rw"); byte[] privateKeyByte = new byte[(int) f.length()]; f.read(privateKeyByte); f.seek(0); certProxy = delegationID + "\n" + //userDN.replaceAll("," + GrDPConstants.CNPROXY, "\0") + "\n" + userDN.replaceAll(GrDPConstants.CNPROXY + ",", "") + "\n" + certProxy; crt = certProxy.substring(0, certProxy.indexOf(ENDCERT) + ENDCERT.length() + 1); certProxyChain = certProxy.substring(certProxy.indexOf(ENDCERT) + ENDCERT.length(), certProxy.length()); f.writeBytes(crt); f.write(privateKeyByte); f.writeBytes(certProxyChain); f.close(); } catch (Exception e) { e.printStackTrace(); } if (!changeFileMode(fileLocation, 600)) { LOGGER.error("Warning: Please check file permissions for your proxy file."); } } /** * save a private key in specific location * @param pk Given private key to save * @param fileLocation location of private key * @param delegationID the ID of the delegation * @param userDN the DN of the client's certificate * @deprecated Use delegation storage. */ public static void savePrivateKey(PrivateKey pk, String fileLocation, String delegationID, String userDN) throws FileNotFoundException, IOException { String prvkey = null; prvkey = GrDPX509Util.writePEM(PrivateKeyReader.getEncoded(pk), GrDPConstants.PRVH + GrDPConstants.NEWLINE, GrDPConstants.PRVF + GrDPConstants.NEWLINE); prvkey = delegationID + "\n" + userDN.replaceAll("," + GrDPConstants.CNPROXY, "\0") + "\n" + prvkey; FileOutputStream os = new FileOutputStream(fileLocation); os.write(prvkey.getBytes()); os.close(); } /** * Search for a generated proxy in cache * @param strDirCache cache directory * @param delegationID Delegation ID * @param userDN UserDN * @return File name of proxy * @deprecated Use delegation storage. */ public static String findProxyInCache(String strDirCache, String delegationID, String userDN) { File dir = new File(strDirCache); FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir1, String name) { return !name.startsWith("."); } }; String[] proxyfilesList = dir.list(filter); if (proxyfilesList == null) { LOGGER.error("Error : No file in proxy cache"); } else { for (int i = 0; i < proxyfilesList.length; i++) { String filename = proxyfilesList[i]; try { BufferedReader in = new BufferedReader(new FileReader(dir.getPath() + "/" + filename)); if ((in.readLine()).equals(delegationID)) { if ((in.readLine().equals(userDN))) { in.close(); //return (dir.getPath()+"/"+filename); return (filename); } } in.close(); } catch (IOException e) { LOGGER.error("Error in reading proxy file"); } } } return null; } /** * Search for associated private key in cache * @param strDirCache cache directory * @param delegationID Delegation ID * @param userDN UserDN * @return File name of private key * @deprecated Use delegation storage. */ public static String findPrivateKeyInCache(String strDirCache, String delegationID, String userDN) { File dir = new File(strDirCache); FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir1, String name) { return name.startsWith("."); } }; String[] proxyfilesList = dir.list(filter); if (proxyfilesList == null) { LOGGER.error("Error : No private key file in proxy cache"); } else { for (int i = 0; i < proxyfilesList.length; i++) { String filename = proxyfilesList[i]; try { BufferedReader in = new BufferedReader(new FileReader(dir.getPath() + "/" + filename)); //while ((str = in.readLine()) != null) { if ((in.readLine().equals(delegationID))) { if ((in.readLine().equals(userDN))) { in.close(); //return (dir.getPath()+"/"+filename); return (filename); } } in.close(); } catch (IOException e) { LOGGER.error("Error in reading private key file"); } } } return null; } /** * Load x509 certificate * @param cert certificate to load * @return X509 Certificate * @throws IOException * @throws GeneralSecurityException * @deprecated Use delegation storage or org.glite.security.util.FileCertReader. */ public static X509Certificate loadCertificate(InputStream cert) throws NoSuchProviderException { X509Certificate certificate = null; try { CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); certificate = (X509Certificate) cf.generateCertificate(cert); } catch (CertificateException e) { e.printStackTrace(); } return certificate; } /** * Load chain of certificates from byte * @param bCerts * @return Array of loaded certificates * @throws IOException * @throws GeneralSecurityException * @deprecated Use delegation storage or org.glite.security.util.FileCertReader. */ public static X509Certificate[] loadCertificateChain(byte[] bCerts) throws IOException, CertificateException, NoSuchProviderException { return loadCertificateChain(new BufferedInputStream(new ByteArrayInputStream(bCerts))); } /** * Load a chain of certificates from BIS * @param bisCerts * @return Array of loaded certificates * @throws IOException * @throws GeneralSecurityException * @deprecated Use delegation storage or org.glite.security.util.FileCertReader. */ public static X509Certificate[] loadCertificateChain(BufferedInputStream bisCerts) throws IOException, CertificateException, NoSuchProviderException { Vector certVector = new Vector(); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); while (bisCerts.available() > 0) { //certificate[index++] = (X509Certificate) cf.generateCertificate(bisCerts); certVector.add(cf.generateCertificate(bisCerts)); } X509Certificate[] certificate = new X509Certificate[certVector.size()]; certVector.copyInto(certificate); return certificate; } /** * Reconstruct a certificate request from a PEM encoded string. * @param request BASE64 PEM encoded string * @return certificate request * @deprecated Use delegation storage or org.glite.security.util.FileCertReader. */ public static PKCS10CertificationRequest loadCertificateRequest(String request) { return new PKCS10CertificationRequest(readPEM(request, GrDPConstants.CRH + GrDPConstants.NEWLINE, GrDPConstants.CRF + GrDPConstants.NEWLINE)); } /** * Returns converted byte array input to hex value * @param input * @return Hex value * @deprecated Use org.bouncycastle.util.encoders.Hex */ /* static private String convertToHex(byte[] input) { StringBuffer result = new StringBuffer(); char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; for (int index = 0; index < input.length; ++index) { byte b = input[index]; result.append(digits[(b & 0xf0) >> 4]); result.append(digits[b & 0x0f]); } return result.toString(); } */ /** * Reading IO file in byte * @param file File name * @return File contents in byte * @throws IOException * @deprecated use relevant functions in util-java or bouncycastle. */ public static byte[] getFilesBytes(File file) throws IOException { InputStream is = new FileInputStream(file); long length = file.length(); if (length > Integer.MAX_VALUE) { LOGGER.error("getFilesBytes :: File is too long to read !"); } byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while ((offset < bytes.length) && ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) { offset += numRead; } if (offset < bytes.length) { throw new IOException("Uncomplete file reading " + file.getName()); } is.close(); return bytes; } /** * Convert array of x509certificates into byte format of PEMs * @param x509Cert * @return x509Certificates in byte format * @deprecated use org.glite.security.util.proxy.ProxyCertificateGenerator. */ public static byte[] certChainToByte(X509Certificate[] x509Cert) throws CertificateEncodingException { String strX509CertChain = ""; for (int index = 0; index < x509Cert.length; ++index) { strX509CertChain = strX509CertChain + GrDPX509Util.writePEM(x509Cert[index].getEncoded(), GrDPConstants.CH + GrDPConstants.NEWLINE, GrDPConstants.CF + GrDPConstants.NEWLINE); LOGGER.debug("CertRequestHandler : Generated proxyCertificate" + strX509CertChain); } return strX509CertChain.getBytes(); } // TODO: marker //------------------- End of old code to remove /** * A synchronizer wrapper for the static digester, only access it through this utility method. * * @param input The bytes to digest. * @return the digested bytes. */ public static synchronized byte[] digest(byte[] input) { // GrDPX509Util utils = new GrDPX509Util(); return s_digester.digest(input); } /** * Change the access mode of a file in the filesystem (!!! system specific !!!). * * @param file Location of the file to be changed. * @param mode New mode for the file. * @return True if file mode has changed. */ public static boolean changeFileMode(String file, int mode) { Runtime runtime = Runtime.getRuntime(); String[] cmd = new String[] { "chmod", String.valueOf(mode), file }; try { Process process = runtime.exec(cmd, null); return (process.waitFor() == 0) ? true : false; } catch (Exception e) { return false; } } /** * Retrieves the location of the user cert file. * from X509_USER_CERT. * @return String the location of the user cert file */ public static String getDefaultCertFile() { String location = null; location = System.getProperty("X509_USER_CERT"); return location; } /** * Retrieves the location of the user key file. * from X509_USER_KEY. * @return String the location of the user key file */ public static String getDefaultKeyFile() { String location = null; location = System.getProperty("X509_USER_KEY"); return location; } /** * Retrieves the location of the CA cert files. * from X509_CERT_DIR. * @return String the locations of the CA certificates */ public static String getDefaultCertLocation() { String location = null; location = System.getProperty("X509_CERT_DIR"); return location; } /** * Retrieves the location of the proxy file. * from X509_USER_PROXY. * @return String the location of the proxy file */ public static String getDefaultProxyFile() { String location; location = System.getProperty("X509_USER_PROXY"); return location; } /** * Returns SHA1 hash digest of file name based on given delegationID and DER encoded DN * in form of SHA1_HASH(DelegationID)+"-"+SHA1_HASH(DN) * @param delegationid_in delegationID of proxy certificate * @param DN_in DER encoded DN * @return Digested file name */ public static String digestFileName(String delegationid_in, String DN_in) { byte[] dgstDlgID = null; byte[] dgstDN = null; String filenameP1 = null; String filenameP2 = "-"; String filenameP3 = null; dgstDlgID = digest(delegationid_in.getBytes()); dgstDlgID = get8MostSignificant(dgstDlgID); filenameP1 = new String(Hex.encode(dgstDlgID)); LOGGER.debug("DN TO DIGEST : " + DN_in.replaceAll(GrDPConstants.CNPROXY + ",", "")); dgstDN = digest((DN_in.replaceAll(GrDPConstants.CNPROXY + ",", "")).getBytes()); dgstDN = get8MostSignificant(dgstDN); filenameP3 = new String(Hex.encode(dgstDN)); // result = filename.digest( randomNum.getBytes() ); LOGGER.debug("Digest of file name : " + filenameP1 + filenameP2 + filenameP3); return filenameP1 + filenameP2 + filenameP3; } /** * Returns 8 most significant bytes of byte array * @param input input byte array * @return 8 MS bytes */ private static byte[] get8MostSignificant(byte[] input) { byte[] result = new byte[8]; for (int i = 0; i <= 7; ++i) result[i] = input[i]; return result; } /** * Returns 'n' most significant bytes of byte array * @param input input byte array * @return 'n' MS bytes */ private static byte[] getMostSignificant(byte[] input, int n) { byte[] result = new byte[n]; for (int i = 0; i <= n - 1; ++i) result[i] = input[i]; return result; } /** * Returns a certificate request in HTTP MIME type format * @param certReq certificate request to response * @return http response format */ public static String certReqResponse(String certReq) { // Constructing HTTP message headers. StringBuffer buffer = new StringBuffer(); buffer.append("HTTP/1.1 200 ok\r\n"); buffer.append("Content-type: " + CERT_REQ_CONTENT_TYPE + "\r\n\r\n"); buffer.append(certReq); return buffer.toString(); } /** * Returns a proxy certificate in HTTP MIME type format * @param proxyCert proxy certificate to response * @return http response format */ public static String certProxyResponse(String proxyCert) { // Constructing HTTP message headers. StringBuffer buffer = new StringBuffer(); buffer.append("HTTP/1.1 200 ok\r\n"); buffer.append("Content-type: " + CERT_CHAIN_CONTENT_TYPE + "\r\n\r\n"); buffer.append(proxyCert); return buffer.toString(); } /** * Makes an HTTP error message out of the error message. * @param errorMsg to send * @return The HTTP error message. */ public static String errorResponse(String errorMsg) { // Constructing HTTP message headers. StringBuffer buffer = new StringBuffer(); buffer.append("HTTP/1.1 " + errorMsg + "\r\n"); buffer.append("\r\n"); return buffer.toString(); } /** * Retrieve the path to the delegatee property file * @return Path to the porperty file */ public static String getDlgeePropertyFile() { String dlgeePropertyFile = null; dlgeePropertyFile = System.getProperty("GLITE_DLGEE_PROPERTY", "dlgee.properties"); LOGGER.debug("GLITE_DLGEE_PROPERTY : " + dlgeePropertyFile); return dlgeePropertyFile; } /** * Retrieve the path to the delegator property file * @return Path to the porperty file */ public static String getDlgorPropertyFile() { String dlgorPropertyFile = null; dlgorPropertyFile = System.getProperty("GLITE_DLGOR_PROPERTY", "dlgor.properties"); return dlgorPropertyFile; } /** * Get the factory to create storage instances. * * @param factoryClass The full name of the class implementing the storage factory. * @return A factory for creating storage object instances. * @throws ClassNotFoundException Could not find the specified class in classpath * @throws NoSuchMethodException Failed to instantiate a factory object * @throws InvocationTargetException Failed to instantiate a factory object * @throws IllegalAccessException Failed to instantiate a factory object * @throws InstantiationException Failed to instantiate a factory object */ @SuppressWarnings("unused") public static GrDPStorageFactory getGrDPStorageFactory(String factoryClass) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { LOGGER.debug("Entered getGrDStorage."); // Get the class references for the helper and DBManager objects Class storageClass = Class.forName(factoryClass); LOGGER.debug("Successfully loaded class '" + factoryClass + "'"); // Create a new helper object instance and return return (GrDPStorageFactory) storageClass.newInstance(); } /** * Create a new certificate request. * * @param subjectDN The dn to include in the certificate request. * @param sigAlgName The algorithm to be used. * @param keyPair The keypair to include in the certificate. * @return A PEM encoded certificate request. * @throws GeneralSecurityException Failed to generate the certificate request. * @deprecated use the method with certificate input instead to avoid problems with DN encoding. */ public static String createCertificateRequest(X509Name subjectDN, String sigAlgName, KeyPair keyPair) throws GeneralSecurityException { PKCS10CertificationRequest certRequest = new PKCS10CertificationRequest(sigAlgName, subjectDN, keyPair.getPublic(), null, keyPair.getPrivate()); StringWriter stringWriter = new StringWriter(); PEMWriter pemWriter = new PEMWriter(stringWriter); try { pemWriter.writeObject(certRequest); pemWriter.flush(); } catch (IOException e) { throw new GeneralSecurityException("Certificate output as string failed: " + e.getMessage()); } return stringWriter.toString(); } /** * Create a new certificate request. * * @param subjectDN The dn to include in the certificate request. * @param sigAlgName The algorithm to be used. * @param keyPair The keypair to include in the certificate. * @return A PEM encoded certificate request. * @throws GeneralSecurityException Failed to generate the certificate request. */ public static String createCertificateRequest(X509Certificate subjectCert, String sigAlgName, KeyPair keyPair) throws GeneralSecurityException { PKCS10CertificationRequest certRequest = new PKCS10CertificationRequest(sigAlgName, subjectCert.getSubjectX500Principal(), keyPair.getPublic(), null, keyPair.getPrivate()); StringWriter stringWriter = new StringWriter(); PEMWriter pemWriter = new PEMWriter(stringWriter); try { pemWriter.writeObject(certRequest); pemWriter.flush(); } catch (IOException e) { throw new GeneralSecurityException("Certificate output as string failed: " + e.getMessage()); } return stringWriter.toString(); } /** * Generate a new key pair. * * @return The generated KeyPair object. */ public static KeyPair getKeyPair(int size) { SecureRandom rand = new SecureRandom(); JDKKeyPairGenerator.RSA keyPairGen = new JDKKeyPairGenerator.RSA(); keyPairGen.initialize(size, rand); return keyPairGen.generateKeyPair(); } /** * Generates a new session ID based on the public key. * @param pk public key of a certificate (request) * @return The generated session ID */ @SuppressWarnings("unused") public static String generateSessionID(PublicKey pk) throws java.security.NoSuchAlgorithmException { return new String(Hex.encode(getMostSignificant(digest(pk.getEncoded()), 20))); } /** * Generates a new delegation ID starting from the given DN and list of VOMS attributes. * * @param dn The dn to be used in the hashing process. * @param vomsAttributes The list of attributes to be used in the hashing process. * @return The generated delegation ID. */ public static String genDlgID(String dn, String[] vomsAttributes) { String originalString = dn; if (vomsAttributes != null) { for (int i = 0; i < vomsAttributes.length; i++) { originalString += vomsAttributes[i]; } } else { LOGGER.debug( "No VOMS attributes in client certificate. Generating DLG ID using" + "only the client DN."); } String digestString = new String(Hex.encode(getMostSignificant(digest(originalString.getBytes()), 20))); LOGGER.debug("Digest VOMS Attributes: " + digestString); return digestString; } /** * Returns the list of VOMS attributes exposed in the given SecurityContext. * * @param sc The SecurityContext object from which to take the attributes * @return A String list containing the attributes. Empty (0 element) array if no attributes. */ public static String[] getVOMSAttributes(SecurityContext sc) { List<VOMSAttribute> vomsAttributes = VOMSValidators.newParser().parse(sc.getClientCertChain()); List<String> attributes = new ArrayList<String>(); for (VOMSAttribute vomsAttribute : vomsAttributes) { List<String> fqans = vomsAttribute.getFQANs(); attributes.addAll(fqans); } return attributes.toArray(new String[attributes.size()]); } /** * Returns a single string representation of the VOMS attributes list. * @param vomsAttributes The VOMS attributes array * @return A single string representation of the VOMS attributes list */ public static String toStringVOMSAttrs(String[] vomsAttributes) { if (vomsAttributes == null) { return ""; } String vomsAttrsStr = ""; for (int i = 0; i < vomsAttributes.length; i++) { vomsAttrsStr += "\t" + vomsAttributes[i]; } return vomsAttrsStr; } /** * Returns the list of VOMS attributes from a single string representation. * @param vomsAttributesStr A single string representation of a VOMS attributes list. * @return A string array containing the VOMS attributes */ public static String[] fromStringVOMSAttrs(String vomsAttributesStr) { if (vomsAttributesStr == null) { return new String[0]; } StringTokenizer st = new StringTokenizer("\t"); ArrayList vomsAttributes = new ArrayList(); while (st.hasMoreTokens()) { vomsAttributes.add(st.nextToken()); } return (String[]) vomsAttributes.toArray(new String[] {}); } }