004-11-15 Andreas Tobler <a.tobler@schweiz.ch>

Import/Merge the X.509 certificate code from Classpath.

	* Makefile.am: Add imported files.
	* Makefile.in: Regenerate.

	2004-11-07  Casey Marshall  <csm@gnu.org>

	* gnu/java/security/provider/Gnu.java(<init>): Add entries in a
	priviliged action. Add new algorithms.
	* gnu/java/security/provider/X509CertificateFactory.java
	(engineGenerateCertificate): Chain exceptions.
	(engineGenerateCertificates): Likewise.
	(engineGenerateCRL): Likewise.
	(engineGenerateCRLs): Likewise.
	(engineGenerateCertPath): New methods.
	(generateCert): Throw exception if 'inStream' is null.
	(generateCRL): Likewise.
	* gnu/java/security/x509/X500DistinguishedName.java: Replaced with
	version from GNU Crypto CVS.
	* gnu/java/security/x509/X509CRL.java: Likewise.
	* gnu/java/security/x509/X509CRLEntry.java: Likewise.
	* gnu/java/security/x509/X509Certificate.java: Likewise.
	* java/security/cert/TrustAnchor.java: Call 'toString' and not
	toRFC2253.
	* gnu/java/security/provider/CollectionCertStoreImpl.java,
	* gnu/java/security/provider/EncodedKeyFactory.java,
	* gnu/java/security/provider/GnuDHPublicKey.java,
	* gnu/java/security/provider/GnuRSAPrivateKey.java,
	* gnu/java/security/provider/GnuRSAPublicKey.java,
	* gnu/java/security/provider/MD2withRSA.java,
	* gnu/java/security/provider/MD4withRSA.java,
	* gnu/java/security/provider/MD5withRSA.java,
	* gnu/java/security/provider/PKIXCertPathValidatorImpl.java,
	* gnu/java/security/provider/RSA.java,
	* gnu/java/security/provider/RSAKeyFactory.java,
	* gnu/java/security/provider/SHA1withRSA.java,
	* gnu/java/security/x509/GnuPKIExtension.java,
	* gnu/java/security/x509/PolicyNodeImpl.java,
	* gnu/java/security/x509/Util.java,
	* gnu/java/security/x509/X509CRLSelectorImpl.java,
	* gnu/java/security/x509/X509CertPath.java,
	* gnu/java/security/x509/X509CertSelectorImpl.java,
	* gnu/java/security/x509/ext/AuthorityKeyIdentifier.java,
	* gnu/java/security/x509/ext/BasicConstraints.java,
	* gnu/java/security/x509/ext/CRLNumber.java,
	* gnu/java/security/x509/ext/CertificatePolicies.java,
	* gnu/java/security/x509/ext/ExtendedKeyUsage.java,
	* gnu/java/security/x509/ext/Extension.java,
	* gnu/java/security/x509/ext/GeneralNames.java,
	* gnu/java/security/x509/ext/IssuerAlternativeNames.java,
	* gnu/java/security/x509/ext/KeyUsage.java,
	* gnu/java/security/x509/ext/PolicyConstraint.java,
	* gnu/java/security/x509/ext/PolicyMappings.java,
	* gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java,
	* gnu/java/security/x509/ext/ReasonCode.java,
	* gnu/java/security/x509/ext/SubjectAlternativeNames.java,
	* gnu/java/security/x509/ext/SubjectKeyIdentifier.java: New files.

	2004-11-07  Casey Marshall  <csm@gnu.org>

	* gnu/java/security/x509/X509CRL.java:
	Missed import statements in previous checkin.

	2004-11-07  Casey Marshall  <csm@gnu.org>

	* gnu/java/security/x509/X509CertPath.java (parse): Fixed reference
	to 'X509CertificateImpl' from previous checkin.

From-SVN: r90682
This commit is contained in:
Andreas Tobler
2004-11-15 21:02:08 +01:00
parent fcb94d103b
commit 507148866c
43 changed files with 6698 additions and 1138 deletions
@@ -0,0 +1,59 @@
/* GnuPKIExtension.java -- interface for GNU PKI extensions.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509;
import java.security.cert.X509Extension;
import java.util.Collection;
import gnu.java.security.OID;
import gnu.java.security.x509.ext.Extension;
public interface GnuPKIExtension extends X509Extension
{
/**
* Returns the extension object for the given object identifier.
*
* @param oid The OID of the extension to get.
* @return The extension, or null if there is no such extension.
*/
Extension getExtension(OID oid);
Collection getExtensions();
}
@@ -0,0 +1,214 @@
/* PolicyNodeImpl.java -- An implementation of a policy tree node.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509;
import java.security.cert.PolicyNode;
import java.security.cert.PolicyQualifierInfo;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public final class PolicyNodeImpl implements PolicyNode
{
// Fields.
// -------------------------------------------------------------------------
private String policy;
private final Set expectedPolicies;
private final Set qualifiers;
private final Set children;
private PolicyNodeImpl parent;
private int depth;
private boolean critical;
private boolean readOnly;
// Constructors.
// -------------------------------------------------------------------------
public PolicyNodeImpl()
{
expectedPolicies = new HashSet();
qualifiers = new HashSet();
children = new HashSet();
readOnly = false;
critical = false;
}
// Instance methods.
// -------------------------------------------------------------------------
public void addChild(PolicyNodeImpl node)
{
if (readOnly)
throw new IllegalStateException("read only");
if (node.getParent() != null)
throw new IllegalStateException("already a child node");
node.parent = this;
node.setDepth(depth + 1);
children.add(node);
}
public Iterator getChildren()
{
return Collections.unmodifiableSet(children).iterator();
}
public int getDepth()
{
return depth;
}
public void setDepth(int depth)
{
if (readOnly)
throw new IllegalStateException("read only");
this.depth = depth;
}
public void addAllExpectedPolicies(Set policies)
{
if (readOnly)
throw new IllegalStateException("read only");
expectedPolicies.addAll(policies);
}
public void addExpectedPolicy(String policy)
{
if (readOnly)
throw new IllegalStateException("read only");
expectedPolicies.add(policy);
}
public Set getExpectedPolicies()
{
return Collections.unmodifiableSet(expectedPolicies);
}
public PolicyNode getParent()
{
return parent;
}
public void addAllPolicyQualifiers (Collection qualifiers)
{
for (Iterator it = qualifiers.iterator(); it.hasNext(); )
{
if (!(it.next() instanceof PolicyQualifierInfo))
throw new IllegalArgumentException ("can only add PolicyQualifierInfos");
}
qualifiers.addAll (qualifiers);
}
public void addPolicyQualifier (PolicyQualifierInfo qualifier)
{
if (readOnly)
throw new IllegalStateException("read only");
qualifiers.add(qualifier);
}
public Set getPolicyQualifiers()
{
return Collections.unmodifiableSet(qualifiers);
}
public String getValidPolicy()
{
return policy;
}
public void setValidPolicy(String policy)
{
if (readOnly)
throw new IllegalStateException("read only");
this.policy = policy;
}
public boolean isCritical()
{
return critical;
}
public void setCritical(boolean critical)
{
if (readOnly)
throw new IllegalStateException("read only");
this.critical = critical;
}
public void setReadOnly()
{
if (readOnly)
return;
readOnly = true;
for (Iterator it = getChildren(); it.hasNext(); )
((PolicyNodeImpl) it.next()).setReadOnly();
}
public String toString()
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < depth; i++)
buf.append(" ");
buf.append("(");
buf.append(PolicyNodeImpl.class.getName());
buf.append(" (oid ");
buf.append(policy);
buf.append(") (depth ");
buf.append(depth);
buf.append(") (qualifiers ");
buf.append(qualifiers);
buf.append(") (critical ");
buf.append(critical);
buf.append(") (expectedPolicies ");
buf.append(expectedPolicies);
buf.append(") (children (");
final String nl = System.getProperty("line.separator");
for (Iterator it = getChildren(); it.hasNext(); )
{
buf.append(nl);
buf.append(it.next().toString());
}
buf.append(")))");
return buf.toString();
}
}
+202
View File
@@ -0,0 +1,202 @@
/* Util.java -- Miscellaneous utility methods.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509;
/**
* A collection of useful class methods.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public final class Util
{
// Constants.
// -------------------------------------------------------------------------
public static final String HEX = "0123456789abcdef";
// Class methods.
// -------------------------------------------------------------------------
/**
* Convert a byte array to a hexadecimal string, as though it were a
* big-endian arbitrarily-sized integer.
*
* @param buf The bytes to format.
* @param off The offset to start at.
* @param len The number of bytes to format.
* @return A hexadecimal representation of the specified bytes.
*/
public static String toHexString(byte[] buf, int off, int len)
{
StringBuffer str = new StringBuffer();
for (int i = 0; i < len; i++)
{
str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
str.append(HEX.charAt(buf[i+off] & 0x0F));
}
return str.toString();
}
/**
* See {@link #toHexString(byte[],int,int)}.
*/
public static String toHexString(byte[] buf)
{
return Util.toHexString(buf, 0, buf.length);
}
/**
* Convert a byte array to a hexadecimal string, separating octets
* with the given character.
*
* @param buf The bytes to format.
* @param off The offset to start at.
* @param len The number of bytes to format.
* @param sep The character to insert between octets.
* @return A hexadecimal representation of the specified bytes.
*/
public static String toHexString(byte[] buf, int off, int len, char sep)
{
StringBuffer str = new StringBuffer();
for (int i = 0; i < len; i++)
{
str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
str.append(HEX.charAt(buf[i+off] & 0x0F));
if (i < len - 1)
str.append(sep);
}
return str.toString();
}
/**
* See {@link #toHexString(byte[],int,int,char)}.
*/
public static String toHexString(byte[] buf, char sep)
{
return Util.toHexString(buf, 0, buf.length, sep);
}
/**
* Create a representation of the given byte array similar to the
* output of `hexdump -C', which is
*
* <p><pre>OFFSET SIXTEEN-BYTES-IN-HEX PRINTABLE-BYTES</pre>
*
* <p>The printable bytes show up as-is if they are printable and
* not a newline character, otherwise showing as '.'.
*
* @param buf The bytes to format.
* @param off The offset to start at.
* @param len The number of bytes to encode.
* @return The formatted string.
*/
public static String hexDump(byte[] buf, int off, int len, String prefix)
{
String nl = System.getProperty("line.separator");
StringBuffer str = new StringBuffer();
int i = 0;
while (i < len)
{
str.append(prefix);
str.append(Util.formatInt(i+off, 16, 8));
str.append(" ");
String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' ');
str.append(s);
for (int j = 56 - (56 - s.length()); j < 56; j++)
str.append(" ");
for (int j = 0; j < Math.min(16, len - i); j++)
{
if ((buf[i+off+j] & 0xFF) < 0x20 || (buf[i+off+j] & 0xFF) > 0x7E)
str.append('.');
else
str.append((char) (buf[i+off+j] & 0xFF));
}
str.append(nl);
i += 16;
}
return str.toString();
}
/**
* See {@link #hexDump(byte[],int,int)}.
*/
public static String hexDump(byte[] buf, String prefix)
{
return hexDump(buf, 0, buf.length, prefix);
}
/**
* Format an integer into the specified radix, zero-filled.
*
* @param i The integer to format.
* @param radix The radix to encode to.
* @param len The target length of the string. The string is
* zero-padded to this length, but may be longer.
* @return The formatted integer.
*/
public static String formatInt(int i, int radix, int len)
{
String s = Integer.toString(i, radix);
StringBuffer buf = new StringBuffer();
for (int j = 0; j < len - s.length(); j++)
buf.append("0");
buf.append(s);
return buf.toString();
}
/**
* Convert a hexadecimal string into its byte representation.
*
* @param hex The hexadecimal string.
* @return The converted bytes.
*/
public static byte[] toByteArray(String hex)
{
hex = hex.toLowerCase();
byte[] buf = new byte[hex.length() / 2];
int j = 0;
for (int i = 0; i < buf.length; i++)
{
buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) |
Character.digit(hex.charAt(j++), 16));
}
return buf;
}
}
File diff suppressed because it is too large Load Diff
+129 -51
View File
@@ -7,7 +7,7 @@ GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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
@@ -44,6 +44,7 @@ import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.x509.ext.Extension;
import java.io.InputStream;
import java.io.IOException;
@@ -57,11 +58,12 @@ import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CRLException;
import java.security.cert.X509CRLEntry;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
@@ -72,11 +74,22 @@ import javax.security.auth.x500.X500Principal;
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class X509CRL extends java.security.cert.X509CRL
implements GnuPKIExtension
{
// Constants and fields.
// ------------------------------------------------------------------------
private static final boolean DEBUG = false;
private static void debug(String msg)
{
if (DEBUG)
{
System.err.print(">> X509CRL: ");
System.err.println(msg);
}
}
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
private static final OID ID_DSA_WITH_SHA1 = new OID("1.2.840.10040.4.3");
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
@@ -92,12 +105,10 @@ public class X509CRL extends java.security.cert.X509CRL
private byte[] algParams;
private Date thisUpdate;
private Date nextUpdate;
private X500Principal issuerDN;
private X500DistinguishedName issuerDN;
private HashMap revokedCerts;
private HashMap extensions;
private HashSet critOids;
private HashSet nonCritOids;
private OID sigAlg;
private byte[] sigAlgParams;
private byte[] rawSig;
@@ -118,8 +129,6 @@ public class X509CRL extends java.security.cert.X509CRL
super();
revokedCerts = new HashMap();
extensions = new HashMap();
critOids = new HashSet();
nonCritOids = new HashSet();
try
{
parse(encoded);
@@ -141,7 +150,9 @@ public class X509CRL extends java.security.cert.X509CRL
public boolean equals(Object o)
{
return ((X509CRL) o).revokedCerts.equals(revokedCerts);
if (!(o instanceof X509CRL))
return false;
return ((X509CRL) o).getRevokedCertificates().equals(revokedCerts.values());
}
public int hashCode()
@@ -182,7 +193,7 @@ public class X509CRL extends java.security.cert.X509CRL
public X500Principal getIssuerX500Principal()
{
return issuerDN;
return new X500Principal(issuerDN.getDer());
}
public Date getThisUpdate()
@@ -197,9 +208,9 @@ public class X509CRL extends java.security.cert.X509CRL
return null;
}
public X509CRLEntry getRevokedCertificate(BigInteger serialNo)
public java.security.cert.X509CRLEntry getRevokedCertificate(BigInteger serialNo)
{
return (X509CRLEntry) revokedCerts.get(serialNo);
return (java.security.cert.X509CRLEntry) revokedCerts.get(serialNo);
}
public Set getRevokedCertificates()
@@ -247,33 +258,68 @@ public class X509CRL extends java.security.cert.X509CRL
public boolean hasUnsupportedCriticalExtension()
{
return false; // XXX
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical() && !e.isSupported())
return true;
}
return false;
}
public Set getCriticalExtensionOIDs()
{
return Collections.unmodifiableSet(critOids);
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public Set getNonCriticalExtensionOIDs()
{
return Collections.unmodifiableSet(nonCritOids);
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (!e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public byte[] getExtensionValue(String oid)
{
byte[] ext = (byte[]) extensions.get(oid);
if (ext != null)
return (byte[]) ext.clone();
Extension e = getExtension(new OID(oid));
if (e != null)
{
return e.getValue().getEncoded();
}
return null;
}
// GnuPKIExtension method.
// -------------------------------------------------------------------------
public Extension getExtension(OID oid)
{
return (Extension) extensions.get(oid);
}
public Collection getExtensions()
{
return extensions.values();
}
// CRL methods.
// ------------------------------------------------------------------------
// -------------------------------------------------------------------------
public String toString()
{
return gnu.java.security.x509.X509CRL.class.getName();
return X509CRL.class.getName();
}
public boolean isRevoked(Certificate cert)
@@ -302,17 +348,23 @@ public class X509CRL extends java.security.cert.X509CRL
private void parse(InputStream in) throws Exception
{
// CertificateList ::= SEQUENCE {
DERReader der = new DERReader(in);
DERValue val = der.read();
debug("start CertificateList len == " + val.getLength());
if (!val.isConstructed())
throw new ASN1ParsingException("malformed CertificateList");
throw new IOException("malformed CertificateList");
encoded = val.getEncoded();
// tbsCertList ::= SEQUENCE { -- TBSCertList
val = der.read();
if (!val.isConstructed())
throw new ASN1ParsingException("malformed TBSCertList");
throw new IOException("malformed TBSCertList");
debug("start tbsCertList len == " + val.getLength());
tbsCRLBytes = val.getEncoded();
// version Version OPTIONAL,
// -- If present must be v2
val = der.read();
if (val.getValue() instanceof BigInteger)
{
@@ -321,78 +373,104 @@ public class X509CRL extends java.security.cert.X509CRL
}
else
version = 1;
debug("read version == " + version);
// signature AlgorithmIdentifier,
debug("start AlgorithmIdentifier len == " + val.getLength());
if (!val.isConstructed())
throw new ASN1ParsingException("malformed AlgorithmIdentifier");
throw new IOException("malformed AlgorithmIdentifier");
DERValue algIdVal = der.read();
algId = (OID) algIdVal.getValue();
debug("read object identifier == " + algId);
if (val.getLength() > algIdVal.getEncodedLength())
{
val = der.read();
debug("read parameters len == " + val.getEncodedLength());
algParams = val.getEncoded();
if (val.isConstructed())
in.skip(val.getLength());
}
issuerDN = new X500Principal(in);
// issuer Name,
val = der.read();
issuerDN = new X500DistinguishedName(val.getEncoded());
der.skip(val.getLength());
debug("read issuer == " + issuerDN);
// thisUpdate Time,
thisUpdate = (Date) der.read().getValue();
debug("read thisUpdate == " + thisUpdate);
// nextUpdate Time OPTIONAL,
val = der.read();
if (val.getValue() instanceof Date)
{
nextUpdate = (Date) val.getValue();
debug("read nextUpdate == " + nextUpdate);
val = der.read();
}
// revokedCertificates SEQUENCE OF SEQUENCE {
// -- X509CRLEntry objects...
// } OPTIONAL,
if (val.getTag() != 0)
{
int len = 0;
while (len < val.getLength())
{
X509CRLEntry entry =
new gnu.java.security.x509.X509CRLEntry(version, in);
X509CRLEntry entry = new X509CRLEntry(version, der);
revokedCerts.put(entry.getSerialNumber(), entry);
len += entry.getEncoded().length;
}
}
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0)
{
val = der.read();
int len = 0;
while (len < val.getLength())
{
DERValue ext = der.read();
OID extId = (OID) der.read().getValue();
DERValue val2 = der.read();
Boolean crit = Boolean.valueOf(false);
if (val2.getValue() instanceof Boolean)
{
crit = (Boolean) val2.getValue();
val2 = der.read();
}
byte[] extVal = (byte[]) val2.getValue();
extensions.put(extId.toString(), extVal);
if (crit.booleanValue())
critOids.add(extId.toString());
else
nonCritOids.add(extId.toString());
len += ext.getEncodedLength();
}
}
val = der.read();
// crlExtensions [0] EXPLICIT Extensions OPTIONAL
// -- if present MUST be v2
if (val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0)
{
if (version < 2)
throw new IOException("extra data in CRL");
DERValue exts = der.read();
if (!exts.isConstructed())
throw new IOException("malformed Extensions");
debug("start Extensions len == " + exts.getLength());
int len = 0;
while (len < exts.getLength())
{
DERValue ext = der.read();
if (!ext.isConstructed())
throw new IOException("malformed Extension");
Extension e = new Extension(ext.getEncoded());
extensions.put(e.getOid(), e);
der.skip(ext.getLength());
len += ext.getEncodedLength();
debug("current count == " + len);
}
val = der.read();
}
debug("read tag == " + val.getTag());
if (!val.isConstructed())
throw new ASN1ParsingException("malformed AlgorithmIdentifier");
throw new IOException("malformed AlgorithmIdentifier");
debug("start AlgorithmIdentifier len == " + val.getLength());
DERValue sigAlgVal = der.read();
debug("read tag == " + sigAlgVal.getTag());
if (sigAlgVal.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed AlgorithmIdentifier");
sigAlg = (OID) sigAlgVal.getValue();
debug("signature id == " + sigAlg);
debug("sigAlgVal length == " + sigAlgVal.getEncodedLength());
if (val.getLength() > sigAlgVal.getEncodedLength())
{
val = der.read();
debug("sig params tag = " + val.getTag() + " len == " + val.getEncodedLength());
sigAlgParams = (byte[]) val.getEncoded();
if (val.isConstructed())
in.skip(val.getLength());
}
val = der.read();
debug("read tag = " + val.getTag());
rawSig = val.getEncoded();
signature = ((BitString) val.getValue()).toByteArray();
}
@@ -1,5 +1,5 @@
/* X509CRLEntry.java -- entry in a X.509 CRL.
Copyright (C) 2003 Free Software Foundation, Inc.
/* X509CRLEntry.java -- an entry in a X.509 CRL.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -7,7 +7,7 @@ GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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
@@ -45,17 +45,17 @@ import java.math.BigInteger;
import java.security.cert.CRLException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import gnu.java.io.ASN1ParsingException;
import gnu.java.security.OID;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.der.*;
import gnu.java.security.x509.ext.*;
/**
* A single entry in a X.509 certificate revocation list.
@@ -64,11 +64,22 @@ import gnu.java.security.der.DERWriter;
* @author Casey Marshall
*/
class X509CRLEntry extends java.security.cert.X509CRLEntry
implements GnuPKIExtension
{
// Constants and fields.
// ------------------------------------------------------------------------
private static final boolean DEBUG = false;
private static void debug(String msg)
{
if (DEBUG)
{
System.err.print(">> X509CRLEntry: ");
System.err.println(msg);
}
}
/** The DER encoded form of this CRL entry. */
private byte[] encoded;
@@ -78,15 +89,9 @@ class X509CRLEntry extends java.security.cert.X509CRLEntry
/** The date the certificate was revoked. */
private Date revocationDate;
/** The encoded extensions. */
/** The CRL entry extensions. */
private HashMap extensions;
/** The set of critical extension OIDs. */
private HashSet critOids;
/** the set of non-critical extension OIDs. */
private HashSet nonCritOids;
// Constructor.
// ------------------------------------------------------------------------
@@ -99,13 +104,11 @@ class X509CRLEntry extends java.security.cert.X509CRLEntry
* @throws CRLException If the ASN.1 structure is invalid.
* @throws IOException If the bytes cannot be read.
*/
X509CRLEntry(int version, InputStream encoded)
X509CRLEntry(int version, DERReader encoded)
throws CRLException, IOException
{
super();
extensions = new HashMap();
critOids = new HashSet();
nonCritOids = new HashSet();
try
{
parse(version, encoded);
@@ -125,8 +128,10 @@ class X509CRLEntry extends java.security.cert.X509CRLEntry
public boolean equals(Object o)
{
return ((X509CRLEntry) o).serialNo.equals(serialNo) &&
((X509CRLEntry) o).revocationDate.equals(revocationDate);
if (!(o instanceof X509CRLEntry))
return false;
return ((X509CRLEntry) o).getSerialNumber().equals(serialNo) &&
((X509CRLEntry) o).getRevocationDate().equals(revocationDate);
}
public int hashCode()
@@ -157,79 +162,119 @@ class X509CRLEntry extends java.security.cert.X509CRLEntry
public String toString()
{
return "X509CRLEntry serial=" + serialNo + " revocation date="
+ revocationDate + " critExt=" + critOids + " ext=" + nonCritOids;
+ revocationDate + " ext=" + extensions;
}
// X509Extension methods.
// ------------------------------------------------------------------------
// -------------------------------------------------------------------------
public boolean hasUnsupportedCriticalExtension()
{
return false; // XXX
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical() && !e.isSupported())
return true;
}
return false;
}
public Set getCriticalExtensionOIDs()
{
return Collections.unmodifiableSet(critOids);
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public Set getNonCriticalExtensionOIDs()
{
return Collections.unmodifiableSet(nonCritOids);
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (!e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public byte[] getExtensionValue(String oid)
{
byte[] ext = (byte[]) extensions.get(oid);
if (ext != null)
return (byte[]) ext.clone();
Extension e = getExtension(new OID(oid));
if (e != null)
{
return e.getValue().getEncoded();
}
return null;
}
// Own methods.
// ------------------------------------------------------------------------
// GnuPKIExtension method.
// -------------------------------------------------------------------------
private void parse(int version, InputStream in) throws Exception
public Extension getExtension(OID oid)
{
DERReader der = new DERReader(in);
return (Extension) extensions.get(oid);
}
public Collection getExtensions()
{
return extensions.values();
}
// Own methods.
// -------------------------------------------------------------------------
private void parse(int version, DERReader der) throws Exception
{
// RevokedCertificate ::= SEQUENCE {
DERValue entry = der.read();
debug("start CRL entry len == " + entry.getLength());
if (!entry.isConstructed())
throw new ASN1ParsingException("malformed revokedCertificate");
throw new IOException("malformed revokedCertificate");
encoded = entry.getEncoded();
int len = 0;
debug("encoded entry:\n" + Util.hexDump(encoded, ">>>> "));
// userCertificate CertificateSerialNumber,
DERValue val = der.read();
serialNo = (BigInteger) val.getValue();
len += DERWriter.definiteEncodingSize(val.getLength())
+ val.getLength() + 1;
len += val.getEncodedLength();
debug("userCertificate == " + serialNo + " current count == " + len);
// revocationDate Time,
val = der.read();
revocationDate = (Date) val.getValue();
len += DERWriter.definiteEncodingSize(val.getLength())
+ val.getLength() + 1;
len += val.getEncodedLength();
debug("revocationDate == " + revocationDate + " current count == " + len);
// crlEntryExtensions Extensions OPTIONAL
// -- if present MUST be v2
if (len < entry.getLength())
{
if (version < 2)
throw new ASN1ParsingException("extra data in CRL entry");
while (len < entry.getLength())
throw new IOException("extra data in CRL entry");
DERValue exts = der.read();
if (!exts.isConstructed())
throw new IOException("malformed Extensions");
debug("start Extensions len == " + exts.getLength());
len = 0;
while (len < exts.getLength())
{
val = der.read();
if (!val.isConstructed())
throw new ASN1ParsingException("malformed Extension");
OID extOid = (OID) der.read().getValue();
Boolean critical = Boolean.valueOf(false);
DERValue val2 = der.read();
if (val2.getValue() instanceof Boolean)
{
critical = (Boolean) val2.getValue();
val2 = der.read();
}
byte[] ext = (byte[]) val2.getValue();
extensions.put(extOid.toString(), ext);
if (critical.booleanValue())
critOids.add(extOid.toString());
else
nonCritOids.add(extOid.toString());
throw new IOException("malformed Extension");
debug("start Extension len == " + val.getLength());
Extension e = new Extension(val.getEncoded());
extensions.put(e.getOid(), e);
der.skip(val.getLength());
len += val.getEncodedLength();
debug("current count == " + len);
}
}
}
@@ -0,0 +1,138 @@
/* X509CRLSelectorImpl.java -- implementation of an X509CRLSelector.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509;
import java.io.IOException;
import java.security.Principal;
import java.security.cert.CRL;
import java.security.cert.CRLSelector;
import java.security.cert.X509CRL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
/**
* Sun's implementation of X509CRLSelector sucks. This one tries to work
* better.
*/
public class X509CRLSelectorImpl implements CRLSelector
{
// Fields.
// -------------------------------------------------------------------------
private Set issuerNames;
// Constructor.
// -------------------------------------------------------------------------
public X509CRLSelectorImpl()
{
issuerNames = new HashSet();
}
// Instance methods.
// -------------------------------------------------------------------------
public void addIssuerName(byte[] issuerName) throws IOException
{
issuerNames.add(new X500DistinguishedName(issuerName));
}
public void addIssuerName(String issuerName)
{
issuerNames.add(new X500DistinguishedName(issuerName));
}
public void addIssuerName(Principal issuerName) throws IOException
{
if (issuerName instanceof X500DistinguishedName)
issuerNames.add(issuerName);
else if (issuerName instanceof X500Principal)
issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded()));
else
issuerNames.add(new X500DistinguishedName(issuerName.getName()));
}
public Collection getIssuerNames()
{
return Collections.unmodifiableSet(issuerNames);
}
public Object clone()
{
X509CRLSelectorImpl copy = new X509CRLSelectorImpl();
copy.issuerNames.addAll(issuerNames);
return copy;
}
public boolean match(CRL crl)
{
if (!(crl instanceof X509CRL))
return false;
try
{
Principal p = ((X509CRL) crl).getIssuerDN();
X500DistinguishedName thisName = null;
if (p instanceof X500DistinguishedName)
thisName = (X500DistinguishedName) p;
else if (p instanceof X500Principal)
thisName = new X500DistinguishedName(((X500Principal) p).getEncoded());
else
thisName = new X500DistinguishedName(p.getName());
for (Iterator it = issuerNames.iterator(); it.hasNext(); )
{
X500DistinguishedName name = (X500DistinguishedName) it.next();
if (thisName.equals(name))
return true;
}
}
catch (Exception x)
{
}
return false;
}
}
@@ -0,0 +1,306 @@
/* X509CertPath.java -- an X.509 certificate path.
Copyright (C) 2004 Free Software Fonudation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertPath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DEREncodingException;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
/**
* A certificate path (or certificate chain) of X509Certificates.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class X509CertPath extends CertPath
{
// Fields.
// -------------------------------------------------------------------------
public static final List ENCODINGS = Collections.unmodifiableList(
Arrays.asList(new String[] { "PkiPath", "PKCS7" }));
private static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2");
private static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1");
/** The certificate path. */
private List path;
/** The cached PKCS #7 encoded bytes. */
private byte[] pkcs_encoded;
/** The cached PkiPath encoded bytes. */
private byte[] pki_encoded;
// Constructor.
// -------------------------------------------------------------------------
public X509CertPath(List path)
{
super("X.509");
this.path = Collections.unmodifiableList(path);
}
public X509CertPath(InputStream in) throws CertificateEncodingException
{
this(in, (String) ENCODINGS.get(0));
}
public X509CertPath(InputStream in, String encoding)
throws CertificateEncodingException
{
super("X.509");
try
{
parse(in, encoding);
}
catch (IOException ioe)
{
throw new CertificateEncodingException();
}
}
// Instance methods.
// -------------------------------------------------------------------------
public List getCertificates()
{
return path; // already unmodifiable
}
public byte[] getEncoded() throws CertificateEncodingException
{
return getEncoded((String) ENCODINGS.get(0));
}
public byte[] getEncoded(String encoding) throws CertificateEncodingException
{
if (encoding.equalsIgnoreCase("PkiPath"))
{
if (pki_encoded == null)
{
try
{
pki_encoded = encodePki();
}
catch (IOException ioe)
{
throw new CertificateEncodingException();
}
}
return (byte[]) pki_encoded.clone();
}
else if (encoding.equalsIgnoreCase("PKCS7"))
{
if (pkcs_encoded == null)
{
try
{
pkcs_encoded = encodePKCS();
}
catch (IOException ioe)
{
throw new CertificateEncodingException();
}
}
return (byte[]) pkcs_encoded.clone();
}
else
throw new CertificateEncodingException("unknown encoding: " + encoding);
}
public Iterator getEncodings()
{
return ENCODINGS.iterator(); // already unmodifiable
}
// Own methods.
// -------------------------------------------------------------------------
private void parse(InputStream in, String encoding)
throws CertificateEncodingException, IOException
{
DERReader der = new DERReader(in);
DERValue path = null;
if (encoding.equalsIgnoreCase("PkiPath"))
{
// PKI encoding is just a SEQUENCE of X.509 certificates.
path = der.read();
if (!path.isConstructed())
throw new DEREncodingException("malformed PkiPath");
}
else if (encoding.equalsIgnoreCase("PKCS7"))
{
// PKCS #7 encoding means that the certificates are contained in a
// SignedData PKCS #7 type.
//
// ContentInfo ::= SEQUENCE {
// contentType ::= ContentType,
// content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
//
// ContentType ::= OBJECT IDENTIFIER
//
// SignedData ::= SEQUENCE {
// version Version,
// digestAlgorithms DigestAlgorithmIdentifiers,
// contentInfo ContentInfo,
// certificates [0] IMPLICIT ExtendedCertificatesAndCertificates
// OPTIONAL,
// crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
// signerInfos SignerInfos }
//
// Version ::= INTEGER
//
DERValue value = der.read();
if (!value.isConstructed())
throw new DEREncodingException("malformed ContentInfo");
value = der.read();
if (!(value.getValue() instanceof OID) ||
((OID) value.getValue()).equals(PKCS7_SIGNED_DATA))
throw new DEREncodingException("not a SignedData");
value = der.read();
if (!value.isConstructed() || value.getTag() != 0)
throw new DEREncodingException("malformed content");
value = der.read();
if (value.getTag() != DER.INTEGER)
throw new DEREncodingException("malformed Version");
value = der.read();
if (!value.isConstructed() || value.getTag() != DER.SET)
throw new DEREncodingException("malformed DigestAlgorithmIdentifiers");
der.skip(value.getLength());
value = der.read();
if (!value.isConstructed())
throw new DEREncodingException("malformed ContentInfo");
der.skip(value.getLength());
path = der.read();
if (!path.isConstructed() || path.getTag() != 0)
throw new DEREncodingException("no certificates");
}
else
throw new CertificateEncodingException("unknown encoding: " + encoding);
LinkedList certs = new LinkedList();
int len = 0;
while (len < path.getLength())
{
DERValue cert = der.read();
try
{
certs.add(new X509Certificate(new ByteArrayInputStream(cert.getEncoded())));
}
catch (CertificateException ce)
{
throw new CertificateEncodingException(ce.getMessage());
}
len += cert.getEncodedLength();
der.skip(cert.getLength());
}
this.path = Collections.unmodifiableList(certs);
}
private byte[] encodePki()
throws CertificateEncodingException, IOException
{
synchronized (path)
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (Iterator i = path.iterator(); i.hasNext(); )
{
out.write(((Certificate) i.next()).getEncoded());
}
byte[] b = out.toByteArray();
DERValue val = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
b.length, b, null);
return val.getEncoded();
}
}
private byte[] encodePKCS()
throws CertificateEncodingException, IOException
{
synchronized (path)
{
ArrayList signedData = new ArrayList(5);
signedData.add(new DERValue(DER.INTEGER, BigInteger.ONE));
signedData.add(new DERValue(DER.CONSTRUCTED | DER.SET,
Collections.EMPTY_SET));
signedData.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
Collections.singletonList(
new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_DATA))));
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (Iterator i = path.iterator(); i.hasNext(); )
{
out.write(((Certificate) i.next()).getEncoded());
}
byte[] b = out.toByteArray();
signedData.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT,
b.length, b, null));
DERValue sdValue = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
signedData);
ArrayList contentInfo = new ArrayList(2);
contentInfo.add(new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_SIGNED_DATA));
contentInfo.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT, sdValue));
return new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
contentInfo).getEncoded();
}
}
}
@@ -0,0 +1,199 @@
/* X509CertSelectorImpl.java -- implementation of an X509CertSelector.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509;
import java.io.IOException;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.CertSelector;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
/**
* Sun's implementation of X509CertSelector sucks. This one tries to work
* better.
*/
public class X509CertSelectorImpl implements CertSelector
{
// Fields.
// -------------------------------------------------------------------------
private Set issuerNames;
private Set subjectNames;
// Constructor.
// -------------------------------------------------------------------------
public X509CertSelectorImpl()
{
issuerNames = new HashSet();
subjectNames = new HashSet();
}
// Instance methods.
// -------------------------------------------------------------------------
public void addIssuerName(byte[] issuerName) throws IOException
{
issuerNames.add(new X500DistinguishedName(issuerName));
}
public void addIssuerName(String issuerName)
{
issuerNames.add(new X500DistinguishedName(issuerName));
}
public void addIssuerName(Principal issuerName) throws IOException
{
if (issuerName instanceof X500DistinguishedName)
issuerNames.add(issuerName);
else if (issuerName instanceof X500Principal)
issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded()));
else
issuerNames.add(new X500DistinguishedName(issuerName.getName()));
}
public Collection getIssuerNames()
{
return Collections.unmodifiableSet(issuerNames);
}
public void addSubjectName(byte[] subjectName) throws IOException
{
subjectNames.add(new X500DistinguishedName(subjectName));
}
public void addSubjectName(String subjectName) throws IOException
{
subjectNames.add(new X500DistinguishedName(subjectName));
}
public void addSubjectName(Principal subjectName) throws IOException
{
if (subjectName instanceof X500DistinguishedName)
subjectNames.add(subjectName);
else if (subjectName instanceof X500Principal)
subjectNames.add(new X500DistinguishedName(((X500Principal) subjectName).getEncoded()));
else
subjectNames.add(new X500DistinguishedName(subjectName.getName()));
}
public Collection getSubjectNames()
{
return Collections.unmodifiableSet(subjectNames);
}
public Object clone()
{
X509CertSelectorImpl copy = new X509CertSelectorImpl();
copy.issuerNames.addAll(issuerNames);
copy.subjectNames.addAll(subjectNames);
return copy;
}
public boolean match(Certificate cert)
{
if (!(cert instanceof X509Certificate))
return false;
boolean matchIssuer = false;
boolean matchSubject = false;
try
{
Principal p = ((X509Certificate) cert).getIssuerDN();
X500DistinguishedName thisName = null;
if (p instanceof X500DistinguishedName)
thisName = (X500DistinguishedName) p;
else if (p instanceof X500Principal)
thisName = new X500DistinguishedName(((X500Principal) p).getEncoded());
else
thisName = new X500DistinguishedName(p.getName());
if (issuerNames.isEmpty())
matchIssuer = true;
else
{
for (Iterator it = issuerNames.iterator(); it.hasNext(); )
{
X500DistinguishedName name = (X500DistinguishedName) it.next();
if (thisName.equals(name))
{
matchIssuer = true;
break;
}
}
}
p = ((X509Certificate) cert).getSubjectDN();
thisName = null;
if (p instanceof X500DistinguishedName)
thisName = (X500DistinguishedName) p;
else if (p instanceof X500Principal)
thisName = new X500DistinguishedName(((X500Principal) p).getEncoded());
else
thisName = new X500DistinguishedName(p.getName());
if (subjectNames.isEmpty())
matchSubject = true;
else
{
for (Iterator it = subjectNames.iterator(); it.hasNext(); )
{
X500DistinguishedName name = (X500DistinguishedName) it.next();
if (thisName.equals(name))
{
matchSubject = true;
break;
}
}
}
}
catch (Exception x)
{
}
return matchIssuer && matchSubject;
}
}
@@ -1,5 +1,5 @@
/* X509Certificate.java -- X.509 certificate.
Copyright (C) 2003 Free Software Foundation, Inc.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -7,7 +7,7 @@ GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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
@@ -42,7 +42,9 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.math.BigInteger;
@@ -64,10 +66,12 @@ import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateParsingException;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -77,17 +81,14 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
import gnu.java.io.ASN1ParsingException;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.der.*;
import gnu.java.security.x509.ext.*;
/**
* An implementation of X.509 certificates.
@@ -95,65 +96,64 @@ import gnu.java.security.der.DERWriter;
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class X509Certificate extends java.security.cert.X509Certificate
implements Serializable
implements Serializable, GnuPKIExtension
{
// Constants and fields.
// ------------------------------------------------------------------------
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
private static final OID ID_DSA_WITH_SHA1 = new OID("1.2.840.10040.4.3");
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
private static final OID ID_RSA_WITH_MD2 = new OID("1.2.840.113549.1.1.2");
private static final OID ID_RSA_WITH_MD5 = new OID("1.2.840.113549.1.1.4");
private static final OID ID_RSA_WITH_SHA1 = new OID("1.2.840.113549.1.1.5");
private static final boolean DEBUG = false;
private static void debug(String msg)
{
if (DEBUG)
{
System.err.print(">> X509Certificate: ");
System.err.println(msg);
}
}
private static void debug(Throwable t)
{
if (DEBUG)
{
System.err.print(">> X509Certificate: ");
t.printStackTrace();
}
}
private static final OID ID_EXTENSION = new OID("2.5.29");
private static final OID ID_KEY_USAGE = ID_EXTENSION.getChild(15);
private static final OID ID_BASIC_CONSTRAINTS = ID_EXTENSION.getChild(19);
private static final OID ID_EXT_KEY_USAGE = ID_EXTENSION.getChild(37);
private static final int OTHER_NAME = 0;
private static final int RFC882_NAME = 1;
private static final int DNS_NAME = 2;
private static final int X400_ADDRESS = 3;
private static final int DIRECTORY_NAME = 4;
private static final int EDI_PARTY_NAME = 5;
private static final int URI = 6;
private static final int IP_ADDRESS = 7;
private static final int REGISTERED_ID = 8;
protected static final OID ID_DSA = new OID ("1.2.840.10040.4.1");
protected static final OID ID_DSA_WITH_SHA1 = new OID ("1.2.840.10040.4.3");
protected static final OID ID_RSA = new OID ("1.2.840.113549.1.1.1");
protected static final OID ID_RSA_WITH_MD2 = new OID ("1.2.840.113549.1.1.2");
protected static final OID ID_RSA_WITH_MD5 = new OID ("1.2.840.113549.1.1.4");
protected static final OID ID_RSA_WITH_SHA1 = new OID ("1.2.840.113549.1.1.5");
protected static final OID ID_ECDSA_WITH_SHA1 = new OID ("1.2.840.10045.4.1");
// This object SHOULD be serialized with an instance of
// java.security.cert.Certificate.CertificateRep, thus all fields are
// transient.
// The encoded certificate.
private transient byte[] encoded;
protected transient byte[] encoded;
// TBSCertificate part.
private transient byte[] tbsCertBytes;
private transient int version;
private transient BigInteger serialNo;
private transient OID algId;
private transient byte[] algVal;
private transient X500Principal issuer;
private transient Date notBefore;
private transient Date notAfter;
private transient X500Principal subject;
private transient PublicKey subjectKey;
private transient BitString issuerUniqueId;
private transient BitString subjectUniqueId;
private transient HashMap extensions;
private transient HashSet critOids;
private transient HashSet nonCritOids;
private transient BitString keyUsage;
private transient int basicConstraints = -1;
protected transient byte[] tbsCertBytes;
protected transient int version;
protected transient BigInteger serialNo;
protected transient OID algId;
protected transient byte[] algVal;
protected transient X500DistinguishedName issuer;
protected transient Date notBefore;
protected transient Date notAfter;
protected transient X500DistinguishedName subject;
protected transient PublicKey subjectKey;
protected transient BitString issuerUniqueId;
protected transient BitString subjectUniqueId;
protected transient Map extensions;
// Signature.
private transient OID sigAlgId;
private transient byte[] sigAlgVal;
private transient byte[] signature;
protected transient OID sigAlgId;
protected transient byte[] sigAlgVal;
protected transient byte[] signature;
// Constructors.
// ------------------------------------------------------------------------
@@ -173,22 +173,29 @@ public class X509Certificate extends java.security.cert.X509Certificate
{
super();
extensions = new HashMap();
critOids = new HashSet();
nonCritOids = new HashSet();
try
{
parse(encoded);
}
catch (IOException ioe)
{
debug(ioe);
throw ioe;
}
catch (Exception e)
{
throw new CertificateException(e.toString());
debug(e);
CertificateException ce = new CertificateException(e.getMessage());
ce.initCause (e);
throw ce;
}
}
protected X509Certificate()
{
extensions = new HashMap();
}
// X509Certificate methods.
// ------------------------------------------------------------------------
@@ -202,9 +209,13 @@ public class X509Certificate extends java.security.cert.X509Certificate
throws CertificateExpiredException, CertificateNotYetValidException
{
if (date.compareTo(notBefore) < 0)
throw new CertificateNotYetValidException();
{
throw new CertificateNotYetValidException();
}
if (date.compareTo(notAfter) > 0)
throw new CertificateExpiredException();
{
throw new CertificateExpiredException();
}
}
public int getVersion()
@@ -219,22 +230,22 @@ public class X509Certificate extends java.security.cert.X509Certificate
public Principal getIssuerDN()
{
return getIssuerX500Principal();
return issuer;
}
public X500Principal getIssuerX500Principal()
{
return issuer;
return new X500Principal(issuer.getDer());
}
public Principal getSubjectDN()
{
return getSubjectX500Principal();
return subject;
}
public X500Principal getSubjectX500Principal()
{
return subject;
return new X500Principal(subject.getDer());
}
public Date getNotBefore()
@@ -260,15 +271,22 @@ public class X509Certificate extends java.security.cert.X509Certificate
public String getSigAlgName()
{
if (sigAlgId.equals(ID_DSA_WITH_SHA1))
return "SHA1withDSA";
if (sigAlgId.equals(ID_RSA_WITH_MD2 ))
return "MD2withRSA";
if (sigAlgId.equals(ID_RSA_WITH_MD5 ))
return "MD5withRSA";
if (sigAlgId.equals(ID_RSA_WITH_SHA1 ))
return "SHA1withRSA";
{
return "SHA1withDSA";
}
if (sigAlgId.equals(ID_RSA_WITH_MD2))
{
return "MD2withRSA";
}
if (sigAlgId.equals(ID_RSA_WITH_MD5))
{
return "MD5withRSA";
}
if (sigAlgId.equals(ID_RSA_WITH_SHA1))
{
return "SHA1withRSA";
}
return "unknown";
// return sigAlgId.getShortName();
}
public String getSigAlgOID()
@@ -284,75 +302,81 @@ public class X509Certificate extends java.security.cert.X509Certificate
public boolean[] getIssuerUniqueID()
{
if (issuerUniqueId != null)
return issuerUniqueId.toBooleanArray();
{
return issuerUniqueId.toBooleanArray();
}
return null;
}
public boolean[] getSubjectUniqueID()
{
if (subjectUniqueId != null)
return subjectUniqueId.toBooleanArray();
{
return subjectUniqueId.toBooleanArray();
}
return null;
}
public boolean[] getKeyUsage()
{
if (keyUsage != null)
return keyUsage.toBooleanArray();
Extension e = getExtension(KeyUsage.ID);
if (e != null)
{
KeyUsage ku = (KeyUsage) e.getValue();
boolean[] result = new boolean[9];
boolean[] b = ku.getKeyUsage().toBooleanArray();
System.arraycopy(b, 0, result, 0, b.length);
return result;
}
return null;
}
public List getExtendedKeyUsage() throws CertificateParsingException
{
byte[] ext = (byte[]) extensions.get("2.5.29.37");
if (ext == null)
return null;
LinkedList usages = new LinkedList();
try
Extension e = getExtension(ExtendedKeyUsage.ID);
if (e != null)
{
DERReader der = new DERReader(new ByteArrayInputStream(ext));
DERValue seq = der.read();
if (!seq.isConstructed())
throw new CertificateParsingException();
int len = 0;
while (len < seq.getLength())
List a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
List b = new ArrayList(a.size());
for (Iterator it = a.iterator(); it.hasNext(); )
{
DERValue oid = der.read();
if (!(oid.getValue() instanceof OID))
throw new CertificateParsingException();
usages.add(oid.getValue().toString());
len += DERWriter.definiteEncodingSize(oid.getLength())
+ oid.getLength() + 1;
b.add(it.next().toString());
}
return Collections.unmodifiableList(b);
}
catch (IOException ioe)
{
throw new CertificateParsingException();
}
return usages;
return null;
}
public int getBasicConstraints()
{
return basicConstraints;
Extension e = getExtension(BasicConstraints.ID);
if (e != null)
{
return ((BasicConstraints) e.getValue()).getPathLengthConstraint();
}
return -1;
}
public Collection getSubjectAlternativeNames()
throws CertificateParsingException
{
byte[] ext = getExtensionValue("2.5.29.17");
if (ext == null)
return null;
return getAltNames(ext);
Extension e = getExtension(SubjectAlternativeNames.ID);
if (e != null)
{
return ((SubjectAlternativeNames) e.getValue()).getNames();
}
return null;
}
public Collection getIssuerAlternativeNames()
throws CertificateParsingException
{
byte[] ext = getExtensionValue("2.5.29.18");
if (ext == null)
return null;
return getAltNames(ext);
Extension e = getExtension(IssuerAlternativeNames.ID);
if (e != null)
{
return ((IssuerAlternativeNames) e.getValue()).getNames();
}
return null;
}
// X509Extension methods.
@@ -360,12 +384,10 @@ public class X509Certificate extends java.security.cert.X509Certificate
public boolean hasUnsupportedCriticalExtension()
{
for (Iterator it = critOids.iterator(); it.hasNext(); )
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
String oid = (String) it.next();
if (!oid.equals("2.5.29.15") && !oid.equals("2.5.29.17") &&
!oid.equals("2.5.29.18") && !oid.equals("2.5.29.19") &&
!oid.equals("2.5.29.37"))
Extension e = (Extension) it.next();
if (e.isCritical() && !e.isSupported())
return true;
}
return false;
@@ -373,24 +395,53 @@ public class X509Certificate extends java.security.cert.X509Certificate
public Set getCriticalExtensionOIDs()
{
return Collections.unmodifiableSet(critOids);
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public Set getNonCriticalExtensionOIDs()
{
return Collections.unmodifiableSet(nonCritOids);
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (!e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public byte[] getExtensionValue(String oid)
{
byte[] ext = (byte[]) extensions.get(oid);
if (ext != null)
return (byte[]) ext.clone();
Extension e = getExtension(new OID(oid));
if (e != null)
{
return e.getValue().getEncoded();
}
return null;
}
// GnuPKIExtension method.
// -------------------------------------------------------------------------
public Extension getExtension(OID oid)
{
return (Extension) extensions.get(oid);
}
public Collection getExtensions()
{
return extensions.values();
}
// Certificate methods.
// ------------------------------------------------------------------------
// -------------------------------------------------------------------------
public byte[] getEncoded() throws CertificateEncodingException
{
@@ -398,7 +449,7 @@ public class X509Certificate extends java.security.cert.X509Certificate
}
public void verify(PublicKey key)
throws CertificateException, NoSuchAlgorithmException,
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException
{
Signature sig = Signature.getInstance(sigAlgId.toString());
@@ -415,8 +466,50 @@ public class X509Certificate extends java.security.cert.X509Certificate
public String toString()
{
// XXX say more than this.
return gnu.java.security.x509.X509Certificate.class.getName();
StringWriter str = new StringWriter();
PrintWriter out = new PrintWriter(str);
out.println(X509Certificate.class.getName() + " {");
out.println(" TBSCertificate {");
out.println(" version = " + version + ";");
out.println(" serialNo = " + serialNo + ";");
out.println(" signature = {");
out.println(" algorithm = " + getSigAlgName() + ";");
out.print(" parameters =");
if (sigAlgVal != null)
{
out.println();
out.print(Util.hexDump(sigAlgVal, " "));
}
else
{
out.println(" null;");
}
out.println(" }");
out.println(" issuer = " + issuer.getName() + ";");
out.println(" validity = {");
out.println(" notBefore = " + notBefore + ";");
out.println(" notAfter = " + notAfter + ";");
out.println(" }");
out.println(" subject = " + subject.getName() + ";");
out.println(" subjectPublicKeyInfo = {");
out.println(" algorithm = " + subjectKey.getAlgorithm());
out.println(" key =");
out.print(Util.hexDump(subjectKey.getEncoded(), " "));
out.println(" };");
out.println(" issuerUniqueId = " + issuerUniqueId + ";");
out.println(" subjectUniqueId = " + subjectUniqueId + ";");
out.println(" extensions = {");
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
out.println(" " + it.next());
}
out.println(" }");
out.println(" }");
out.println(" signatureAlgorithm = " + getSigAlgName() + ";");
out.println(" signatureValue =");
out.print(Util.hexDump(signature, " "));
out.println("}");
return str.toString();
}
public PublicKey getPublicKey()
@@ -424,11 +517,25 @@ public class X509Certificate extends java.security.cert.X509Certificate
return subjectKey;
}
protected Object writeReplace() throws ObjectStreamException
public boolean equals(Object other)
{
return super.writeReplace();
if (!(other instanceof X509Certificate))
return false;
try
{
if (other instanceof X509Certificate)
return Arrays.equals(encoded, ((X509Certificate) other).encoded);
byte[] enc = ((X509Certificate) other).getEncoded();
if (enc == null)
return false;
return Arrays.equals(encoded, enc);
}
catch (CertificateEncodingException cee)
{
return false;
}
}
// Own methods.
// ------------------------------------------------------------------------
@@ -438,68 +545,13 @@ public class X509Certificate extends java.security.cert.X509Certificate
private void doVerify(Signature sig, PublicKey key)
throws CertificateException, InvalidKeyException, SignatureException
{
debug("verifying sig=" + sig + " key=" + key);
sig.initVerify(key);
sig.update(tbsCertBytes);
if (!sig.verify(signature))
throw new CertificateException("signature not validated");
}
/**
* Read a GeneralNames structure.
*/
private List getAltNames(byte[] encoded)
throws CertificateParsingException
{
LinkedList names = new LinkedList();
try
{
ByteArrayInputStream in = new ByteArrayInputStream(encoded);
DERReader der = new DERReader(in);
DERValue seq = der.read();
if (!seq.isConstructed())
throw new CertificateParsingException();
int len = 0;
while (len < seq.getLength())
{
DERValue name = der.read();
ArrayList pair = new ArrayList(2);
Object nameVal = null;
switch (name.getTag())
{
case RFC882_NAME:
case DNS_NAME:
case URI:
nameVal = new String((byte[]) name.getValue());
break;
case IP_ADDRESS:
nameVal = InetAddress.getByAddress(
(byte[]) name.getValue()).getHostAddress();
break;
case REGISTERED_ID:
nameVal = new OID((byte[]) name.getValue());
break;
case OTHER_NAME:
case X400_ADDRESS:
case DIRECTORY_NAME:
case EDI_PARTY_NAME:
nameVal = name.getEncoded();
break;
default:
throw new CertificateParsingException();
}
pair.add(new Integer(name.getTag()));
pair.add(nameVal);
names.add(pair);
if (name.isConstructed())
in.skip(name.getLength());
len += name.getEncodedLength();
}
throw new CertificateException("signature not validated");
}
catch (IOException ioe)
{
throw new CertificateParsingException(ioe.toString());
}
return Collections.unmodifiableList(names);
}
/**
@@ -513,20 +565,27 @@ public class X509Certificate extends java.security.cert.X509Certificate
// Certificate ::= SEQUENCE {
DERValue cert = der.read();
debug("start Certificate len == " + cert.getLength());
this.encoded = cert.getEncoded();
if (!cert.isConstructed())
throw new ASN1ParsingException("malformed Certificate");
{
throw new IOException("malformed Certificate");
}
// TBSCertificate ::= SEQUENCE {
DERValue tbsCert = der.read();
if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE)
throw new ASN1ParsingException("malformed TBSCertificate");
{
throw new IOException("malformed TBSCertificate");
}
tbsCertBytes = tbsCert.getEncoded();
debug("start TBSCertificate len == " + tbsCert.getLength());
// Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }
DERValue val = der.read();
if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0)
{
// Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }
version = ((BigInteger) der.read().getValue()).intValue() + 1;
val = der.read();
}
@@ -534,163 +593,154 @@ public class X509Certificate extends java.security.cert.X509Certificate
{
version = 1;
}
debug("read version == " + version);
// SerialNumber ::= INTEGER
serialNo = (BigInteger) val.getValue();
debug("read serial number == " + serialNo);
// AlgorithmIdentifier ::= SEQUENCE {
val = der.read();
if (!val.isConstructed())
throw new ASN1ParsingException("malformed AlgorithmIdentifier");
{
throw new IOException("malformed AlgorithmIdentifier");
}
int certAlgLen = val.getLength();
debug("start AlgorithmIdentifier len == " + certAlgLen);
val = der.read();
// algorithm OBJECT IDENTIFIER,
algId = (OID) val.getValue();
debug("read algorithm ID == " + algId);
// parameters ANY DEFINED BY algorithm OPTIONAL }
if (certAlgLen > val.getEncodedLength())
{
val = der.read();
if (val == null)
algVal = null;
{
algVal = null;
}
else
algVal = val.getEncoded();
{
algVal = val.getEncoded();
}
if (val.isConstructed())
encoded.skip(val.getLength());
{
encoded.skip(val.getLength());
}
debug("read algorithm parameters == " + algVal);
}
issuer = new X500Principal(encoded);
// issuer Name,
val = der.read();
issuer = new X500DistinguishedName(val.getEncoded());
der.skip(val.getLength());
debug("read issuer == " + issuer);
// Validity ::= SEQUENCE {
// notBefore Time,
// notAfter Time }
if (!der.read().isConstructed())
throw new ASN1ParsingException("malformed Validity");
{
throw new IOException("malformed Validity");
}
notBefore = (Date) der.read().getValue();
notAfter = (Date) der.read().getValue();
debug("read notBefore == " + notBefore);
debug("read notAfter == " + notAfter);
subject = new X500Principal(encoded);
// subject Name,
val = der.read();
subject = new X500DistinguishedName(val.getEncoded());
der.skip(val.getLength());
debug("read subject == " + subject);
if (!der.read().isConstructed())
throw new ASN1ParsingException("malformed SubjectPublicKeyInfo");
val = der.read();
if (!val.isConstructed())
throw new ASN1ParsingException("malformed AlgorithmIdentifier");
int keyAlgLen = val.getLength();
val = der.read();
OID keyID = (OID) val.getValue();
byte[] keyParams = null;
if (keyAlgLen > val.getEncodedLength())
// SubjectPublicKeyInfo ::= SEQUENCE {
// algorithm AlgorithmIdentifier,
// subjectPublicKey BIT STRING }
DERValue spki = der.read();
if (!spki.isConstructed())
{
val = der.read();
keyParams = val.getEncoded();
if (algVal == null)
algVal = keyParams;
if (val.isConstructed())
encoded.skip(val.getLength());
throw new IOException("malformed SubjectPublicKeyInfo");
}
val = der.read();
byte[] keyVal = ((BitString) val.getValue()).toByteArray();
if (keyID.equals(ID_DSA))
{
AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
params.init(keyParams, "ASN.1");
KeyFactory keyFac = KeyFactory.getInstance("DSA");
DSAParameterSpec spec = (DSAParameterSpec)
params.getParameterSpec(DSAParameterSpec.class);
subjectKey = keyFac.generatePublic(new DSAPublicKeySpec(
(BigInteger) new DERReader(keyVal).read().getValue(),
spec.getP(), spec.getQ(), spec.getG()));
}
else if (keyID.equals(ID_RSA))
{
KeyFactory keyFac = KeyFactory.getInstance("RSA");
DERReader rsaKey = new DERReader(keyVal);
if (!rsaKey.read().isConstructed())
throw new ASN1ParsingException("malformed RSAPublicKey");
subjectKey = keyFac.generatePublic(new RSAPublicKeySpec(
(BigInteger) rsaKey.read().getValue(),
(BigInteger) rsaKey.read().getValue()));
}
else
throw new ASN1ParsingException("unknown key algorithm " + keyID);
KeyFactory spkFac = KeyFactory.getInstance("X.509");
subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
der.skip(spki.getLength());
debug("read subjectPublicKey == " + subjectKey);
if (version > 1)
val = der.read();
{
val = der.read();
}
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1)
{
byte[] b = (byte[]) val.getValue();
issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
debug("read issuerUniqueId == " + issuerUniqueId);
val = der.read();
}
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2)
{
byte[] b = (byte[]) val.getValue();
subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
debug("read subjectUniqueId == " + subjectUniqueId);
val = der.read();
}
if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3)
{
val = der.read();
debug("start Extensions len == " + val.getLength());
int len = 0;
while (len < val.getLength())
{
DERValue ext = der.read();
OID extId = (OID) der.read().getValue();
DERValue val2 = der.read();
Boolean crit = Boolean.valueOf(false);
if (val2.getValue() instanceof Boolean)
{
crit = (Boolean) val2.getValue();
val2 = der.read();
}
byte[] extVal = (byte[]) val2.getValue();
extensions.put(extId.toString(), extVal);
if (crit.booleanValue())
critOids.add(extId.toString());
else
nonCritOids.add(extId.toString());
if (extId.equals(ID_KEY_USAGE))
{
keyUsage = (BitString) DERReader.read(extVal).getValue();
}
else if (extId.equals(ID_BASIC_CONSTRAINTS))
{
DERReader bc = new DERReader(extVal);
DERValue constraints = bc.read();
if (!constraints.isConstructed())
throw new ASN1ParsingException("malformed BasicConstraints");
if (constraints.getLength() > 0)
{
boolean ca = false;
int constr = -1;
val2 = bc.read();
if (val2.getValue() instanceof Boolean)
{
ca = ((Boolean) val2.getValue()).booleanValue();
if (constraints.getLength() > val2.getEncodedLength())
val2 = bc.read();
}
if (val2.getValue() instanceof BigInteger)
constr = ((BigInteger) val2.getValue()).intValue();
basicConstraints = constr;
}
}
debug("start extension len == " + ext.getLength());
Extension e = new Extension(ext.getEncoded());
extensions.put(e.getOid(), e);
der.skip(ext.getLength());
len += ext.getEncodedLength();
debug("count == " + len);
}
}
val = der.read();
if (!val.isConstructed())
throw new ASN1ParsingException("malformed AlgorithmIdentifier");
{
throw new IOException("malformed AlgorithmIdentifier");
}
int sigAlgLen = val.getLength();
debug("start AlgorithmIdentifier len == " + sigAlgLen);
val = der.read();
sigAlgId = (OID) val.getValue();
debug("read algorithm id == " + sigAlgId);
if (sigAlgLen > val.getEncodedLength())
{
val = der.read();
if (val.getValue() == null)
sigAlgVal = keyParams;
{
if (subjectKey instanceof DSAPublicKey)
{
AlgorithmParameters params =
AlgorithmParameters.getInstance("DSA");
DSAParams dsap = ((DSAPublicKey) subjectKey).getParams();
DSAParameterSpec spec =
new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG());
params.init(spec);
sigAlgVal = params.getEncoded();
}
}
else
sigAlgVal = (byte[]) val.getEncoded();
{
sigAlgVal = (byte[]) val.getEncoded();
}
if (val.isConstructed())
encoded.skip(val.getLength());
{
encoded.skip(val.getLength());
}
debug("read parameters == " + sigAlgVal);
}
signature = ((BitString) der.read().getValue()).toByteArray();
debug("read signature ==\n" + Util.hexDump(signature, ">>>> "));
}
}
@@ -0,0 +1,134 @@
/* AuthorityKeyIdentifier.java -- Authority key identifier extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.x509.Util;
public class AuthorityKeyIdentifier extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.35");
private final byte[] keyIdentifier;
private final GeneralNames authorityCertIssuer;
private final BigInteger authorityCertSerialNumber;
// Contstructor.
// -------------------------------------------------------------------------
public AuthorityKeyIdentifier(final byte[] encoded) throws IOException
{
super(encoded);
DERReader der = new DERReader(encoded);
// AuthorityKeyIdentifier ::= SEQUENCE {
DERValue val = der.read();
if (!val.isConstructed())
throw new IOException("malformed AuthorityKeyIdentifier");
if (val.getLength() > 0)
val = der.read();
// keyIdentifier [0] KeyIdentifier OPTIONAL,
// KeyIdentifier ::= OCTET STRING
if (val.getTagClass() == DER.APPLICATION && val.getTag() == 0)
{
keyIdentifier = (byte[]) val.getValue();
val = der.read();
}
else
keyIdentifier = null;
// authorityCertIssuer [1] GeneralNames OPTIONAL,
if (val.getTagClass() == DER.APPLICATION && val.getTag() == 1)
{
byte[] b = val.getEncoded();
b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
authorityCertIssuer = new GeneralNames(b);
der.skip(val.getLength());
val = der.read();
}
else
authorityCertIssuer = null;
// authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
if (val.getTagClass() == DER.APPLICATION && val.getTag() == 2)
{
authorityCertSerialNumber = new BigInteger((byte[]) val.getValue());
}
else
authorityCertSerialNumber = null;
}
// Instance methods.
// -------------------------------------------------------------------------
public byte[] getKeyIdentifier()
{
return keyIdentifier != null ? (byte[]) keyIdentifier.clone() : null;
}
public GeneralNames getAuthorityCertIssuer()
{
return authorityCertIssuer;
}
public BigInteger getAuthorityCertSerialNumber()
{
return authorityCertSerialNumber;
}
public String toString()
{
return AuthorityKeyIdentifier.class.getName() + " [ keyId=" +
(keyIdentifier != null ? Util.toHexString (keyIdentifier, ':') : "nil") +
" authorityCertIssuer=" + authorityCertIssuer +
" authorityCertSerialNumbe=" + authorityCertSerialNumber + " ]";
}
}
@@ -0,0 +1,129 @@
/* BasicConstraints.java -- the basic constraints extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class BasicConstraints extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.19");
private final boolean ca;
private final int pathLenConstraint;
// Constructor.
// -------------------------------------------------------------------------
public BasicConstraints(final byte[] encoded) throws IOException
{
super(encoded);
DERReader der = new DERReader(encoded);
DERValue bc = der.read();
if (!bc.isConstructed())
throw new IOException("malformed BasicConstraints");
DERValue val = bc;
if (bc.getLength() > 0)
val = der.read();
if (val.getTag() == DER.BOOLEAN)
{
ca = ((Boolean) val.getValue()).booleanValue();
if (val.getEncodedLength() < bc.getLength())
val = der.read();
}
else
ca = false;
if (val.getTag() == DER.INTEGER)
{
pathLenConstraint = ((BigInteger) val.getValue()).intValue();
}
else
pathLenConstraint = -1;
}
public BasicConstraints (final boolean ca, final int pathLenConstraint)
{
this.ca = ca;
this.pathLenConstraint = pathLenConstraint;
}
// Instance methods.
// -------------------------------------------------------------------------
public boolean isCA()
{
return ca;
}
public int getPathLengthConstraint()
{
return pathLenConstraint;
}
public byte[] getEncoded()
{
if (encoded == null)
{
List bc = new ArrayList (2);
bc.add (new DERValue (DER.BOOLEAN, new Boolean (ca)));
if (pathLenConstraint >= 0)
bc.add (new DERValue (DER.INTEGER,
BigInteger.valueOf ((long) pathLenConstraint)));
encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, bc).getEncoded();
}
return (byte[]) encoded.clone();
}
public String toString()
{
return BasicConstraints.class.getName() + " [ isCA=" + ca +
" pathLen=" + pathLenConstraint + " ]";
}
}
@@ -0,0 +1,97 @@
/* CRLNumber.java -- CRL number extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.math.BigInteger;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class CRLNumber extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.20");
private final BigInteger number;
// Constructor.
// -------------------------------------------------------------------------
public CRLNumber(final byte[] encoded) throws IOException
{
super(encoded);
DERValue val = DERReader.read(encoded);
if (val.getTag() != DER.INTEGER)
throw new IOException("malformed CRLNumber");
number = (BigInteger) val.getValue();
}
public CRLNumber (final BigInteger number)
{
this.number = number;
}
// Instance method.
// -------------------------------------------------------------------------
public BigInteger getNumber()
{
return number;
}
public byte[] getEncoded()
{
if (encoded == null)
{
encoded = new DERValue (DER.INTEGER, number).getEncoded();
}
return (byte[]) encoded.clone();
}
public String toString()
{
return CRLNumber.class.getName() + " [ " + number + " ]";
}
}
@@ -0,0 +1,191 @@
/* CertificatePolicies.java -- certificate policy extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.PolicyQualifierInfo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class CertificatePolicies extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.32");
private final List policies;
private final Map policyQualifierInfos;
// Constructor.
// -------------------------------------------------------------------------
public CertificatePolicies(final byte[] encoded) throws IOException
{
super(encoded);
DERReader der = new DERReader(encoded);
DERValue pol = der.read();
if (!pol.isConstructed())
throw new IOException("malformed CertificatePolicies");
int len = 0;
LinkedList policyList = new LinkedList();
HashMap qualifierMap = new HashMap();
while (len < pol.getLength())
{
DERValue policyInfo = der.read();
if (!policyInfo.isConstructed())
throw new IOException("malformed PolicyInformation");
DERValue val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed CertPolicyId");
OID policyId = (OID) val.getValue();
policyList.add(policyId);
if (val.getEncodedLength() < policyInfo.getLength())
{
DERValue qual = der.read();
int len2 = 0;
LinkedList quals = new LinkedList();
while (len2 < qual.getLength())
{
val = der.read();
quals.add(new PolicyQualifierInfo(val.getEncoded()));
der.skip(val.getLength());
len2 += val.getEncodedLength();
}
qualifierMap.put(policyId, quals);
}
len += policyInfo.getEncodedLength();
}
policies = Collections.unmodifiableList(policyList);
policyQualifierInfos = Collections.unmodifiableMap(qualifierMap);
}
public CertificatePolicies (final List policies,
final Map policyQualifierInfos)
{
for (Iterator it = policies.iterator(); it.hasNext(); )
if (!(it.next() instanceof OID))
throw new IllegalArgumentException ("policies must be OIDs");
for (Iterator it = policyQualifierInfos.entrySet().iterator(); it.hasNext();)
{
Map.Entry e = (Map.Entry) it.next();
if (!(e.getKey() instanceof OID) || !policies.contains (e.getKey()))
throw new IllegalArgumentException
("policyQualifierInfos keys must be OIDs");
if (!(e.getValue() instanceof List))
throw new IllegalArgumentException
("policyQualifierInfos values must be Lists of PolicyQualifierInfos");
for (Iterator it2 = ((List) e.getValue()).iterator(); it.hasNext(); )
if (!(it2.next() instanceof PolicyQualifierInfo))
throw new IllegalArgumentException
("policyQualifierInfos values must be Lists of PolicyQualifierInfos");
}
this.policies = Collections.unmodifiableList (new ArrayList (policies));
this.policyQualifierInfos = Collections.unmodifiableMap
(new HashMap (policyQualifierInfos));
}
// Instance methods.
// -------------------------------------------------------------------------
public List getPolicies()
{
return policies;
}
public List getPolicyQualifierInfos(OID oid)
{
return (List) policyQualifierInfos.get(oid);
}
public byte[] getEncoded()
{
if (encoded == null)
{
List pol = new ArrayList (policies.size());
for (Iterator it = policies.iterator(); it.hasNext(); )
{
OID policy = (OID) it.next();
List qualifiers = getPolicyQualifierInfos (policy);
List l = new ArrayList (qualifiers == null ? 1 : 2);
l.add (new DERValue (DER.OBJECT_IDENTIFIER, policy));
if (qualifiers != null)
{
List ll = new ArrayList (qualifiers.size());
for (Iterator it2 = qualifiers.iterator(); it.hasNext(); )
{
PolicyQualifierInfo info = (PolicyQualifierInfo) it2.next();
try
{
ll.add (DERReader.read (info.getEncoded()));
}
catch (IOException ioe)
{
}
}
l.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ll));
}
pol.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, l));
}
encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded();
}
return (byte[]) encoded.clone();
}
public String toString()
{
return CertificatePolicies.class.getName() + " [ policies=" + policies +
" policyQualifierInfos=" + policyQualifierInfos + " ]";
}
}
@@ -0,0 +1,95 @@
/* ExtendedKeyUsage.java -- the extended key usage extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class ExtendedKeyUsage extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.37");
private final List purposeIds;
// Constructor.
// -------------------------------------------------------------------------
public ExtendedKeyUsage(final byte[] encoded) throws IOException
{
super(encoded);
DERReader der = new DERReader(encoded);
DERValue usageList = der.read();
if (!usageList.isConstructed())
throw new IOException("malformed ExtKeyUsageSyntax");
int len = 0;
purposeIds = new LinkedList();
while (len < usageList.getLength())
{
DERValue val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed KeyPurposeId");
purposeIds.add(val.getValue());
len += val.getEncodedLength();
}
}
// Instance method.
// -------------------------------------------------------------------------
public List getPurposeIds()
{
return Collections.unmodifiableList(purposeIds);
}
public String toString()
{
return ExtendedKeyUsage.class.getName() + " [ " + purposeIds + " ]";
}
}
@@ -0,0 +1,289 @@
/* Extension.java -- an X.509 certificate or CRL extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.x509.Util;
public class Extension
{
// Fields.
// -------------------------------------------------------------------------
private static final boolean DEBUG = false;
private static void debug(String msg)
{
System.err.print(">> Extension: ");
System.err.println(msg);
}
/**
* This extension's object identifier.
*/
protected final OID oid;
/**
* The criticality flag.
*/
protected final boolean critical;
/**
* Whether or not this extension is locally supported.
*/
protected boolean isSupported;
/**
* The extension value.
*/
protected final Value value;
/**
* The DER encoded form.
*/
protected byte[] encoded;
// Constructors.
// -------------------------------------------------------------------------
public Extension(byte[] encoded) throws IOException
{
this.encoded = (byte[]) encoded.clone();
DERReader der = new DERReader(encoded);
// Extension ::= SEQUENCE {
DERValue val = der.read();
if (DEBUG) debug("read val tag == " + val.getTag() + " len == " + val.getLength());
if (!val.isConstructed())
throw new IOException("malformed Extension");
// extnID OBJECT IDENTIFIER,
val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("expecting OBJECT IDENTIFIER");
oid = (OID) val.getValue();
if (DEBUG) debug("read oid == " + oid);
// critical BOOLEAN DEFAULT FALSE,
val = der.read();
if (val.getTag() == DER.BOOLEAN)
{
critical = ((Boolean) val.getValue()).booleanValue();
val = der.read();
}
else
critical = false;
if (DEBUG) debug("is critical == " + critical);
// extnValue OCTET STRING }
if (val.getTag() != DER.OCTET_STRING)
throw new IOException("expecting OCTET STRING");
byte[] encval = (byte[]) val.getValue();
isSupported = true;
if (oid.equals(AuthorityKeyIdentifier.ID))
{
value = new AuthorityKeyIdentifier(encval);
}
else if (oid.equals(SubjectKeyIdentifier.ID))
{
value = new SubjectKeyIdentifier(encval);
}
else if (oid.equals(KeyUsage.ID))
{
value = new KeyUsage(encval);
}
else if (oid.equals(PrivateKeyUsagePeriod.ID))
{
value = new PrivateKeyUsagePeriod(encval);
}
else if (oid.equals(CertificatePolicies.ID))
{
value = new CertificatePolicies(encval);
}
else if (oid.equals (PolicyConstraint.ID))
{
value = new PolicyConstraint (encval);
}
else if (oid.equals(PolicyMappings.ID))
{
value = new PolicyMappings(encval);
}
else if (oid.equals(SubjectAlternativeNames.ID))
{
value = new SubjectAlternativeNames(encval);
}
else if (oid.equals(IssuerAlternativeNames.ID))
{
value = new IssuerAlternativeNames(encval);
}
else if (oid.equals(BasicConstraints.ID))
{
value = new BasicConstraints(encval);
}
else if (oid.equals(ExtendedKeyUsage.ID))
{
value = new ExtendedKeyUsage(encval);
}
else if (oid.equals(CRLNumber.ID))
{
value = new CRLNumber(encval);
}
else if (oid.equals(ReasonCode.ID))
{
value = new ReasonCode(encval);
}
else
{
value = new Value(encval);
isSupported = false;
}
if (DEBUG) debug("read value == " + value);
}
public Extension (final OID oid, final Value value, final boolean critical)
{
this.oid = oid;
this.value = value;
this.critical = critical;
isSupported = true;
}
// Instance methods.
// -------------------------------------------------------------------------
public OID getOid()
{
return oid;
}
public boolean isCritical()
{
return critical;
}
public boolean isSupported()
{
return isSupported;
}
public Value getValue()
{
return value;
}
public byte[] getEncoded()
{
if (encoded == null)
encode();
return (byte[]) encoded.clone();
}
public String toString()
{
return Extension.class.getName() + " [ id=" + oid + " critical=" +
critical + " value=" + value + " ]";
}
public DERValue getDerValue()
{
List ext = new ArrayList (3);
ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid));
ext.add (new DERValue (DER.BOOLEAN, new Boolean (critical)));
ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded()));
return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext);
}
// Own methods.
// -------------------------------------------------------------------------
private void encode()
{
encoded = getDerValue().getEncoded();
}
// Inner class.
// -------------------------------------------------------------------------
public static class Value
{
// Fields.
// -----------------------------------------------------------------------
protected byte[] encoded;
// Constructor.
// -----------------------------------------------------------------------
public Value(byte[] encoded)
{
this.encoded = (byte[]) encoded.clone();
}
protected Value() { }
// Instance methods.
// -----------------------------------------------------------------------
public byte[] getEncoded()
{
return (byte[]) encoded;
}
public boolean equals(Object o)
{
if (!(o instanceof Value))
return false;
return Arrays.equals(encoded, ((Value) o).encoded);
}
public String toString()
{
return Util.toHexString(encoded, ':');
}
}
}
@@ -0,0 +1,157 @@
/* GeneralNames.java -- the GeneralNames object.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import gnu.java.security.OID;
import gnu.java.security.x509.X500DistinguishedName;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class GeneralNames
{
// Instance methods.
// -------------------------------------------------------------------------
public static final int OTHER_NAME = 0;
public static final int RFC822_NAME = 1;
public static final int DNS_NAME = 2;
public static final int X400_ADDRESS = 3;
public static final int DIRECTORY_NAME = 4;
public static final int EDI_PARTY_NAME = 5;
public static final int URI = 6;
public static final int IP_ADDRESS = 7;
public static final int REGISTERED_ID = 8;
private List names;
// Constructor.
// -------------------------------------------------------------------------
public GeneralNames(final byte[] encoded) throws IOException
{
names = new LinkedList();
DERReader der = new DERReader(encoded);
DERValue nameList = der.read();
if (!nameList.isConstructed())
throw new IOException("malformed GeneralNames");
int len = 0;
while (len < nameList.getLength())
{
DERValue name = der.read();
List namePair = new ArrayList(2);
if (name.getTagClass() != DER.APPLICATION)
throw new IOException("malformed GeneralName");
namePair.add(new Integer(name.getTag()));
DERValue val = null;
switch (name.getTag())
{
case RFC822_NAME:
case DNS_NAME:
case X400_ADDRESS:
case URI:
namePair.add(new String((byte[]) name.getValue()));
break;
case OTHER_NAME:
case EDI_PARTY_NAME:
namePair.add(name.getValue());
break;
case DIRECTORY_NAME:
byte[] b = name.getEncoded();
b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
namePair.add(new X500DistinguishedName(b).toString());
break;
case IP_ADDRESS:
namePair.add(InetAddress.getByAddress((byte[]) name.getValue())
.getHostAddress());
break;
case REGISTERED_ID:
byte[] bb = name.getEncoded();
bb[0] = (byte) DER.OBJECT_IDENTIFIER;
namePair.add(new OID(bb).toString());
break;
default:
throw new IOException("unknown tag " + name.getTag());
}
names.add(namePair);
len += name.getEncodedLength();
}
}
// Instance methods.
// -------------------------------------------------------------------------
public List getNames()
{
List l = new ArrayList(names.size());
for (Iterator it = names.iterator(); it.hasNext(); )
{
List ll = (List) it.next();
List pair = new ArrayList(2);
pair.add(ll.get(0));
if (ll.get(1) instanceof byte[])
pair.add(((byte[]) ll.get(1)).clone());
else
pair.add(ll.get(1));
l.add(Collections.unmodifiableList(pair));
}
return Collections.unmodifiableList(l);
}
public String toString()
{
return GeneralNames.class.getName() + " [ " + names + " ]";
}
}
@@ -0,0 +1,76 @@
/* IssuerAlternatuveNames.java -- issuer alternative names extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.util.List;
import gnu.java.security.OID;
public class IssuerAlternativeNames extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.18");
private final GeneralNames names;
// Constructor.
// -------------------------------------------------------------------------
public IssuerAlternativeNames(final byte[] encoded) throws IOException
{
super(encoded);
names = new GeneralNames(encoded);
}
// Instance method.
// -------------------------------------------------------------------------
public List getNames()
{
return names.getNames();
}
public String toString()
{
return IssuerAlternativeNames.class.getName() + " [ " + names + " ]";
}
}
@@ -0,0 +1,92 @@
/* KeyUsage.java -- the key usage extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class KeyUsage extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.15");
public static final int DIGITAL_SIGNATURE = 0;
public static final int NON_REPUDIATION = 1;
public static final int KEY_ENCIPHERMENT = 2;
public static final int DATA_ENCIPHERMENT = 3;
public static final int KEY_AGREEMENT = 4;
public static final int KEY_CERT_SIGN = 5;
public static final int CRL_SIGN = 6;
public static final int ENCIPHER_ONLY = 7;
public static final int DECIPHER_ONLY = 8;
private final BitString keyUsage;
// Constructor.
// -------------------------------------------------------------------------
public KeyUsage(final byte[] encoded) throws IOException
{
super(encoded);
DERValue val = DERReader.read(encoded);
if (val.getTag() != DER.BIT_STRING)
throw new IOException("malformed KeyUsage");
keyUsage = (BitString) val.getValue();
}
// Instance methods.
// -------------------------------------------------------------------------
public BitString getKeyUsage()
{
return keyUsage;
}
public String toString()
{
return KeyUsage.class.getName() + " [ " + keyUsage + " ]";
}
}
@@ -0,0 +1,109 @@
/* PolicyConstraint.java -- policyConstraint extension
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.math.BigInteger;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.x509.Util;
public class PolicyConstraint extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID ("2.5.29.36");
private final int requireExplicitPolicy;
private final int inhibitPolicyMapping;
// Constructors.
// -------------------------------------------------------------------------
public PolicyConstraint (final byte[] encoded) throws IOException
{
super (encoded);
int rpc = -1, ipm = -1;
DERReader der = new DERReader(encoded);
DERValue pc = der.read();
if (!pc.isConstructed())
throw new IOException("malformed PolicyConstraints");
DERValue val;
int len = pc.getLength();
while (len > 0)
{
val = der.read();
if (val.getTag() == 0)
rpc = new BigInteger ((byte[]) val.getValue()).intValue();
else if (val.getTag() == 1)
ipm = new BigInteger ((byte[]) val.getValue()).intValue();
else
throw new IOException ("invalid policy constraint");
len -= val.getEncodedLength();
}
requireExplicitPolicy = rpc;
inhibitPolicyMapping = ipm;
}
// Instance methods.
// -------------------------------------------------------------------------
public int getRequireExplicitPolicy()
{
return requireExplicitPolicy;
}
public int getInhibitPolicyMapping()
{
return inhibitPolicyMapping;
}
public String toString()
{
return PolicyConstraint.class.getName() + " [ requireExplicitPolicy=" +
requireExplicitPolicy + " inhibitPolicyMapping=" + inhibitPolicyMapping
+ " ]";
}
}
@@ -0,0 +1,104 @@
/* PolicyMappings.java -- policy mappings extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class PolicyMappings extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.33");
private final Map mappings;
// Constructor.
// -------------------------------------------------------------------------
public PolicyMappings(final byte[] encoded) throws IOException
{
super(encoded);
DERReader der = new DERReader(encoded);
DERValue maps = der.read();
if (!maps.isConstructed())
throw new IOException("malformed PolicyMappings");
int len = 0;
HashMap _mappings = new HashMap();
while (len < maps.getLength())
{
DERValue map = der.read();
if (!map.isConstructed())
throw new IOException("malformed PolicyMapping");
DERValue val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed PolicyMapping");
OID issuerPolicy = (OID) val.getValue();
val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed PolicyMapping");
OID subjectPolicy = (OID) val.getValue();
_mappings.put(issuerPolicy, subjectPolicy);
len += map.getEncodedLength();
}
mappings = Collections.unmodifiableMap(_mappings);
}
// Instance methods.
// -------------------------------------------------------------------------
public OID getSubjectDomainPolicy(OID issuerDomainPolicy)
{
return (OID) mappings.get(issuerDomainPolicy);
}
public String toString()
{
return PolicyMappings.class.getName() + " [ " + mappings + " ]";
}
}
@@ -0,0 +1,105 @@
/* PrivateKeyUsagePeriod.java -- private key usage period extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.util.Date;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class PrivateKeyUsagePeriod extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.16");
private final Date notBefore;
private final Date notAfter;
// Constructor.
// -------------------------------------------------------------------------
public PrivateKeyUsagePeriod(final byte[] encoded) throws IOException
{
super(encoded);
DERReader der = new DERReader(encoded);
DERValue val = der.read();
if (!val.isConstructed())
throw new IOException("malformed PrivateKeyUsagePeriod");
if (val.getLength() > 0)
val = der.read();
if (val.getTagClass() == DER.APPLICATION || val.getTag() == 0)
{
notBefore = (Date) val.getValue();
val = der.read();
}
else
notBefore = null;
if (val.getTagClass() == DER.APPLICATION || val.getTag() == 1)
{
notAfter = (Date) val.getValue();
}
else
notAfter = null;
}
// Instance methods.
// -------------------------------------------------------------------------
public Date getNotBefore()
{
return notBefore != null ? (Date) notBefore.clone() : null;
}
public Date getNotAfter()
{
return notAfter != null ? (Date) notAfter.clone() : null;
}
public String toString()
{
return PrivateKeyUsagePeriod.class.getName() + " [ notBefore=" + notBefore
+ " notAfter=" + notAfter + " ]";
}
}
@@ -0,0 +1,85 @@
/* ReasonCode.java -- a reason code for a certificate revocation.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.math.BigInteger;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
public class ReasonCode extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.21");
public final int reason;
// Constructor.
// -------------------------------------------------------------------------
public ReasonCode(final byte[] encoded) throws IOException
{
super(encoded);
DERValue val = DERReader.read(encoded);
if (val.getTag() != DER.ENUMERATED)
throw new IOException("malformed CRLReason");
reason = ((BigInteger) val.getValue()).intValue();
if (reason < 0 || reason == 7 || reason > 10)
throw new IOException("illegal reason: " + reason);
}
// Instance method.
// -------------------------------------------------------------------------
public int getReasonCode()
{
return reason;
}
public String toString()
{
return ReasonCode.class.getName() + " [ " + reason + " ]";
}
}
@@ -0,0 +1,77 @@
/* SubjectAlternatuveNames.java -- subject alternative names extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import java.util.List;
import gnu.java.security.OID;
public class SubjectAlternativeNames extends Extension.Value
{
// Constants and fields.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.17");
private final GeneralNames names;
// Constructor.
// -------------------------------------------------------------------------
public SubjectAlternativeNames(final byte[] encoded) throws IOException
{
super(encoded);
names = new GeneralNames(encoded);
}
// Instance method.
// -------------------------------------------------------------------------
public List getNames()
{
return names.getNames();
}
public String toString()
{
return SubjectAlternativeNames.class.getName() + " [ " + names + " ]";
}
}
@@ -0,0 +1,84 @@
/* SubjectKeyIdentifier.java -- subject key identifier extension.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath 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; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.x509.ext;
import java.io.IOException;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.x509.Util;
public class SubjectKeyIdentifier extends Extension.Value
{
// Constant.
// -------------------------------------------------------------------------
public static final OID ID = new OID("2.5.29.14");
private final byte[] keyIdentifier;
// Constructor.
// -------------------------------------------------------------------------
public SubjectKeyIdentifier(final byte[] encoded) throws IOException
{
super(encoded);
DERValue val = DERReader.read(encoded);
if (val.getTag() != DER.OCTET_STRING)
throw new IOException("malformed SubjectKeyIdentifier");
keyIdentifier = (byte[]) val.getValue();
}
// Instance methods.
// -------------------------------------------------------------------------
public byte[] getKeyIdentifier()
{
return (byte[]) keyIdentifier.clone();
}
public String toString()
{
return SubjectKeyIdentifier.class.getName() + " [ " +
Util.toHexString (keyIdentifier, ':') + " ]";
}
}