1/* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.security.pkcs10; 27 28import java.io.IOException; 29import java.io.OutputStream; 30import java.security.cert.CertificateException; 31import java.util.Collection; 32import java.util.Collections; 33import java.util.Enumeration; 34import java.util.Hashtable; 35 36import sun.security.util.*; 37 38/** 39 * This class defines the PKCS10 attributes for the request. 40 * The ASN.1 syntax for this is: 41 * <pre> 42 * Attributes ::= SET OF Attribute 43 * </pre> 44 * 45 * @author Amit Kapoor 46 * @author Hemma Prafullchandra 47 * @see PKCS10 48 * @see PKCS10Attribute 49 */ 50public class PKCS10Attributes implements DerEncoder { 51 52 private Hashtable<String, PKCS10Attribute> map = 53 new Hashtable<String, PKCS10Attribute>(3); 54 55 /** 56 * Default constructor for the PKCS10 attribute. 57 */ 58 public PKCS10Attributes() { } 59 60 /** 61 * Create the object from the array of PKCS10Attribute objects. 62 * 63 * @param attrs the array of PKCS10Attribute objects. 64 */ 65 public PKCS10Attributes(PKCS10Attribute[] attrs) { 66 for (int i = 0; i < attrs.length; i++) { 67 map.put(attrs[i].getAttributeId().toString(), attrs[i]); 68 } 69 } 70 71 /** 72 * Create the object, decoding the values from the passed DER stream. 73 * The DER stream contains the SET OF Attribute. 74 * 75 * @param in the DerInputStream to read the attributes from. 76 * @exception IOException on decoding errors. 77 */ 78 public PKCS10Attributes(DerInputStream in) throws IOException { 79 DerValue[] attrs = in.getSet(3, true); 80 81 if (attrs == null) 82 throw new IOException("Illegal encoding of attributes"); 83 for (int i = 0; i < attrs.length; i++) { 84 PKCS10Attribute attr = new PKCS10Attribute(attrs[i]); 85 map.put(attr.getAttributeId().toString(), attr); 86 } 87 } 88 89 /** 90 * Encode the attributes in DER form to the stream. 91 * 92 * @param out the OutputStream to marshal the contents to. 93 * @exception IOException on encoding errors. 94 */ 95 public void encode(OutputStream out) throws IOException { 96 derEncode(out); 97 } 98 99 /** 100 * Encode the attributes in DER form to the stream. 101 * Implements the {@code DerEncoder} interface. 102 * 103 * @param out the OutputStream to marshal the contents to. 104 * @exception IOException on encoding errors. 105 */ 106 public void derEncode(OutputStream out) throws IOException { 107 // first copy the elements into an array 108 Collection<PKCS10Attribute> allAttrs = map.values(); 109 PKCS10Attribute[] attribs = 110 allAttrs.toArray(new PKCS10Attribute[map.size()]); 111 112 DerOutputStream attrOut = new DerOutputStream(); 113 attrOut.putOrderedSetOf(DerValue.createTag(DerValue.TAG_CONTEXT, 114 true, (byte)0), 115 attribs); 116 out.write(attrOut.toByteArray()); 117 } 118 119 /** 120 * Set the attribute value. 121 */ 122 public void setAttribute(String name, Object obj) { 123 if (obj instanceof PKCS10Attribute) { 124 map.put(name, (PKCS10Attribute)obj); 125 } 126 } 127 128 /** 129 * Get the attribute value. 130 */ 131 public Object getAttribute(String name) { 132 return map.get(name); 133 } 134 135 /** 136 * Delete the attribute value. 137 */ 138 public void deleteAttribute(String name) { 139 map.remove(name); 140 } 141 142 /** 143 * Return an enumeration of names of attributes existing within this 144 * attribute. 145 */ 146 public Enumeration<PKCS10Attribute> getElements() { 147 return (map.elements()); 148 } 149 150 /** 151 * Return a Collection of attributes existing within this 152 * PKCS10Attributes object. 153 */ 154 public Collection<PKCS10Attribute> getAttributes() { 155 return (Collections.unmodifiableCollection(map.values())); 156 } 157 158 /** 159 * Compares this PKCS10Attributes for equality with the specified 160 * object. If the {@code other} object is an 161 * {@code instanceof PKCS10Attributes}, then 162 * all the entries are compared with the entries from this. 163 * 164 * @param other the object to test for equality with this PKCS10Attributes. 165 * @return true if all the entries match that of the Other, 166 * false otherwise. 167 */ 168 public boolean equals(Object other) { 169 if (this == other) 170 return true; 171 if (!(other instanceof PKCS10Attributes)) 172 return false; 173 174 Collection<PKCS10Attribute> othersAttribs = 175 ((PKCS10Attributes)other).getAttributes(); 176 PKCS10Attribute[] attrs = 177 othersAttribs.toArray(new PKCS10Attribute[othersAttribs.size()]); 178 int len = attrs.length; 179 if (len != map.size()) 180 return false; 181 PKCS10Attribute thisAttr, otherAttr; 182 String key = null; 183 for (int i=0; i < len; i++) { 184 otherAttr = attrs[i]; 185 key = otherAttr.getAttributeId().toString(); 186 187 if (key == null) 188 return false; 189 thisAttr = map.get(key); 190 if (thisAttr == null) 191 return false; 192 if (! thisAttr.equals(otherAttr)) 193 return false; 194 } 195 return true; 196 } 197 198 /** 199 * Returns a hashcode value for this PKCS10Attributes. 200 * 201 * @return the hashcode value. 202 */ 203 public int hashCode() { 204 return map.hashCode(); 205 } 206 207 /** 208 * Returns a string representation of this {@code PKCS10Attributes} object 209 * in the form of a set of entries, enclosed in braces and separated 210 * by the ASCII characters "<code>, </code>" (comma and space). 211 * <p>Overrides the {@code toString} method of {@code Object}. 212 * 213 * @return a string representation of this PKCS10Attributes. 214 */ 215 public String toString() { 216 String s = map.size() + "\n" + map.toString(); 217 return s; 218 } 219} 220