/*
 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.pkcs;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import sun.security.util.DerEncoder;
import sun.security.util.DerValue;
import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;
import sun.security.util.ObjectIdentifier;

A set of attributes of class PKCS9Attribute.
Author:Douglas Hoover
/** * A set of attributes of class PKCS9Attribute. * * @author Douglas Hoover */
public class PKCS9Attributes {
Attributes in this set indexed by OID.
/** * Attributes in this set indexed by OID. */
private final Hashtable<ObjectIdentifier, PKCS9Attribute> attributes = new Hashtable<ObjectIdentifier, PKCS9Attribute>(3);
The keys of this hashtable are the OIDs of permitted attributes.
/** * The keys of this hashtable are the OIDs of permitted attributes. */
private final Hashtable<ObjectIdentifier, ObjectIdentifier> permittedAttributes;
The DER encoding of this attribute set. The tag byte must be DerValue.tag_SetOf.
/** * The DER encoding of this attribute set. The tag byte must be * DerValue.tag_SetOf. */
private final byte[] derEncoding; /* * Contols how attributes, which are not recognized by the PKCS9Attribute * class, are handled during parsing. */ private boolean ignoreUnsupportedAttributes = false;
Construct a set of PKCS9 Attributes from its DER encoding on a DerInputStream, accepting only attributes with OIDs on the given list. If the array is null, accept all attributes supported by class PKCS9Attribute.
Params:
  • permittedAttributes – Array of attribute OIDs that will be accepted.
  • in – the contents of the DER encoding of the attribute set.
Throws:
  • IOException – on i/o error, encoding syntax error, unacceptable or unsupported attribute, or duplicate attribute.
See Also:
/** * Construct a set of PKCS9 Attributes from its * DER encoding on a DerInputStream, accepting only attributes * with OIDs on the given * list. If the array is null, accept all attributes supported by * class PKCS9Attribute. * * @param permittedAttributes * Array of attribute OIDs that will be accepted. * @param in * the contents of the DER encoding of the attribute set. * * @exception IOException * on i/o error, encoding syntax error, unacceptable or * unsupported attribute, or duplicate attribute. * * @see PKCS9Attribute */
public PKCS9Attributes(ObjectIdentifier[] permittedAttributes, DerInputStream in) throws IOException { if (permittedAttributes != null) { this.permittedAttributes = new Hashtable<ObjectIdentifier, ObjectIdentifier>( permittedAttributes.length); for (int i = 0; i < permittedAttributes.length; i++) this.permittedAttributes.put(permittedAttributes[i], permittedAttributes[i]); } else { this.permittedAttributes = null; } // derEncoding initialized in <code>decode()</code> derEncoding = decode(in); }
Construct a set of PKCS9 Attributes from the contents of its DER encoding on a DerInputStream. Accept all attributes supported by class PKCS9Attribute and reject any unsupported attributes.
Params:
  • in – the contents of the DER encoding of the attribute set.
Throws:
  • IOException – on i/o error, encoding syntax error, or unsupported or duplicate attribute.
See Also:
/** * Construct a set of PKCS9 Attributes from the contents of its * DER encoding on a DerInputStream. Accept all attributes * supported by class PKCS9Attribute and reject any unsupported * attributes. * * @param in the contents of the DER encoding of the attribute set. * @exception IOException * on i/o error, encoding syntax error, or unsupported or * duplicate attribute. * * @see PKCS9Attribute */
public PKCS9Attributes(DerInputStream in) throws IOException { this(in, false); }
Construct a set of PKCS9 Attributes from the contents of its DER encoding on a DerInputStream. Accept all attributes supported by class PKCS9Attribute and ignore any unsupported attributes, if directed.
Params:
  • in – the contents of the DER encoding of the attribute set.
  • ignoreUnsupportedAttributes – If true then any attributes not supported by the PKCS9Attribute class are ignored. Otherwise unsupported attributes cause an exception to be thrown.
Throws:
  • IOException – on i/o error, encoding syntax error, or unsupported or duplicate attribute.
See Also:
/** * Construct a set of PKCS9 Attributes from the contents of its * DER encoding on a DerInputStream. Accept all attributes * supported by class PKCS9Attribute and ignore any unsupported * attributes, if directed. * * @param in the contents of the DER encoding of the attribute set. * @param ignoreUnsupportedAttributes If true then any attributes * not supported by the PKCS9Attribute class are ignored. Otherwise * unsupported attributes cause an exception to be thrown. * @exception IOException * on i/o error, encoding syntax error, or unsupported or * duplicate attribute. * * @see PKCS9Attribute */
public PKCS9Attributes(DerInputStream in, boolean ignoreUnsupportedAttributes) throws IOException { this.ignoreUnsupportedAttributes = ignoreUnsupportedAttributes; // derEncoding initialized in <code>decode()</code> derEncoding = decode(in); permittedAttributes = null; }
Construct a set of PKCS9 Attributes from the given array of PKCS9 attributes. DER encoding on a DerInputStream. All attributes in attribs must be supported by class PKCS9Attribute.
Throws:
  • IOException – on i/o error, encoding syntax error, or unsupported or duplicate attribute.
See Also:
/** * Construct a set of PKCS9 Attributes from the given array of * PKCS9 attributes. * DER encoding on a DerInputStream. All attributes in * <code>attribs</code> must be * supported by class PKCS9Attribute. * * @exception IOException * on i/o error, encoding syntax error, or unsupported or * duplicate attribute. * * @see PKCS9Attribute */
public PKCS9Attributes(PKCS9Attribute[] attribs) throws IllegalArgumentException, IOException { ObjectIdentifier oid; for (int i=0; i < attribs.length; i++) { oid = attribs[i].getOID(); if (attributes.containsKey(oid)) throw new IllegalArgumentException( "PKCSAttribute " + attribs[i].getOID() + " duplicated while constructing " + "PKCS9Attributes."); attributes.put(oid, attribs[i]); } derEncoding = generateDerEncoding(); permittedAttributes = null; }
Decode this set of PKCS9 attributes from the contents of its DER encoding. Ignores unsupported attributes when directed.
Params:
  • in – the contents of the DER encoding of the attribute set.
Throws:
  • IOException – on i/o error, encoding syntax error, unacceptable or unsupported attribute, or duplicate attribute.
/** * Decode this set of PKCS9 attributes from the contents of its * DER encoding. Ignores unsupported attributes when directed. * * @param in * the contents of the DER encoding of the attribute set. * * @exception IOException * on i/o error, encoding syntax error, unacceptable or * unsupported attribute, or duplicate attribute. */
private byte[] decode(DerInputStream in) throws IOException { DerValue val = in.getDerValue(); // save the DER encoding with its proper tag byte. byte[] derEncoding = val.toByteArray(); derEncoding[0] = DerValue.tag_SetOf; DerInputStream derIn = new DerInputStream(derEncoding); DerValue[] derVals = derIn.getSet(3,true); PKCS9Attribute attrib; ObjectIdentifier oid; boolean reuseEncoding = true; for (int i=0; i < derVals.length; i++) { try { attrib = new PKCS9Attribute(derVals[i]); } catch (ParsingException e) { if (ignoreUnsupportedAttributes) { reuseEncoding = false; // cannot reuse supplied DER encoding continue; // skip } else { throw e; } } oid = attrib.getOID(); if (attributes.get(oid) != null) throw new IOException("Duplicate PKCS9 attribute: " + oid); if (permittedAttributes != null && !permittedAttributes.containsKey(oid)) throw new IOException("Attribute " + oid + " not permitted in this attribute set"); attributes.put(oid, attrib); } return reuseEncoding ? derEncoding : generateDerEncoding(); }
Put the DER encoding of this PKCS9 attribute set on an DerOutputStream, tagged with the given implicit tag.
Params:
  • tag – the implicit tag to use in the DER encoding.
  • out – the output stream on which to put the DER encoding.
Throws:
/** * Put the DER encoding of this PKCS9 attribute set on an * DerOutputStream, tagged with the given implicit tag. * * @param tag the implicit tag to use in the DER encoding. * @param out the output stream on which to put the DER encoding. * * @exception IOException on output error. */
public void encode(byte tag, OutputStream out) throws IOException { out.write(tag); out.write(derEncoding, 1, derEncoding.length -1); } private byte[] generateDerEncoding() throws IOException { DerOutputStream out = new DerOutputStream(); Object[] attribVals = attributes.values().toArray(); out.putOrderedSetOf(DerValue.tag_SetOf, castToDerEncoder(attribVals)); return out.toByteArray(); }
Return the DER encoding of this attribute set, tagged with DerValue.tag_SetOf.
/** * Return the DER encoding of this attribute set, tagged with * DerValue.tag_SetOf. */
public byte[] getDerEncoding() throws IOException { return derEncoding.clone(); }
Get an attribute from this set.
/** * Get an attribute from this set. */
public PKCS9Attribute getAttribute(ObjectIdentifier oid) { return attributes.get(oid); }
Get an attribute from this set.
/** * Get an attribute from this set. */
public PKCS9Attribute getAttribute(String name) { return attributes.get(PKCS9Attribute.getOID(name)); }
Get an array of all attributes in this set, in order of OID.
/** * Get an array of all attributes in this set, in order of OID. */
public PKCS9Attribute[] getAttributes() { PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()]; ObjectIdentifier oid; int j = 0; for (int i=1; i < PKCS9Attribute.PKCS9_OIDS.length && j < attribs.length; i++) { attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); if (attribs[j] != null) j++; } return attribs; }
Get an attribute value by OID.
/** * Get an attribute value by OID. */
public Object getAttributeValue(ObjectIdentifier oid) throws IOException { try { Object value = getAttribute(oid).getValue(); return value; } catch (NullPointerException ex) { throw new IOException("No value found for attribute " + oid); } }
Get an attribute value by type name.
/** * Get an attribute value by type name. */
public Object getAttributeValue(String name) throws IOException { ObjectIdentifier oid = PKCS9Attribute.getOID(name); if (oid == null) throw new IOException("Attribute name " + name + " not recognized or not supported."); return getAttributeValue(oid); }
Returns the PKCS9 block in a printable string form.
/** * Returns the PKCS9 block in a printable string form. */
public String toString() { StringBuffer buf = new StringBuffer(200); buf.append("PKCS9 Attributes: [\n\t"); ObjectIdentifier oid; PKCS9Attribute value; boolean first = true; for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) { value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); if (value == null) continue; // we have a value; print it if (first) first = false; else buf.append(";\n\t"); buf.append(value.toString()); } buf.append("\n\t] (end PKCS9 Attributes)"); return buf.toString(); }
Cast an object array whose components are DerEncoders to DerEncoder[].
/** * Cast an object array whose components are * <code>DerEncoder</code>s to <code>DerEncoder[]</code>. */
static DerEncoder[] castToDerEncoder(Object[] objs) { DerEncoder[] encoders = new DerEncoder[objs.length]; for (int i=0; i < encoders.length; i++) encoders[i] = (DerEncoder) objs[i]; return encoders; } }