summaryrefslogtreecommitdiffstats
path: root/pki/base/util/src/netscape/security/x509/Attribute.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/util/src/netscape/security/x509/Attribute.java')
-rw-r--r--pki/base/util/src/netscape/security/x509/Attribute.java335
1 files changed, 335 insertions, 0 deletions
diff --git a/pki/base/util/src/netscape/security/x509/Attribute.java b/pki/base/util/src/netscape/security/x509/Attribute.java
new file mode 100644
index 000000000..a5fa02245
--- /dev/null
+++ b/pki/base/util/src/netscape/security/x509/Attribute.java
@@ -0,0 +1,335 @@
+// --- 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.x509;
+
+import java.util.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import sun.io.ByteToCharConverter;
+
+import java.io.*;
+import netscape.security.util.*;
+
+/**
+ * An attribute, as identified by some attribute ID, has some particular values.
+ * Values are as a rule ASN.1 printable strings. A conventional set of type IDs
+ * is recognized when parsing. The following shows the syntax:
+ * <pre>
+ *
+ * Attribute ::= SEQUENCE {
+ * type AttributeType,
+ * value SET OF AttributeValue
+ * -- at least one value is required --}
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY
+ *
+ * </pre>
+ * Refer to draft-ietf-pkix-ipki-part1-11 for the support attributes listed on
+ * page 96 of the internet draft. The are listed here for easy reference: name,
+ * common name, surname, given name, initials, generation qualifier, dn qualifier,
+ * country name, locality name, state or province name, organization name, organization
+ * unit name, title, pkcs9 email. Not all the attributes are supported. Please check
+ * the X500NameAttrMap for defined attributes.
+ *
+ * @author Christine Ho
+ */
+
+public final class Attribute implements Serializable, DerEncoder {
+
+ //private variables
+ ObjectIdentifier oid;
+ Vector valueSet = new Vector();
+ transient protected X500NameAttrMap attrMap;
+
+ //========== CONSTRUCTOR ==================================
+
+ /**
+ * Construct an attribute from attribute type and attribute value
+ * @param oid the object identifier of the attribute type
+ * @param value the value string
+ */
+ public Attribute (ObjectIdentifier oid, String value)
+ throws IOException
+ {
+
+ //pre-condition verification
+ if ((oid == null) || (value == null))
+ throw new IOException("Invalid Input - null passed");
+
+ attrMap = X500NameAttrMap.getDefault();
+ this.oid = oid;
+ valueSet.addElement(value);
+ }
+
+ /**
+ * Construct an attribute from attribute type and attribute values
+ * @param oid the object identifier of the attribute type
+ * @param values String value vector
+ */
+ public Attribute (ObjectIdentifier oid, Vector values)
+ throws IOException
+ {
+
+ //pre-condition verification
+ if ((oid == null) || (values == null))
+ throw new IOException("Invalid Input - null passed");
+
+ attrMap = X500NameAttrMap.getDefault();
+ this.oid = oid;
+
+ //copy the value into the valueSet list
+ Enumeration vals = values.elements();
+ while (vals.hasMoreElements()) {
+ Object obj = vals.nextElement();
+ if (obj instanceof String)
+ valueSet.addElement(obj);
+ else
+ throw new IOException("values vectore must consist of String object");
+ }
+ }
+
+ /**
+ * Construct an attribute from attribute type and attribute values
+ * @param oid attribute type string CN,OU,O,C,L,TITLE,ST,STREET,UID,MAIL,E,DC
+ * @param values String value vector
+ */
+ public Attribute (String attr, Vector values)
+ throws IOException
+ {
+
+ //pre-condition verification
+ if ((attr == null) || (values == null))
+ throw new IOException("Invalid Input - null passed");
+
+ ObjectIdentifier identifier = null;
+ try {
+ identifier = new ObjectIdentifier(attr);
+ } catch (Exception e) {
+ }
+
+ ObjectIdentifier id = identifier;
+ if (identifier == null) {
+ attrMap = X500NameAttrMap.getDefault();
+ id = attrMap.getOid(attr);
+ if (id == null)
+ throw new IOException("Attr is not supported - does not contain in attr map");
+ }
+ this.oid = id;
+
+ //copy the value into the valueSet list
+ Enumeration vals = values.elements();
+ while (vals.hasMoreElements()) {
+ Object obj = vals.nextElement();
+ if (obj instanceof String)
+ valueSet.addElement(obj);
+ else
+ throw new IOException("Values vectore must consist of String object");
+ }
+ }
+
+ /**
+ * Construct an attribute from a der encoded object. This der
+ * der encoded value should represent the attribute object.
+ * @param value the attribute object in der encode form.
+ */
+ public Attribute (DerValue val)
+ throws IOException
+ {
+
+ //pre-condition verification
+ if (val == null)
+ throw new IOException("Invalid Input - null passed");
+
+ attrMap = X500NameAttrMap.getDefault();
+
+ decodeThis(val);
+
+ }
+
+ //========== PUBLIC METHODS ==================================
+
+ /**
+ * Returns the OID in the Attribute.
+ * @return the ObjectIdentifier in this Attribute.
+ */
+ public ObjectIdentifier getOid()
+ {
+ return oid;
+ }
+
+ /**
+ * Returns enumeration of values in this attribute.
+ * @return Enumeration of values of this Attribute.
+ */
+ public Enumeration getValues()
+ {
+ if (valueSet == null) return null;
+ return valueSet.elements();
+ }
+
+ /**
+ * Encodes the Attribute to a Der output stream.
+ * Attribute are encoded as a SEQUENCE of two elements.
+ * @param out The Der output stream.
+ */
+ public void encode(DerOutputStream out) throws IOException
+ {
+ encodeThis(out);
+ }
+
+ /**
+ * DER encode this object onto an output stream.
+ * Implements the <code>DerEncoder</code> interface.
+ *
+ * @param out
+ * the output stream on which to write the DER encoding.
+ *
+ * @exception IOException on encoding error.
+ */
+ public void derEncode (OutputStream out) throws IOException
+ {
+ encodeThis(out);
+ }
+
+ /**
+ * Prints a string version of this extension.
+ */
+ public String toString()
+ {
+ String theoid = "Attribute: "+oid+"\n";
+ String values = "Values: ";
+ Enumeration n = valueSet.elements();
+ if (n.hasMoreElements()) {
+ values += (String)n.nextElement();
+ while (n.hasMoreElements())
+ values+= ","+(String)n.nextElement();
+ }
+ return theoid+values+"\n";
+ }
+
+
+ //========== PRIVATE METHODS ==================================
+
+ //encode the attribute object
+ private void encodeThis(OutputStream out)
+ throws IOException
+ {
+ DerOutputStream tmp = new DerOutputStream ();
+ DerOutputStream tmp2 = new DerOutputStream ();
+
+ tmp.putOID (oid);
+ encodeValueSet(tmp);
+ tmp2.write (DerValue.tag_Sequence, tmp);
+ out.write(tmp2.toByteArray());
+ }
+
+ //encode the attribute object
+ private void encodeValueSet(OutputStream out)
+ throws IOException
+ {
+ DerOutputStream tmp = new DerOutputStream ();
+ DerOutputStream tmp2 = new DerOutputStream ();
+
+ //get the attribute converter
+ AVAValueConverter converter = attrMap.getValueConverter(oid);
+ if (converter == null) {
+ converter = new GenericValueConverter();
+ //throw new IOException("Converter not found: unsupported attribute type");
+ }
+
+ //loop through all the values and encode
+ Enumeration vals = valueSet.elements();
+ while (vals.hasMoreElements()) {
+ String val = (String) vals.nextElement();
+ DerValue derobj = converter.getValue(val);
+ derobj.encode(tmp);
+ }
+
+ tmp2.write (DerValue.tag_SetOf, tmp);
+ out.write(tmp2.toByteArray());
+ }
+
+ //decode the attribute object
+ private void decodeThis(DerValue val)
+ throws IOException
+ {
+
+ //pre-condition verification
+ if (val == null) {
+ throw new IOException("Invalid Input - null passed.");
+ }
+
+ if (val.tag != DerValue.tag_Sequence) {
+ throw new IOException("Invalid encoding for Attribute.");
+ }
+
+ if (val.data.available() == 0) {
+ throw new IOException("No data available in "
+ + "passed DER encoded value.");
+ }
+ this.oid = val.data.getDerValue().getOID();
+
+ if (val.data.available() == 0) {
+ throw new IOException("Invalid encoding for Attribute - value missing");
+ }
+ decodeValueSet(val.data.getDerValue());
+
+ if (this.oid == null)
+ throw new IOException("Invalid encoding for Attribute - OID missing");
+
+ }
+
+ //decode the attribute value set
+ private void decodeValueSet(DerValue val)
+ throws IOException
+ {
+ //pre-condition verification
+ if (val == null) {
+ throw new IOException("Invalid Input - null passed.");
+ }
+
+ AVAValueConverter converter = attrMap.getValueConverter(this.oid);
+ if (converter == null) {
+ converter = new GenericValueConverter();
+ //throw new IOException("Attribute is not supported - not in attr map");
+ }
+
+ if (val.tag != DerValue.tag_SetOf) {
+ throw new IOException("Invalid encoding for Attribute Value Set.");
+ }
+
+ if (val.data.available() == 0) {
+ throw new IOException("No data available in "
+ + "passed DER encoded attribute value set.");
+ }
+
+ //get the value set
+ while (val.data.available() != 0) {
+ DerValue value = val.data.getDerValue();
+ valueSet.addElement(converter.getAsString(value));
+ }
+ }
+
+}
+