151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.pkcs; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.OutputStream; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Hashtable; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.DerEncoder; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.DerValue; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.DerInputStream; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.DerOutputStream; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ObjectIdentifier; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A set of attributes of class PKCS9Attribute. 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Douglas Hoover 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class PKCS9Attributes { 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Attributes in this set indexed by OID. 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Hashtable<ObjectIdentifier, PKCS9Attribute> attributes = 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new Hashtable<ObjectIdentifier, PKCS9Attribute>(3); 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The keys of this hashtable are the OIDs of permitted attributes. 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Hashtable<ObjectIdentifier, ObjectIdentifier> permittedAttributes; 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The DER encoding of this attribute set. The tag byte must be 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DerValue.tag_SetOf. 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final byte[] derEncoding; 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Contols how attributes, which are not recognized by the PKCS9Attribute 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class, are handled during parsing. 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean ignoreUnsupportedAttributes = false; 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Construct a set of PKCS9 Attributes from its 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER encoding on a DerInputStream, accepting only attributes 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with OIDs on the given 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * list. If the array is null, accept all attributes supported by 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class PKCS9Attribute. 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param permittedAttributes 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Array of attribute OIDs that will be accepted. 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the contents of the DER encoding of the attribute set. 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on i/o error, encoding syntax error, unacceptable or 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unsupported attribute, or duplicate attribute. 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see PKCS9Attribute 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attributes(ObjectIdentifier[] permittedAttributes, 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputStream in) throws IOException { 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (permittedAttributes != null) { 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.permittedAttributes = 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new Hashtable<ObjectIdentifier, ObjectIdentifier>( 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski permittedAttributes.length); 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < permittedAttributes.length; i++) 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.permittedAttributes.put(permittedAttributes[i], 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski permittedAttributes[i]); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.permittedAttributes = null; 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // derEncoding initialized in <code>decode()</code> 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski derEncoding = decode(in); 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Construct a set of PKCS9 Attributes from the contents of its 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER encoding on a DerInputStream. Accept all attributes 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * supported by class PKCS9Attribute and reject any unsupported 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * attributes. 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in the contents of the DER encoding of the attribute set. 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on i/o error, encoding syntax error, or unsupported or 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * duplicate attribute. 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see PKCS9Attribute 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attributes(DerInputStream in) throws IOException { 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(in, false); 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Construct a set of PKCS9 Attributes from the contents of its 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER encoding on a DerInputStream. Accept all attributes 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * supported by class PKCS9Attribute and ignore any unsupported 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * attributes, if directed. 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in the contents of the DER encoding of the attribute set. 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ignoreUnsupportedAttributes If true then any attributes 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not supported by the PKCS9Attribute class are ignored. Otherwise 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unsupported attributes cause an exception to be thrown. 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on i/o error, encoding syntax error, or unsupported or 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * duplicate attribute. 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see PKCS9Attribute 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attributes(DerInputStream in, 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean ignoreUnsupportedAttributes) throws IOException { 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.ignoreUnsupportedAttributes = ignoreUnsupportedAttributes; 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // derEncoding initialized in <code>decode()</code> 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski derEncoding = decode(in); 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski permittedAttributes = null; 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Construct a set of PKCS9 Attributes from the given array of 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * PKCS9 attributes. 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER encoding on a DerInputStream. All attributes in 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>attribs</code> must be 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * supported by class PKCS9Attribute. 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on i/o error, encoding syntax error, or unsupported or 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * duplicate attribute. 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see PKCS9Attribute 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attributes(PKCS9Attribute[] attribs) 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IllegalArgumentException, IOException { 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier oid; 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i < attribs.length; i++) { 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski oid = attribs[i].getOID(); 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (attributes.containsKey(oid)) 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException( 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "PKCSAttribute " + attribs[i].getOID() + 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski " duplicated while constructing " + 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "PKCS9Attributes."); 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attributes.put(oid, attribs[i]); 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski derEncoding = generateDerEncoding(); 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski permittedAttributes = null; 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Decode this set of PKCS9 attributes from the contents of its 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DER encoding. Ignores unsupported attributes when directed. 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param in 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the contents of the DER encoding of the attribute set. 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on i/o error, encoding syntax error, unacceptable or 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unsupported attribute, or duplicate attribute. 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] decode(DerInputStream in) throws IOException { 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue val = in.getDerValue(); 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // save the DER encoding with its proper tag byte. 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] derEncoding = val.toByteArray(); 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski derEncoding[0] = DerValue.tag_SetOf; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerInputStream derIn = new DerInputStream(derEncoding); 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerValue[] derVals = derIn.getSet(3,true); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PKCS9Attribute attrib; 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier oid; 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean reuseEncoding = true; 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i < derVals.length; i++) { 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attrib = new PKCS9Attribute(derVals[i]); 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ParsingException e) { 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ignoreUnsupportedAttributes) { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski reuseEncoding = false; // cannot reuse supplied DER encoding 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; // skip 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw e; 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski oid = attrib.getOID(); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (attributes.get(oid) != null) 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Duplicate PKCS9 attribute: " + oid); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (permittedAttributes != null && 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski !permittedAttributes.containsKey(oid)) 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Attribute " + oid + 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski " not permitted in this attribute set"); 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attributes.put(oid, attrib); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return reuseEncoding ? derEncoding : generateDerEncoding(); 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Put the DER encoding of this PKCS9 attribute set on an 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DerOutputStream, tagged with the given implicit tag. 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param tag the implicit tag to use in the DER encoding. 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param out the output stream on which to put the DER encoding. 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException on output error. 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void encode(byte tag, OutputStream out) throws IOException { 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(tag); 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(derEncoding, 1, derEncoding.length -1); 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] generateDerEncoding() throws IOException { 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerOutputStream out = new DerOutputStream(); 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object[] attribVals = attributes.values().toArray(); 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.putOrderedSetOf(DerValue.tag_SetOf, 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski castToDerEncoder(attribVals)); 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return out.toByteArray(); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return the DER encoding of this attribute set, tagged with 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DerValue.tag_SetOf. 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] getDerEncoding() throws IOException { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return derEncoding.clone(); 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an attribute from this set. 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attribute getAttribute(ObjectIdentifier oid) { 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return attributes.get(oid); 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an attribute from this set. 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attribute getAttribute(String name) { 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return attributes.get(PKCS9Attribute.getOID(name)); 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an array of all attributes in this set, in order of OID. 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public PKCS9Attribute[] getAttributes() { 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()]; 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier oid; 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int j = 0; 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=1; i < PKCS9Attribute.PKCS9_OIDS.length && 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski j < attribs.length; i++) { 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (attribs[j] != null) 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski j++; 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return attribs; 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an attribute value by OID. 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object getAttributeValue(ObjectIdentifier oid) 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException { 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object value = getAttribute(oid).getValue(); 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return value; 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NullPointerException ex) { 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("No value found for attribute " + oid); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get an attribute value by type name. 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object getAttributeValue(String name) throws IOException { 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier oid = PKCS9Attribute.getOID(name); 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oid == null) 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Attribute name " + name + 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski " not recognized or not supported."); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getAttributeValue(oid); 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the PKCS9 block in a printable string form. 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuffer buf = new StringBuffer(200); 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buf.append("PKCS9 Attributes: [\n\t"); 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ObjectIdentifier oid; 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PKCS9Attribute value; 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean first = true; 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) { 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == null) continue; 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // we have a value; print it 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (first) 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski first = false; 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buf.append(";\n\t"); 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buf.append(value.toString()); 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buf.append("\n\t] (end PKCS9 Attributes)"); 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return buf.toString(); 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Cast an object array whose components are 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>DerEncoder</code>s to <code>DerEncoder[]</code>. 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static DerEncoder[] castToDerEncoder(Object[] objs) { 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DerEncoder[] encoders = new DerEncoder[objs.length]; 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i < encoders.length; i++) 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encoders[i] = (DerEncoder) objs[i]; 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return encoders; 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 366