Frames | No Frames |
1: /* SignatureCodecFactory.java -- Factory to instantiate Signature codecs 2: Copyright (C) 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.java.security.sig; 40: 41: import gnu.java.security.Registry; 42: import gnu.java.security.hash.HashFactory; 43: import gnu.java.security.sig.dss.DSSSignatureRawCodec; 44: import gnu.java.security.sig.dss.DSSSignatureX509Codec; 45: import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureRawCodec; 46: import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; 47: import gnu.java.security.sig.rsa.RSAPSSSignatureRawCodec; 48: import gnu.java.security.util.FormatUtil; 49: 50: import java.util.Collections; 51: import java.util.HashSet; 52: import java.util.Iterator; 53: import java.util.Set; 54: 55: /** 56: * A <i>Factory</i> class to instantiate Signature codecs. 57: */ 58: public class SignatureCodecFactory 59: { 60: private static Set names; 61: 62: /** Trivial constructor to enforce Singleton pattern. */ 63: private SignatureCodecFactory() 64: { 65: super(); 66: } 67: 68: /** 69: * Returns the appropriate codec given a composed signature algorithm and an 70: * encoding format. A composed name is formed by the concatenation of the 71: * canonical signature algorithm name, the forward slash character 72: * <code>/</code> and the canonical name of the encoding format. 73: * <p> 74: * When the encoding format name is missing, the Raw encoding format is 75: * assumed. When this is the case the trailing forward slash is discarded from 76: * the name. 77: * 78: * @param name the case-insensitive, possibly composed, signature codec name. 79: * @return an instance of the signaturecodec, or <code>null</code> if none 80: * found. 81: */ 82: public static ISignatureCodec getInstance(String name) 83: { 84: if (name == null) 85: return null; 86: 87: name = name.trim(); 88: if (name.length() == 0) 89: return null; 90: 91: if (name.startsWith("/")) 92: return null; 93: 94: if (name.endsWith("/")) 95: return getInstance(name.substring(0, name.length() - 1), 96: Registry.RAW_ENCODING_ID); 97: 98: int i = name.indexOf("/"); 99: if (i == - 1) 100: return getInstance(name, Registry.RAW_ENCODING_ID); 101: 102: String sigName = name.substring(0, i); 103: String formatName = name.substring(i + 1); 104: return getInstance(sigName, formatName); 105: } 106: 107: /** 108: * Returns an instance of a signature codec given the canonical name of the 109: * signature algorithm, and that of the encoding format. 110: * 111: * @param name the case-insensitive signature algorithm name. 112: * @param format the name of the format to use when encodigng/decoding 113: * signatures generated by the named algorithm. 114: * @return an instance of the signature codec, or <code>null</code> if none 115: * found. 116: */ 117: public static ISignatureCodec getInstance(String name, String format) 118: { 119: int formatID = FormatUtil.getFormatID(format); 120: if (formatID == 0) 121: return null; 122: 123: return getInstance(name, formatID); 124: } 125: 126: /** 127: * Returns an instance of a signature codec given the canonical name of the 128: * signature algorithm, and the identifier of the format to use when 129: * encoding/decoding signatures generated by that algorithm. 130: * 131: * @param name the case-insensitive signature algorithm name. 132: * @param formatID the identifier of the format to use when encoding / 133: * decoding signatures generated by the designated algorithm. 134: * @return an instance of the signature codec, or <code>null</code> if none 135: * found. 136: */ 137: public static ISignatureCodec getInstance(String name, int formatID) 138: { 139: if (name == null) 140: return null; 141: 142: name = name.trim(); 143: switch (formatID) 144: { 145: case Registry.RAW_ENCODING_ID: 146: return getRawCodec(name); 147: case Registry.X509_ENCODING_ID: 148: return getX509Codec(name); 149: } 150: 151: return null; 152: } 153: 154: /** 155: * Returns a {@link Set} of supported signature codec names. 156: * 157: * @return a {@link Set} of the names of supported signature codec (Strings). 158: */ 159: public static synchronized final Set getNames() 160: { 161: if (names == null) 162: { 163: HashSet hs = new HashSet(); 164: hs.add(Registry.DSS_SIG + "/" + Registry.RAW_ENCODING_SHORT_NAME); 165: hs.add(Registry.DSS_SIG + "/" + Registry.X509_ENCODING_SORT_NAME); 166: Set hashNames = HashFactory.getNames(); 167: for (Iterator it = hashNames.iterator(); it.hasNext();) 168: { 169: String mdName = (String) it.next(); 170: String name = Registry.RSA_PKCS1_V1_5_SIG + "-" + mdName; 171: hs.add(name + "/" + Registry.RAW_ENCODING_SHORT_NAME); 172: hs.add(name + "/" + Registry.X509_ENCODING_SORT_NAME); 173: name = Registry.RSA_PSS_SIG + "-" + mdName; 174: hs.add(name + "/" + Registry.RAW_ENCODING_SHORT_NAME); 175: } 176: 177: names = Collections.unmodifiableSet(hs); 178: } 179: 180: return names; 181: } 182: 183: /** 184: * @param name the trimmed name of a signature algorithm. 185: * @return a Raw format codec for the designated signature algorithm, or 186: * <code>null</code> if none exists. 187: */ 188: private static ISignatureCodec getRawCodec(String name) 189: { 190: ISignatureCodec result = null; 191: if (name.equalsIgnoreCase(Registry.DSA_SIG) 192: || name.equalsIgnoreCase(Registry.DSS_SIG)) 193: result = new DSSSignatureRawCodec(); 194: else 195: { 196: name = name.toLowerCase(); 197: if (name.startsWith(Registry.RSA_PKCS1_V1_5_SIG)) 198: result = new RSAPKCS1V1_5SignatureRawCodec(); 199: else if (name.startsWith(Registry.RSA_PSS_SIG)) 200: result = new RSAPSSSignatureRawCodec(); 201: } 202: 203: return result; 204: } 205: 206: /** 207: * @param name the trimmed name of a signature algorithm. 208: * @return a X.509 format codec for the designated signature algorithm, or 209: * <code>null</code> if none exists. 210: */ 211: private static ISignatureCodec getX509Codec(String name) 212: { 213: ISignatureCodec result = null; 214: if (name.equalsIgnoreCase(Registry.DSA_SIG) 215: || name.equalsIgnoreCase(Registry.DSS_SIG)) 216: result = new DSSSignatureX509Codec(); 217: else 218: { 219: name = name.toLowerCase(); 220: if (name.startsWith(Registry.RSA_PKCS1_V1_5_SIG)) 221: result = new RSAPKCS1V1_5SignatureX509Codec(); 222: } 223: 224: return result; 225: } 226: }