summaryrefslogtreecommitdiffstats
path: root/libjava/gnu/java/security/x509/X509Certificate.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/java/security/x509/X509Certificate.java')
-rw-r--r--libjava/gnu/java/security/x509/X509Certificate.java604
1 files changed, 327 insertions, 277 deletions
diff --git a/libjava/gnu/java/security/x509/X509Certificate.java b/libjava/gnu/java/security/x509/X509Certificate.java
index 1ec2e87c2c6..25a56d4a8ef 100644
--- a/libjava/gnu/java/security/x509/X509Certificate.java
+++ b/libjava/gnu/java/security/x509/X509Certificate.java
@@ -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 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;
+ 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();
+ }
+ }
+
+ 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();
- }
- }
- catch (IOException ioe)
{
- throw new CertificateParsingException(ioe.toString());
+ throw new CertificateException("signature not validated");
}
- 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);
-
- if (!der.read().isConstructed())
- throw new ASN1ParsingException("malformed SubjectPublicKeyInfo");
-
- val = der.read();
- if (!val.isConstructed())
- throw new ASN1ParsingException("malformed AlgorithmIdentifier");
- int keyAlgLen = val.getLength();
+ // subject Name,
val = der.read();
- OID keyID = (OID) val.getValue();
- byte[] keyParams = null;
- if (keyAlgLen > val.getEncodedLength())
+ subject = new X500DistinguishedName(val.getEncoded());
+ der.skip(val.getLength());
+ debug("read subject == " + subject);
+
+ // 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();
+ KeyFactory spkFac = KeyFactory.getInstance("X.509");
+ subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
+ der.skip(spki.getLength());
+ debug("read subjectPublicKey == " + subjectKey);
- 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))
+ if (version > 1)
{
- 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()));
+ val = der.read();
}
- else
- throw new ASN1ParsingException("unknown key algorithm " + keyID);
-
- if (version > 1)
- 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, ">>>> "));
}
}
OpenPOWER on IntegriCloud