/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* Class supporting any PKCS9 attributes.
*
* The following table shows the correspondence between
* PKCS9 attribute types and value component classes.
* For types not listed here, its name is the OID
* in string form, its value is a (single-valued)
* byte array that is the SET's encoding.
*
* <P>
* <TABLE BORDER CELLPADDING=8 ALIGN=CENTER>
*
* <TR>
* <TH>Object Identifier</TH>
* <TH>Attribute Name</TH>
* <TH>Type</TH>
* <TH>Value Class</TH>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.1</TD>
* <TD>EmailAddress</TD>
* <TD>Multi-valued</TD>
* <TD><code>String[]</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.2</TD>
* <TD>UnstructuredName</TD>
* <TD>Multi-valued</TD>
* <TD><code>String[]</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.3</TD>
* <TD>ContentType</TD>
* <TD>Single-valued</TD>
* <TD><code>ObjectIdentifier</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.4</TD>
* <TD>MessageDigest</TD>
* <TD>Single-valued</TD>
* <TD><code>byte[]</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.5</TD>
* <TD>SigningTime</TD>
* <TD>Single-valued</TD>
* <TD><code>Date</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.6</TD>
* <TD>Countersignature</TD>
* <TD>Multi-valued</TD>
* <TD><code>SignerInfo[]</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.7</TD>
* <TD>ChallengePassword</TD>
* <TD>Single-valued</TD>
* <TD><code>String</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.8</TD>
* <TD>UnstructuredAddress</TD>
* <TD>Single-valued</TD>
* <TD><code>String</code></TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.9</TD>
* <TD>ExtendedCertificateAttributes</TD>
* <TD>Multi-valued</TD>
* <TD>(not supported)</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.10</TD>
* <TD>IssuerAndSerialNumber</TD>
* <TD>Single-valued</TD>
* <TD>(not supported)</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.{11,12}</TD>
* <TD>RSA DSI proprietary</TD>
* <TD>Single-valued</TD>
* <TD>(not supported)</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.13</TD>
* <TD>Single-valued</TD>
* <TD>(not supported)</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.14</TD>
* <TD>ExtensionRequest</TD>
* <TD>Single-valued</TD>
* <TD>CertificateExtensions</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.15</TD>
* <TD>SMIMECapability</TD>
* <TD>Single-valued</TD>
* <TD>(not supported)</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.16.2.12</TD>
* <TD>SigningCertificate</TD>
* <TD>Single-valued</TD>
* <TD>SigningCertificateInfo</TD>
* </TR>
*
* <TR>
* <TD>1.2.840.113549.1.9.16.2.14</TD>
* <TD>SignatureTimestampToken</TD>
* <TD>Single-valued</TD>
* <TD>byte[]</TD>
* </TR>
*
* </TABLE>
*
* @author Douglas Hoover
*/
/* Are we debugging ? */
/**
* Array of attribute OIDs defined in PKCS9, by number.
*/
static { // static initializer for PKCS9_OIDS
PKCS9_OIDS[i] =
}
// Initialize SigningCertificate and SignatureTimestampToken
// separately (because their values are out of sequence)
try {
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e.toString());
}
}
// first element [0] not used
= PKCS9_OIDS[9];
// [11], [12] are RSA DSI proprietary
PKCS9_OIDS[17];
"ExtendedCertificateAttributes";
// [11], [12] are RSA DSI proprietary
"SignatureTimestampToken";
/**
* Hashtable mapping names and variant names of supported
* attributes to their OIDs. This table contains all name forms
* that occur in PKCS9, in lower case.
*/
static { // static initializer for PCKS9_NAMES
};
/**
* Hashtable mapping attribute OIDs defined in PKCS9 to the
* corresponding attribute value type.
*/
static {
}
/**
* Acceptable ASN.1 tags for DER encodings of values of PKCS9
* attributes, by index in <code>PKCS9_OIDS</code>.
* Sets of acceptable tags are represented as arrays.
*/
null,
null,
null,
null,
};
static {
try {
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e.toString());
}
}
/**
* Array indicating which PKCS9 attributes are single-valued,
* by index in <code>PKCS9_OIDS</code>.
*/
private static final boolean[] SINGLE_VALUED = {
false,
false, // EMailAddress
false, // UnstructuredName
true, // ContentType
true, // MessageDigest
true, // SigningTime
false, // Countersignature
true, // ChallengePassword
false, // UnstructuredAddress
false, // ExtendedCertificateAttributes
true, // IssuerAndSerialNumber - not supported yet
false, // not used
false, // not used
false, // not used
true, // ExtensionRequest
true, // SMIMECapability - not supported yet
true, // SigningCertificate
true // SignatureTimestampToken
};
/**
* The OID of this attribute.
*/
/**
* The index of the OID of this attribute in <code>PKCS9_OIDS</code>,
* or -1 if it's unknown.
*/
private int index;
/**
* Value set of this attribute. Its class is given by
* <code>VALUE_CLASSES[index]</code>. The SET itself
* as byte[] if unknown.
*/
/**
* Construct an attribute object from the attribute's OID and
* value. If the attribute is single-valued, provide only one
* value. If the attribute is multi-valued, provide an array
* containing all the values.
* Arrays of length zero are accepted, though probably useless.
*
* <P> The
* <a href=#classTable>table</a> gives the class that <code>value</code>
* must have for a given attribute.
*
* @exception IllegalArgumentException
* if the <code>value</code> has the wrong type.
*/
throws IllegalArgumentException {
}
/**
* Construct an attribute object from the attribute's name and
* value. If the attribute is single-valued, provide only one
* value. If the attribute is multi-valued, provide an array
* containing all the values.
* Arrays of length zero are accepted, though probably useless.
*
* <P> The
* <a href=#classTable>table</a> gives the class that <code>value</code>
* must have for a given attribute. Reasonable variants of these
* attributes are accepted; in particular, case does not matter.
*
* @exception IllegalArgumentException
* if the <code>name</code> is not recognized or the
* <code>value</code> has the wrong type.
*/
throws IllegalArgumentException {
throw new IllegalArgumentException(
"Unrecognized attribute name " + name +
" constructing PKCS9Attribute.");
}
throws IllegalArgumentException {
throw new IllegalArgumentException(
"Wrong value class " +
" for attribute " + oid +
" constructing PKCS9Attribute; was " +
}
}
/**
* Construct a PKCS9Attribute from its encoding on an input
* stream.
*
* @param val the DerValue representing the DER encoding of the attribute.
* @exception IOException on parsing error.
*/
throw new IOException("Excess data parsing PKCS9Attribute");
throw new IOException("PKCS9Attribute doesn't have two components");
// get the oid
if (index == -1) {
}
return;
}
// check single valued have only one value
// check for illegal element tags
}
switch (index) {
case 1: // email address
case 2: // unstructured name
case 8: // unstructured address
{ // open scope
} // close scope
break;
case 3: // content type
break;
case 4: // message digest
break;
case 5: // signing time
break;
case 6: // countersignature
{ // open scope
values[i] =
} // close scope
break;
case 7: // challenge password
break;
case 9: // extended-certificate attribute -- not supported
throw new IOException("PKCS9 extended-certificate " +
"attribute not supported.");
// break unnecessary
case 10: // issuerAndserialNumber attribute -- not supported
throw new IOException("PKCS9 IssuerAndSerialNumber" +
"attribute not supported.");
// break unnecessary
case 11: // RSA DSI proprietary
case 12: // RSA DSI proprietary
throw new IOException("PKCS9 RSA DSI attributes" +
"11 and 12, not supported.");
// break unnecessary
throw new IOException("PKCS9 attribute #13 not supported.");
// break unnecessary
case 14: // ExtensionRequest
value = new CertificateExtensions(
break;
case 15: // SMIME-capability attribute -- not supported
throw new IOException("PKCS9 SMIMECapability " +
"attribute not supported.");
// break unnecessary
case 16: // SigningCertificate attribute
break;
case 17: // SignatureTimestampToken attribute
break;
default: // can't happen
}
}
/**
* Write the DER encoding of this attribute to an output stream.
*
* <P> N.B.: This method always encodes values of
* ChallengePassword and UnstructuredAddress attributes as ASN.1
* <code>PrintableString</code>s, without checking whether they
* should be encoded as <code>T61String</code>s.
*/
switch (index) {
case -1: // Unknown
break;
case 1: // email address
case 2: // unstructured name
{ // open scope
DerOutputStream[] temps = new
temps[i] = new DerOutputStream();
}
} // close scope
break;
case 3: // content type
{
}
break;
case 4: // message digest
{
}
break;
case 5: // signing time
{
}
break;
case 6: // countersignature
break;
case 7: // challenge password
{
}
break;
case 8: // unstructured address
{ // open scope
DerOutputStream[] temps = new
temps[i] = new DerOutputStream();
}
} // close scope
break;
case 9: // extended-certificate attribute -- not supported
throw new IOException("PKCS9 extended-certificate " +
"attribute not supported.");
// break unnecessary
case 10: // issuerAndserialNumber attribute -- not supported
throw new IOException("PKCS9 IssuerAndSerialNumber" +
"attribute not supported.");
// break unnecessary
case 11: // RSA DSI proprietary
case 12: // RSA DSI proprietary
throw new IOException("PKCS9 RSA DSI attributes" +
"11 and 12, not supported.");
// break unnecessary
throw new IOException("PKCS9 attribute #13 not supported.");
// break unnecessary
case 14: // ExtensionRequest
{
try {
} catch (CertificateException ex) {
}
}
break;
case 15: // SMIMECapability
throw new IOException("PKCS9 attribute #15 not supported.");
// break unnecessary
case 16: // SigningCertificate
throw new IOException(
"PKCS9 SigningCertificate attribute not supported.");
// break unnecessary
case 17: // SignatureTimestampToken
break;
default: // can't happen
}
}
/**
* Returns if the attribute is known. Unknown attributes can be created
* from DER encoding with unknown OIDs.
*/
public boolean isKnown() {
return index != -1;
}
/**
* Get the value of this attribute. If the attribute is
* single-valued, return just the one value. If the attribute is
* multi-valued, return an array containing all the values.
* It is possible for this array to be of length 0.
*
* <P> The
* <a href=#classTable>table</a> gives the class of the value returned,
* depending on the type of this attribute.
*/
return value;
}
/**
* Show whether this attribute is single-valued.
*/
public boolean isSingleValued() {
}
/**
* Return the OID of this attribute.
*/
return oid;
}
/**
* Return the name of this attribute.
*/
return index == -1 ?
}
/**
* Return the OID for a given attribute name or null if we don't recognize
* the name.
*/
}
/**
* Return the attribute name for a given OID or null if we don't recognize
* the oid.
*/
}
/**
* Returns a string representation of this attribute.
*/
if (index == -1) {
} else {
}
if (value instanceof byte[]) { // special case for octet string
} else {
}
} else { // multi-valued
boolean first = true;
if (first)
first = false;
else
}
}
}
/**
* Beginning the search at <code>start</code>, find the first
* index <code>i</code> such that <code>a[i] = obj</code>.
*
* @return the index, if found, and -1 otherwise.
*/
}
return -1;
}
/**
* Throw an exception when there are multiple values for
* a single-valued attribute.
*/
throw new IOException("Single-value attribute " +
" has multiple values.");
}
/**
* Throw an exception when the tag on a value encoding is
* wrong for the attribute whose value it is. This method
* will only be called for known tags.
*/
throws IOException {
}
}
}