diff options
Diffstat (limited to 'pki/base/util/src/netscape/security/extensions/GenericASN1Extension.java')
-rw-r--r-- | pki/base/util/src/netscape/security/extensions/GenericASN1Extension.java | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/pki/base/util/src/netscape/security/extensions/GenericASN1Extension.java b/pki/base/util/src/netscape/security/extensions/GenericASN1Extension.java new file mode 100644 index 000000000..f756a4c0b --- /dev/null +++ b/pki/base/util/src/netscape/security/extensions/GenericASN1Extension.java @@ -0,0 +1,448 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.util.Hashtable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.lang.reflect.Array; +import java.math.BigInteger; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.text.DateFormat; +import java.text.ParseException; + +import netscape.security.util.*; +import netscape.security.x509.*; +import java.security.cert.CertificateException; + + + +/** + * Represent the AsnInteger Extension. + */ +public class GenericASN1Extension extends Extension +implements CertAttrSet { + protected static final int MAX_ATTR = 10; + + protected static final String PROP_CRITICAL = + "critical"; + protected static final String PROP_NAME = + "name"; + protected static final String PROP_OID = + "oid"; + protected static final String PROP_PATTERN = + "pattern"; + protected static final String PROP_ATTRIBUTE = + "attribute"; + protected static final String PROP_TYPE = + "type"; + protected static final String PROP_SOURCE = + "source"; + protected static final String PROP_VALUE = + "value"; + protected static final String PROP_PREDICATE = + "predicate"; + /** + * Identifier for this attribute, to be used with the + * get, set, delete methods of Certificate, x509 type. + */ + public static String NAME = null; + public static String OID = null; + public static Hashtable mConfig = null; + public static String pattern = null; + private int index = 0; + + // Encode this value + private void encodeThis() + throws IOException, ParseException + { + this.extensionValue = encodePattern(); + } + + // Encode pattern + private byte[] encodePattern() + throws IOException, ParseException + { + DerOutputStream os = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + String type = null; + String value = null; + String source = null; + while (index < pattern.length()) { + char ch = pattern.charAt(index); + switch (ch) { + case '{' : + index++; + byte[] buff = encodePattern(); + tmp.putDerValue(new DerValue(buff)); + break; + case '}' : + os.write(DerValue.tag_Sequence, tmp); + return os.toByteArray(); + default : + type = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_TYPE); + if (type.equalsIgnoreCase("integer")) { + int num = Integer.parseInt((String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE)); + PutInteger(tmp, num); + } + else if (type.equalsIgnoreCase("ia5string")) { + source = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_SOURCE); + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutIA5String(tmp, getFromFile(value)); + else + PutIA5String(tmp, value); + } + else if (type.equalsIgnoreCase("octetstring")) { + source = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_SOURCE); + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + // It should be colon seperated ASCII Hexdecimal String + if (source.equalsIgnoreCase("file")) + PutOctetString(tmp, getFromFile(value)); + else + PutOctetString(tmp, value); + } + else if (type.equalsIgnoreCase("bmpstring")) { + source = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_SOURCE); + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutBMPString(tmp, getFromFile(value)); + else + PutBMPString(tmp, value); + } + else if (type.equalsIgnoreCase("printablestring")) { + source = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_SOURCE); + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutPrintableString(tmp, getFromFile(value)); + else + PutPrintableString(tmp, value); + } + else if (type.equalsIgnoreCase("visiblestring")) { + source = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_SOURCE); + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutVisibleString(tmp, getFromFile(value)); + else + PutVisibleString(tmp, value); + } + else if (type.equalsIgnoreCase("utctime")) { + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + PutUTCtime(tmp, value); + } + else if (type.equalsIgnoreCase("oid")) { + value = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + PutOID(tmp, value); + } + else if (type.equalsIgnoreCase("boolean")) { + boolean bool = false; + String b = (String)mConfig.get(PROP_ATTRIBUTE+"."+ch+"."+PROP_VALUE); + if (b.equalsIgnoreCase("true")) + bool = true; + else + bool = false; + PutBoolean(tmp, bool); + } + else if (type.equalsIgnoreCase("null")) { + tmp.putNull(); + } + else { + throw new ParseException("Unknown Attribute Type", 0); + } + } + index++; + } + + return tmp.toByteArray(); + } + + /** + * Create a GenericASN1Extension with the value and oid. + * The criticality is set to false. + * + * @param the values to be set for the extension. + */ + public GenericASN1Extension(String name, String oid, String pattern, boolean critical, Hashtable config) + throws IOException, ParseException + { + ObjectIdentifier tmpid = new ObjectIdentifier(oid); + NAME = name; + OID = oid; + mConfig = config; + this.pattern = pattern; + + try { + if (OIDMap.getName(tmpid) == null) + OIDMap.addAttribute("netscape.security.x509.GenericASN1Extension", oid, name); + } catch (CertificateException e) {} + + this.extensionId = tmpid; + this.critical = critical; + encodeThis(); + } + + /** + * Create a GenericASN1Extension with the value and oid. + * The criticality is set to false. + * + * @param the values to be set for the extension. + */ + public GenericASN1Extension(Hashtable config) + throws IOException, ParseException + { + mConfig = config; + ObjectIdentifier tmpid = new ObjectIdentifier((String)mConfig.get(PROP_OID)); + NAME = (String)mConfig.get(PROP_NAME); + OID = (String)mConfig.get(PROP_OID); + pattern = (String)mConfig.get(PROP_PATTERN); + + try { + if (OIDMap.getName(tmpid) == null) + OIDMap.addAttribute("GenericASN1Extension", OID, NAME); + } catch (CertificateException e) {} + + this.extensionId = tmpid; + this.critical = false; + String b = (String)mConfig.get(PROP_CRITICAL); + if (b.equalsIgnoreCase("true")) + this.critical = true; + else + this.critical = false; + encodeThis(); + } + + /** + * Create the extension from the passed DER encoded value of the same. + * + * @param critical true if the extension is to be treated as critical. + * @param value Array of DER encoded bytes of the actual value. + * @exception IOException on error. + */ + public GenericASN1Extension(Boolean critical, Object value) + throws IOException + { + this.extensionId = new ObjectIdentifier(OID); + this.critical = critical.booleanValue(); + + int len = Array.getLength(value); + byte[] extValue = new byte[len]; + for (int i = 0; i < len; i++) { + extValue[i] = Array.getByte(value, i); + } + this.extensionValue = extValue; + } + + /** + * Set the attribute value. + */ + public void set(String name, Object obj) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Get the attribute value. + */ + public Object get(String name) throws IOException { + return null; + } + + /** + * Delete the attribute value. + */ + public void delete(String name) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Returns a printable representation of the GenericASN1Extension. + */ + public String toString() { + return (null); + } + + /** + * Decode the extension from the InputStream. + * + * @param in the InputStream to unmarshal the contents from. + * @exception IOException on decoding or validity errors. + */ + public void decode(InputStream in) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) + throws IOException + { + DerOutputStream tmp = new DerOutputStream(); + + try { + if (this.extensionValue == null) { + this.extensionId = new ObjectIdentifier(OID); + this.critical = true; + encodeThis(); + } + } + catch (ParseException e) {} + + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Return the name of this attribute. + */ + public String getName () { + return (NAME); + } + /** + * Set the name of this attribute. + */ + public void setName (String name) { + NAME = name; + } + /** + * Return the OID of this attribute. + */ + public String getOID () { + return (OID); + } + /** + * Set the OID of this attribute. + */ + public void setOID (String oid) { + OID = oid; + } + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration getElements () { + AttributeNameEnumeration elements = new AttributeNameEnumeration(); + elements.addElement("octet"); + + return (elements.elements()); + } + + private void PutInteger(DerOutputStream os, int number) + throws IOException, ParseException { + os.putInteger(new BigInt(number)); + return; + } + + private void PutIA5String(DerOutputStream os, String value) + throws IOException, ParseException { + os.putIA5String(value); + return; + } + + private void PutOctetString(DerOutputStream os, String value) + throws IOException, ParseException { + StringTokenizer token = new StringTokenizer(value, ":"); + byte[] octets = new byte[token.countTokens()]; + for (int i = 0; token.hasMoreElements(); i++) { + String num = (String)token.nextElement(); + octets[i] = (byte) Integer.parseInt(num, 16); + } + + os.putOctetString(octets); + return; + } + + private void PutBMPString(DerOutputStream os, String value) + throws IOException, ParseException { + os.putBMPString(value); + return; + } + + private void PutPrintableString(DerOutputStream os, String value) + throws IOException, ParseException { + os.putPrintableString(value); + return; + } + + private void PutVisibleString(DerOutputStream os, String value) + throws IOException, ParseException { + os.putVisibleString(value); + return; + } + + private void PutUTCtime(DerOutputStream os, String value) + throws IOException, ParseException { + DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); + os.putUTCTime(df.parse(value)); + return; + } + + private void PutOID(DerOutputStream os, String value) + throws IOException, ParseException { + os.putOID(new ObjectIdentifier(value)); + return; + } + + private void PutBoolean(DerOutputStream os, boolean value) + throws IOException, ParseException { + os.putBoolean(value); + return; + } + + private String getFromFile(String fname) throws IOException { + String s = null; + byte[] buff = null; + int i = 0; + int j = 0; + if ((fname == null) || (fname.equals(""))) { + throw new IOException("File name is not provided."); + } + + FileInputStream fis = new FileInputStream(fname); + int n = 0; + while ((n = fis.available()) > 0) { + buff = new byte[n]; + int result = fis.read(buff); + if (result == -1) break; + s = new String(buff); + } + + for (i = 0, j = 0; j < s.length(); j++) { + int ch = (int)s.charAt(j); + if (ch == 10 || ch == 13 || ch == 9) + continue; + i++; + } + buff = new byte[i]; + for (i = 0, j = 0; j < s.length(); j++) { + int ch = (int)s.charAt(j); + if (ch == 10 || ch == 13 || ch == 9) + continue; + buff[i++] = (byte)ch; + } + + s = new String(buff); + + return s; + } +} |