004-11-15 Andreas Tobler <a.tobler@schweiz.ch>
authorAndreas Tobler <andreast@gcc.gnu.org>
Mon, 15 Nov 2004 20:02:08 +0000 (21:02 +0100)
committerAndreas Tobler <andreast@gcc.gnu.org>
Mon, 15 Nov 2004 20:02:08 +0000 (21:02 +0100)
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

43 files changed:
libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/gnu/java/security/provider/CollectionCertStoreImpl.java [new file with mode: 0644]
libjava/gnu/java/security/provider/EncodedKeyFactory.java [new file with mode: 0644]
libjava/gnu/java/security/provider/Gnu.java
libjava/gnu/java/security/provider/GnuDHPublicKey.java [new file with mode: 0644]
libjava/gnu/java/security/provider/GnuRSAPrivateKey.java [new file with mode: 0644]
libjava/gnu/java/security/provider/GnuRSAPublicKey.java [new file with mode: 0644]
libjava/gnu/java/security/provider/MD2withRSA.java [new file with mode: 0644]
libjava/gnu/java/security/provider/MD4withRSA.java [new file with mode: 0644]
libjava/gnu/java/security/provider/MD5withRSA.java [new file with mode: 0644]
libjava/gnu/java/security/provider/PKIXCertPathValidatorImpl.java [new file with mode: 0644]
libjava/gnu/java/security/provider/RSA.java [new file with mode: 0644]
libjava/gnu/java/security/provider/RSAKeyFactory.java [new file with mode: 0644]
libjava/gnu/java/security/provider/SHA1withRSA.java [new file with mode: 0644]
libjava/gnu/java/security/provider/X509CertificateFactory.java
libjava/gnu/java/security/x509/GnuPKIExtension.java [new file with mode: 0644]
libjava/gnu/java/security/x509/PolicyNodeImpl.java [new file with mode: 0644]
libjava/gnu/java/security/x509/Util.java [new file with mode: 0644]
libjava/gnu/java/security/x509/X500DistinguishedName.java
libjava/gnu/java/security/x509/X509CRL.java
libjava/gnu/java/security/x509/X509CRLEntry.java
libjava/gnu/java/security/x509/X509CRLSelectorImpl.java [new file with mode: 0644]
libjava/gnu/java/security/x509/X509CertPath.java [new file with mode: 0644]
libjava/gnu/java/security/x509/X509CertSelectorImpl.java [new file with mode: 0644]
libjava/gnu/java/security/x509/X509Certificate.java
libjava/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/BasicConstraints.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/CRLNumber.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/CertificatePolicies.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/ExtendedKeyUsage.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/Extension.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/GeneralNames.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/IssuerAlternativeNames.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/KeyUsage.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/PolicyConstraint.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/PolicyMappings.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/ReasonCode.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/SubjectAlternativeNames.java [new file with mode: 0644]
libjava/gnu/java/security/x509/ext/SubjectKeyIdentifier.java [new file with mode: 0644]
libjava/java/security/cert/TrustAnchor.java

index 1e9a691317b23375c1aa9d75904e1e2631bf3136..a9a492f33267ef91b18efbe2c6d5eaa34a109e43 100644 (file)
@@ -1,3 +1,73 @@
+2004-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.
+
 2004-11-12  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR other/14264
        'F_RDLCK' for shared locks, 'F_WRLCK' for exclusive locks.
 
 2004-11-11  Robert Schuster <thebohemian@gmx.net>
-  
-       Fixed regression:
-       * gnu/java/beans/IntrospectionIncubator.java:
-       (addMethod): corrected classification of normal and property methods
-       (capitalize): added documentation
-       (DoubleKey): [class] added documentation
+
+       Fixed regression:
+       * gnu/java/beans/IntrospectionIncubator.java:
+       (addMethod): Corrected classification of normal and property methods.
+       (capitalize): Added documentation.
+       (DoubleKey): [class] Added documentation.
 
 2004-11-09  Tom Tromey  <tromey@redhat.com>
 
index 9c39dec6ccf959f44f392009d00950d44401a0cd..9a439fada5a88b8708ee17430fd3d0dc285ef95f 100644 (file)
@@ -2749,24 +2749,57 @@ gnu/java/security/der/DEREncodingException.java \
 gnu/java/security/der/DERReader.java \
 gnu/java/security/der/DERValue.java \
 gnu/java/security/der/DERWriter.java \
+gnu/java/security/provider/CollectionCertStoreImpl.java \
 gnu/java/security/provider/DSAKeyFactory.java \
 gnu/java/security/provider/DSAKeyPairGenerator.java \
 gnu/java/security/provider/DSAParameterGenerator.java \
 gnu/java/security/provider/DSAParameters.java \
 gnu/java/security/provider/DSASignature.java \
 gnu/java/security/provider/DefaultPolicy.java \
+gnu/java/security/provider/EncodedKeyFactory.java \
 gnu/java/security/provider/Gnu.java \
+gnu/java/security/provider/GnuDHPublicKey.java \
 gnu/java/security/provider/GnuDSAPrivateKey.java \
 gnu/java/security/provider/GnuDSAPublicKey.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/MD5.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/SHA.java \
 gnu/java/security/provider/SHA1PRNG.java \
+gnu/java/security/provider/SHA1withRSA.java \
 gnu/java/security/provider/X509CertificateFactory.java \
 gnu/java/security/util/Prime.java \
+gnu/java/security/x509/GnuPKIExtension.java \
+gnu/java/security/x509/PolicyNodeImpl.java \
+gnu/java/security/x509/Util.java \
 gnu/java/security/x509/X500DistinguishedName.java \
 gnu/java/security/x509/X509CRL.java \
 gnu/java/security/x509/X509CRLEntry.java \
+gnu/java/security/x509/X509CRLSelectorImpl.java \
 gnu/java/security/x509/X509Certificate.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 \
 gnu/java/text/AttributedFormatBuffer.java \
 gnu/java/text/BaseBreakIterator.java \
 gnu/java/text/CharacterBreakIterator.java \
index 8a23bcd1e9a9a8a96f6b6482e39cf142448dab46..7227bc8c36c3c625193b5108248eeafc0afade43 100644 (file)
@@ -802,24 +802,57 @@ am__libgcj_la_SOURCES_DIST = prims.cc jni.cc exception.cc resolve.cc \
        gnu/java/security/der/DERReader.java \
        gnu/java/security/der/DERValue.java \
        gnu/java/security/der/DERWriter.java \
+       gnu/java/security/provider/CollectionCertStoreImpl.java \
        gnu/java/security/provider/DSAKeyFactory.java \
        gnu/java/security/provider/DSAKeyPairGenerator.java \
        gnu/java/security/provider/DSAParameterGenerator.java \
        gnu/java/security/provider/DSAParameters.java \
        gnu/java/security/provider/DSASignature.java \
        gnu/java/security/provider/DefaultPolicy.java \
+       gnu/java/security/provider/EncodedKeyFactory.java \
        gnu/java/security/provider/Gnu.java \
+       gnu/java/security/provider/GnuDHPublicKey.java \
        gnu/java/security/provider/GnuDSAPrivateKey.java \
        gnu/java/security/provider/GnuDSAPublicKey.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/MD5.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/SHA.java \
        gnu/java/security/provider/SHA1PRNG.java \
+       gnu/java/security/provider/SHA1withRSA.java \
        gnu/java/security/provider/X509CertificateFactory.java \
        gnu/java/security/util/Prime.java \
+       gnu/java/security/x509/GnuPKIExtension.java \
+       gnu/java/security/x509/PolicyNodeImpl.java \
+       gnu/java/security/x509/Util.java \
        gnu/java/security/x509/X500DistinguishedName.java \
        gnu/java/security/x509/X509CRL.java \
        gnu/java/security/x509/X509CRLEntry.java \
+       gnu/java/security/x509/X509CRLSelectorImpl.java \
        gnu/java/security/x509/X509Certificate.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 \
        gnu/java/text/AttributedFormatBuffer.java \
        gnu/java/text/BaseBreakIterator.java \
        gnu/java/text/CharacterBreakIterator.java \
@@ -3747,24 +3780,57 @@ am__objects_14 = $(am__objects_9) gnu/classpath/ServiceFactory.lo \
        gnu/java/security/der/DERReader.lo \
        gnu/java/security/der/DERValue.lo \
        gnu/java/security/der/DERWriter.lo \
+       gnu/java/security/provider/CollectionCertStoreImpl.lo \
        gnu/java/security/provider/DSAKeyFactory.lo \
        gnu/java/security/provider/DSAKeyPairGenerator.lo \
        gnu/java/security/provider/DSAParameterGenerator.lo \
        gnu/java/security/provider/DSAParameters.lo \
        gnu/java/security/provider/DSASignature.lo \
        gnu/java/security/provider/DefaultPolicy.lo \
+       gnu/java/security/provider/EncodedKeyFactory.lo \
        gnu/java/security/provider/Gnu.lo \
+       gnu/java/security/provider/GnuDHPublicKey.lo \
        gnu/java/security/provider/GnuDSAPrivateKey.lo \
        gnu/java/security/provider/GnuDSAPublicKey.lo \
+       gnu/java/security/provider/GnuRSAPrivateKey.lo \
+       gnu/java/security/provider/GnuRSAPublicKey.lo \
+       gnu/java/security/provider/MD2withRSA.lo \
+       gnu/java/security/provider/MD4withRSA.lo \
        gnu/java/security/provider/MD5.lo \
+       gnu/java/security/provider/MD5withRSA.lo \
+       gnu/java/security/provider/PKIXCertPathValidatorImpl.lo \
+       gnu/java/security/provider/RSA.lo \
+       gnu/java/security/provider/RSAKeyFactory.lo \
        gnu/java/security/provider/SHA.lo \
        gnu/java/security/provider/SHA1PRNG.lo \
+       gnu/java/security/provider/SHA1withRSA.lo \
        gnu/java/security/provider/X509CertificateFactory.lo \
        gnu/java/security/util/Prime.lo \
+       gnu/java/security/x509/GnuPKIExtension.lo \
+       gnu/java/security/x509/PolicyNodeImpl.lo \
+       gnu/java/security/x509/Util.lo \
        gnu/java/security/x509/X500DistinguishedName.lo \
        gnu/java/security/x509/X509CRL.lo \
        gnu/java/security/x509/X509CRLEntry.lo \
+       gnu/java/security/x509/X509CRLSelectorImpl.lo \
        gnu/java/security/x509/X509Certificate.lo \
+       gnu/java/security/x509/X509CertPath.lo \
+       gnu/java/security/x509/X509CertSelectorImpl.lo \
+       gnu/java/security/x509/ext/AuthorityKeyIdentifier.lo \
+       gnu/java/security/x509/ext/BasicConstraints.lo \
+       gnu/java/security/x509/ext/CRLNumber.lo \
+       gnu/java/security/x509/ext/CertificatePolicies.lo \
+       gnu/java/security/x509/ext/ExtendedKeyUsage.lo \
+       gnu/java/security/x509/ext/Extension.lo \
+       gnu/java/security/x509/ext/GeneralNames.lo \
+       gnu/java/security/x509/ext/IssuerAlternativeNames.lo \
+       gnu/java/security/x509/ext/KeyUsage.lo \
+       gnu/java/security/x509/ext/PolicyConstraint.lo \
+       gnu/java/security/x509/ext/PolicyMappings.lo \
+       gnu/java/security/x509/ext/PrivateKeyUsagePeriod.lo \
+       gnu/java/security/x509/ext/ReasonCode.lo \
+       gnu/java/security/x509/ext/SubjectAlternativeNames.lo \
+       gnu/java/security/x509/ext/SubjectKeyIdentifier.lo \
        gnu/java/text/AttributedFormatBuffer.lo \
        gnu/java/text/BaseBreakIterator.lo \
        gnu/java/text/CharacterBreakIterator.lo \
@@ -6573,24 +6639,57 @@ gnu/java/security/der/DEREncodingException.java \
 gnu/java/security/der/DERReader.java \
 gnu/java/security/der/DERValue.java \
 gnu/java/security/der/DERWriter.java \
+gnu/java/security/provider/CollectionCertStoreImpl.java \
 gnu/java/security/provider/DSAKeyFactory.java \
 gnu/java/security/provider/DSAKeyPairGenerator.java \
 gnu/java/security/provider/DSAParameterGenerator.java \
 gnu/java/security/provider/DSAParameters.java \
 gnu/java/security/provider/DSASignature.java \
 gnu/java/security/provider/DefaultPolicy.java \
+gnu/java/security/provider/EncodedKeyFactory.java \
 gnu/java/security/provider/Gnu.java \
+gnu/java/security/provider/GnuDHPublicKey.java \
 gnu/java/security/provider/GnuDSAPrivateKey.java \
 gnu/java/security/provider/GnuDSAPublicKey.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/MD5.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/SHA.java \
 gnu/java/security/provider/SHA1PRNG.java \
+gnu/java/security/provider/SHA1withRSA.java \
 gnu/java/security/provider/X509CertificateFactory.java \
 gnu/java/security/util/Prime.java \
+gnu/java/security/x509/GnuPKIExtension.java \
+gnu/java/security/x509/PolicyNodeImpl.java \
+gnu/java/security/x509/Util.java \
 gnu/java/security/x509/X500DistinguishedName.java \
 gnu/java/security/x509/X509CRL.java \
 gnu/java/security/x509/X509CRLEntry.java \
+gnu/java/security/x509/X509CRLSelectorImpl.java \
 gnu/java/security/x509/X509Certificate.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 \
 gnu/java/text/AttributedFormatBuffer.java \
 gnu/java/text/BaseBreakIterator.java \
 gnu/java/text/CharacterBreakIterator.java \
@@ -9407,6 +9506,9 @@ gnu/java/security/provider/$(am__dirstamp):
 gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp):
        @$(mkdir_p) gnu/java/security/provider/$(DEPDIR)
        @: > gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/CollectionCertStoreImpl.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/DSAKeyFactory.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
@@ -9425,24 +9527,57 @@ gnu/java/security/provider/DSASignature.lo:  \
 gnu/java/security/provider/DefaultPolicy.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/EncodedKeyFactory.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/Gnu.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/GnuDHPublicKey.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/GnuDSAPrivateKey.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/GnuDSAPublicKey.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/GnuRSAPrivateKey.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/GnuRSAPublicKey.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/MD2withRSA.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/MD4withRSA.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/MD5.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/MD5withRSA.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/PKIXCertPathValidatorImpl.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/RSA.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/RSAKeyFactory.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/SHA.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/SHA1PRNG.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/provider/SHA1withRSA.lo:  \
+       gnu/java/security/provider/$(am__dirstamp) \
+       gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/provider/X509CertificateFactory.lo:  \
        gnu/java/security/provider/$(am__dirstamp) \
        gnu/java/security/provider/$(DEPDIR)/$(am__dirstamp)
@@ -9461,6 +9596,15 @@ gnu/java/security/x509/$(am__dirstamp):
 gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp):
        @$(mkdir_p) gnu/java/security/x509/$(DEPDIR)
        @: > gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/GnuPKIExtension.lo:  \
+       gnu/java/security/x509/$(am__dirstamp) \
+       gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/PolicyNodeImpl.lo:  \
+       gnu/java/security/x509/$(am__dirstamp) \
+       gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/Util.lo:  \
+       gnu/java/security/x509/$(am__dirstamp) \
+       gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/x509/X500DistinguishedName.lo:  \
        gnu/java/security/x509/$(am__dirstamp) \
        gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
@@ -9470,9 +9614,69 @@ gnu/java/security/x509/X509CRL.lo:  \
 gnu/java/security/x509/X509CRLEntry.lo:  \
        gnu/java/security/x509/$(am__dirstamp) \
        gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/X509CRLSelectorImpl.lo:  \
+       gnu/java/security/x509/$(am__dirstamp) \
+       gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
 gnu/java/security/x509/X509Certificate.lo:  \
        gnu/java/security/x509/$(am__dirstamp) \
        gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/X509CertPath.lo:  \
+       gnu/java/security/x509/$(am__dirstamp) \
+       gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/X509CertSelectorImpl.lo:  \
+       gnu/java/security/x509/$(am__dirstamp) \
+       gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/$(am__dirstamp):
+       @$(mkdir_p) gnu/java/security/x509/ext
+       @: > gnu/java/security/x509/ext/$(am__dirstamp)
+gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp):
+       @$(mkdir_p) gnu/java/security/x509/ext/$(DEPDIR)
+       @: > gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/AuthorityKeyIdentifier.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/BasicConstraints.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/CRLNumber.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/CertificatePolicies.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/ExtendedKeyUsage.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/Extension.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/GeneralNames.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/IssuerAlternativeNames.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/KeyUsage.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/PolicyConstraint.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/PolicyMappings.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/PrivateKeyUsagePeriod.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/ReasonCode.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/SubjectAlternativeNames.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+gnu/java/security/x509/ext/SubjectKeyIdentifier.lo:  \
+       gnu/java/security/x509/ext/$(am__dirstamp) \
+       gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
 gnu/java/text/$(am__dirstamp):
        @$(mkdir_p) gnu/java/text
        @: > gnu/java/text/$(am__dirstamp)
@@ -15059,6 +15263,8 @@ mostlyclean-compile:
        -rm -f gnu/java/security/der/DERValue.lo
        -rm -f gnu/java/security/der/DERWriter.$(OBJEXT)
        -rm -f gnu/java/security/der/DERWriter.lo
+       -rm -f gnu/java/security/provider/CollectionCertStoreImpl.$(OBJEXT)
+       -rm -f gnu/java/security/provider/CollectionCertStoreImpl.lo
        -rm -f gnu/java/security/provider/DSAKeyFactory.$(OBJEXT)
        -rm -f gnu/java/security/provider/DSAKeyFactory.lo
        -rm -f gnu/java/security/provider/DSAKeyPairGenerator.$(OBJEXT)
@@ -15071,30 +15277,94 @@ mostlyclean-compile:
        -rm -f gnu/java/security/provider/DSASignature.lo
        -rm -f gnu/java/security/provider/DefaultPolicy.$(OBJEXT)
        -rm -f gnu/java/security/provider/DefaultPolicy.lo
+       -rm -f gnu/java/security/provider/EncodedKeyFactory.$(OBJEXT)
+       -rm -f gnu/java/security/provider/EncodedKeyFactory.lo
        -rm -f gnu/java/security/provider/Gnu.$(OBJEXT)
        -rm -f gnu/java/security/provider/Gnu.lo
+       -rm -f gnu/java/security/provider/GnuDHPublicKey.$(OBJEXT)
+       -rm -f gnu/java/security/provider/GnuDHPublicKey.lo
        -rm -f gnu/java/security/provider/GnuDSAPrivateKey.$(OBJEXT)
        -rm -f gnu/java/security/provider/GnuDSAPrivateKey.lo
        -rm -f gnu/java/security/provider/GnuDSAPublicKey.$(OBJEXT)
        -rm -f gnu/java/security/provider/GnuDSAPublicKey.lo
+       -rm -f gnu/java/security/provider/GnuRSAPrivateKey.$(OBJEXT)
+       -rm -f gnu/java/security/provider/GnuRSAPrivateKey.lo
+       -rm -f gnu/java/security/provider/GnuRSAPublicKey.$(OBJEXT)
+       -rm -f gnu/java/security/provider/GnuRSAPublicKey.lo
+       -rm -f gnu/java/security/provider/MD2withRSA.$(OBJEXT)
+       -rm -f gnu/java/security/provider/MD2withRSA.lo
+       -rm -f gnu/java/security/provider/MD4withRSA.$(OBJEXT)
+       -rm -f gnu/java/security/provider/MD4withRSA.lo
        -rm -f gnu/java/security/provider/MD5.$(OBJEXT)
        -rm -f gnu/java/security/provider/MD5.lo
+       -rm -f gnu/java/security/provider/MD5withRSA.$(OBJEXT)
+       -rm -f gnu/java/security/provider/MD5withRSA.lo
+       -rm -f gnu/java/security/provider/PKIXCertPathValidatorImpl.$(OBJEXT)
+       -rm -f gnu/java/security/provider/PKIXCertPathValidatorImpl.lo
+       -rm -f gnu/java/security/provider/RSA.$(OBJEXT)
+       -rm -f gnu/java/security/provider/RSA.lo
+       -rm -f gnu/java/security/provider/RSAKeyFactory.$(OBJEXT)
+       -rm -f gnu/java/security/provider/RSAKeyFactory.lo
        -rm -f gnu/java/security/provider/SHA.$(OBJEXT)
        -rm -f gnu/java/security/provider/SHA.lo
        -rm -f gnu/java/security/provider/SHA1PRNG.$(OBJEXT)
        -rm -f gnu/java/security/provider/SHA1PRNG.lo
+       -rm -f gnu/java/security/provider/SHA1withRSA.$(OBJEXT)
+       -rm -f gnu/java/security/provider/SHA1withRSA.lo
        -rm -f gnu/java/security/provider/X509CertificateFactory.$(OBJEXT)
        -rm -f gnu/java/security/provider/X509CertificateFactory.lo
        -rm -f gnu/java/security/util/Prime.$(OBJEXT)
        -rm -f gnu/java/security/util/Prime.lo
+       -rm -f gnu/java/security/x509/GnuPKIExtension.$(OBJEXT)
+       -rm -f gnu/java/security/x509/GnuPKIExtension.lo
+       -rm -f gnu/java/security/x509/PolicyNodeImpl.$(OBJEXT)
+       -rm -f gnu/java/security/x509/PolicyNodeImpl.lo
+       -rm -f gnu/java/security/x509/Util.$(OBJEXT)
+       -rm -f gnu/java/security/x509/Util.lo
        -rm -f gnu/java/security/x509/X500DistinguishedName.$(OBJEXT)
        -rm -f gnu/java/security/x509/X500DistinguishedName.lo
        -rm -f gnu/java/security/x509/X509CRL.$(OBJEXT)
        -rm -f gnu/java/security/x509/X509CRL.lo
        -rm -f gnu/java/security/x509/X509CRLEntry.$(OBJEXT)
        -rm -f gnu/java/security/x509/X509CRLEntry.lo
+       -rm -f gnu/java/security/x509/X509CRLSelectorImpl.$(OBJEXT)
+       -rm -f gnu/java/security/x509/X509CRLSelectorImpl.lo
+       -rm -f gnu/java/security/x509/X509CertPath.$(OBJEXT)
+       -rm -f gnu/java/security/x509/X509CertPath.lo
+       -rm -f gnu/java/security/x509/X509CertSelectorImpl.$(OBJEXT)
+       -rm -f gnu/java/security/x509/X509CertSelectorImpl.lo
        -rm -f gnu/java/security/x509/X509Certificate.$(OBJEXT)
        -rm -f gnu/java/security/x509/X509Certificate.lo
+       -rm -f gnu/java/security/x509/ext/AuthorityKeyIdentifier.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/AuthorityKeyIdentifier.lo
+       -rm -f gnu/java/security/x509/ext/BasicConstraints.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/BasicConstraints.lo
+       -rm -f gnu/java/security/x509/ext/CRLNumber.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/CRLNumber.lo
+       -rm -f gnu/java/security/x509/ext/CertificatePolicies.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/CertificatePolicies.lo
+       -rm -f gnu/java/security/x509/ext/ExtendedKeyUsage.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/ExtendedKeyUsage.lo
+       -rm -f gnu/java/security/x509/ext/Extension.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/Extension.lo
+       -rm -f gnu/java/security/x509/ext/GeneralNames.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/GeneralNames.lo
+       -rm -f gnu/java/security/x509/ext/IssuerAlternativeNames.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/IssuerAlternativeNames.lo
+       -rm -f gnu/java/security/x509/ext/KeyUsage.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/KeyUsage.lo
+       -rm -f gnu/java/security/x509/ext/PolicyConstraint.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/PolicyConstraint.lo
+       -rm -f gnu/java/security/x509/ext/PolicyMappings.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/PolicyMappings.lo
+       -rm -f gnu/java/security/x509/ext/PrivateKeyUsagePeriod.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/PrivateKeyUsagePeriod.lo
+       -rm -f gnu/java/security/x509/ext/ReasonCode.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/ReasonCode.lo
+       -rm -f gnu/java/security/x509/ext/SubjectAlternativeNames.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/SubjectAlternativeNames.lo
+       -rm -f gnu/java/security/x509/ext/SubjectKeyIdentifier.$(OBJEXT)
+       -rm -f gnu/java/security/x509/ext/SubjectKeyIdentifier.lo
        -rm -f gnu/java/text/AttributedFormatBuffer.$(OBJEXT)
        -rm -f gnu/java/text/AttributedFormatBuffer.lo
        -rm -f gnu/java/text/BaseBreakIterator.$(OBJEXT)
@@ -19629,24 +19899,57 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/der/$(DEPDIR)/DERReader.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/der/$(DEPDIR)/DERValue.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/der/$(DEPDIR)/DERWriter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/CollectionCertStoreImpl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/DSAKeyFactory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/DSAKeyPairGenerator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/DSAParameterGenerator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/DSAParameters.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/DSASignature.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/DefaultPolicy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/EncodedKeyFactory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/Gnu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/GnuDHPublicKey.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/GnuDSAPrivateKey.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/GnuDSAPublicKey.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/GnuRSAPrivateKey.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/GnuRSAPublicKey.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/MD2withRSA.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/MD4withRSA.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/MD5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/MD5withRSA.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/PKIXCertPathValidatorImpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/RSA.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/RSAKeyFactory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/SHA.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/SHA1PRNG.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/SHA1withRSA.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/provider/$(DEPDIR)/X509CertificateFactory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/util/$(DEPDIR)/Prime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/GnuPKIExtension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/PolicyNodeImpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/Util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X500DistinguishedName.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X509CRL.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X509CRLEntry.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X509CRLSelectorImpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X509CertPath.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X509CertSelectorImpl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/$(DEPDIR)/X509Certificate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/AuthorityKeyIdentifier.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/BasicConstraints.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/CRLNumber.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/CertificatePolicies.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/ExtendedKeyUsage.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/Extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/GeneralNames.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/IssuerAlternativeNames.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/KeyUsage.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/PolicyConstraint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/PolicyMappings.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/PrivateKeyUsagePeriod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/ReasonCode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/SubjectAlternativeNames.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@gnu/java/security/x509/ext/$(DEPDIR)/SubjectKeyIdentifier.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/text/$(DEPDIR)/AttributedFormatBuffer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/text/$(DEPDIR)/BaseBreakIterator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@gnu/java/text/$(DEPDIR)/CharacterBreakIterator.Plo@am__quote@
@@ -22547,6 +22850,7 @@ clean-libtool:
        -rm -rf gnu/java/security/provider/.libs gnu/java/security/provider/_libs
        -rm -rf gnu/java/security/util/.libs gnu/java/security/util/_libs
        -rm -rf gnu/java/security/x509/.libs gnu/java/security/x509/_libs
+       -rm -rf gnu/java/security/x509/ext/.libs gnu/java/security/x509/ext/_libs
        -rm -rf gnu/java/text/.libs gnu/java/text/_libs
        -rm -rf gnu/java/util/.libs gnu/java/util/_libs
        -rm -rf gnu/java/util/prefs/.libs gnu/java/util/prefs/_libs
@@ -23079,6 +23383,8 @@ distclean-generic:
        -rm -f gnu/java/security/util/$(am__dirstamp)
        -rm -f gnu/java/security/x509/$(DEPDIR)/$(am__dirstamp)
        -rm -f gnu/java/security/x509/$(am__dirstamp)
+       -rm -f gnu/java/security/x509/ext/$(DEPDIR)/$(am__dirstamp)
+       -rm -f gnu/java/security/x509/ext/$(am__dirstamp)
        -rm -f gnu/java/text/$(DEPDIR)/$(am__dirstamp)
        -rm -f gnu/java/text/$(am__dirstamp)
        -rm -f gnu/java/util/$(DEPDIR)/$(am__dirstamp)
@@ -23297,7 +23603,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \
 
 distclean: distclean-recursive
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
-       -rm -rf ./$(DEPDIR) gnu/awt/$(DEPDIR) gnu/awt/j2d/$(DEPDIR) gnu/awt/xlib/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/awt/$(DEPDIR) gnu/java/awt/image/$(DEPDIR) gnu/java/awt/peer/$(DEPDIR) gnu/java/awt/peer/gtk/$(DEPDIR) gnu/java/beans/$(DEPDIR) gnu/java/beans/editors/$(DEPDIR) gnu/java/beans/info/$(DEPDIR) gnu/java/io/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/lang/reflect/$(DEPDIR) gnu/java/locale/$(DEPDIR) gnu/java/math/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/net/protocol/file/$(DEPDIR) gnu/java/net/protocol/gcjlib/$(DEPDIR) gnu/java/net/protocol/http/$(DEPDIR) gnu/java/net/protocol/jar/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) gnu/java/nio/charset/$(DEPDIR) gnu/java/rmi/$(DEPDIR) gnu/java/rmi/dgc/$(DEPDIR) gnu/java/rmi/registry/$(DEPDIR) gnu/java/rmi/rmic/$(DEPDIR) gnu/java/rmi/server/$(DEPDIR) gnu/java/security/$(DEPDIR) gnu/java/security/action/$(DEPDIR) gnu/java/security/der/$(DEPDIR) gnu/java/security/provider/$(DEPDIR) gnu/java/security/util/$(DEPDIR) gnu/java/security/x509/$(DEPDIR) gnu/java/text/$(DEPDIR) gnu/java/util/$(DEPDIR) gnu/java/util/prefs/$(DEPDIR) gnu/regexp/$(DEPDIR) java/applet/$(DEPDIR) java/awt/$(DEPDIR) java/awt/color/$(DEPDIR) java/awt/datatransfer/$(DEPDIR) java/awt/dnd/$(DEPDIR) java/awt/dnd/peer/$(DEPDIR) java/awt/event/$(DEPDIR) java/awt/font/$(DEPDIR) java/awt/geom/$(DEPDIR) java/awt/im/$(DEPDIR) java/awt/im/spi/$(DEPDIR) java/awt/image/$(DEPDIR) java/awt/image/renderable/$(DEPDIR) java/awt/peer/$(DEPDIR) java/awt/print/$(DEPDIR) java/beans/$(DEPDIR) java/beans/beancontext/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/math/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/nio/channels/spi/$(DEPDIR) java/nio/charset/$(DEPDIR) java/nio/charset/spi/$(DEPDIR) java/rmi/$(DEPDIR) java/rmi/activation/$(DEPDIR) java/rmi/dgc/$(DEPDIR) java/rmi/registry/$(DEPDIR) java/rmi/server/$(DEPDIR) java/security/$(DEPDIR) java/security/acl/$(DEPDIR) java/security/cert/$(DEPDIR) java/security/interfaces/$(DEPDIR) java/security/spec/$(DEPDIR) java/sql/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/jar/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/prefs/$(DEPDIR) java/util/regex/$(DEPDIR) java/util/zip/$(DEPDIR) javax/accessibility/$(DEPDIR) javax/crypto/$(DEPDIR) javax/crypto/interfaces/$(DEPDIR) javax/crypto/spec/$(DEPDIR) javax/imageio/$(DEPDIR) javax/imageio/event/$(DEPDIR) javax/imageio/metadata/$(DEPDIR) javax/imageio/spi/$(DEPDIR) javax/imageio/stream/$(DEPDIR) javax/naming/$(DEPDIR) javax/naming/directory/$(DEPDIR) javax/naming/event/$(DEPDIR) javax/naming/ldap/$(DEPDIR) javax/naming/spi/$(DEPDIR) javax/net/$(DEPDIR) javax/net/ssl/$(DEPDIR) javax/print/$(DEPDIR) javax/print/attribute/$(DEPDIR) javax/print/attribute/standard/$(DEPDIR) javax/print/event/$(DEPDIR) javax/security/auth/$(DEPDIR) javax/security/auth/callback/$(DEPDIR) javax/security/auth/login/$(DEPDIR) javax/security/auth/x500/$(DEPDIR) javax/security/cert/$(DEPDIR) javax/security/sasl/$(DEPDIR) javax/sql/$(DEPDIR) javax/swing/$(DEPDIR) javax/swing/border/$(DEPDIR) javax/swing/colorchooser/$(DEPDIR) javax/swing/event/$(DEPDIR) javax/swing/filechooser/$(DEPDIR) javax/swing/plaf/$(DEPDIR) javax/swing/plaf/basic/$(DEPDIR) javax/swing/plaf/metal/$(DEPDIR) javax/swing/table/$(DEPDIR) javax/swing/text/$(DEPDIR) javax/swing/text/html/$(DEPDIR) javax/swing/text/html/parser/$(DEPDIR) javax/swing/tree/$(DEPDIR) javax/swing/undo/$(DEPDIR) javax/transaction/$(DEPDIR) javax/transaction/xa/$(DEPDIR) jni/classpath/$(DEPDIR) jni/gtk-peer/$(DEPDIR) org/ietf/jgss/$(DEPDIR) org/w3c/dom/$(DEPDIR) org/w3c/dom/ranges/$(DEPDIR) org/w3c/dom/traversal/$(DEPDIR) org/xml/sax/$(DEPDIR) org/xml/sax/ext/$(DEPDIR) org/xml/sax/helpers/$(DEPDIR) sysdep/$(DEPDIR)
+       -rm -rf ./$(DEPDIR) gnu/awt/$(DEPDIR) gnu/awt/j2d/$(DEPDIR) gnu/awt/xlib/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/awt/$(DEPDIR) gnu/java/awt/image/$(DEPDIR) gnu/java/awt/peer/$(DEPDIR) gnu/java/awt/peer/gtk/$(DEPDIR) gnu/java/beans/$(DEPDIR) gnu/java/beans/editors/$(DEPDIR) gnu/java/beans/info/$(DEPDIR) gnu/java/io/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/lang/reflect/$(DEPDIR) gnu/java/locale/$(DEPDIR) gnu/java/math/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/net/protocol/file/$(DEPDIR) gnu/java/net/protocol/gcjlib/$(DEPDIR) gnu/java/net/protocol/http/$(DEPDIR) gnu/java/net/protocol/jar/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) gnu/java/nio/charset/$(DEPDIR) gnu/java/rmi/$(DEPDIR) gnu/java/rmi/dgc/$(DEPDIR) gnu/java/rmi/registry/$(DEPDIR) gnu/java/rmi/rmic/$(DEPDIR) gnu/java/rmi/server/$(DEPDIR) gnu/java/security/$(DEPDIR) gnu/java/security/action/$(DEPDIR) gnu/java/security/der/$(DEPDIR) gnu/java/security/provider/$(DEPDIR) gnu/java/security/util/$(DEPDIR) gnu/java/security/x509/$(DEPDIR) gnu/java/security/x509/ext/$(DEPDIR) gnu/java/text/$(DEPDIR) gnu/java/util/$(DEPDIR) gnu/java/util/prefs/$(DEPDIR) gnu/regexp/$(DEPDIR) java/applet/$(DEPDIR) java/awt/$(DEPDIR) java/awt/color/$(DEPDIR) java/awt/datatransfer/$(DEPDIR) java/awt/dnd/$(DEPDIR) java/awt/dnd/peer/$(DEPDIR) java/awt/event/$(DEPDIR) java/awt/font/$(DEPDIR) java/awt/geom/$(DEPDIR) java/awt/im/$(DEPDIR) java/awt/im/spi/$(DEPDIR) java/awt/image/$(DEPDIR) java/awt/image/renderable/$(DEPDIR) java/awt/peer/$(DEPDIR) java/awt/print/$(DEPDIR) java/beans/$(DEPDIR) java/beans/beancontext/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/math/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/nio/channels/spi/$(DEPDIR) java/nio/charset/$(DEPDIR) java/nio/charset/spi/$(DEPDIR) java/rmi/$(DEPDIR) java/rmi/activation/$(DEPDIR) java/rmi/dgc/$(DEPDIR) java/rmi/registry/$(DEPDIR) java/rmi/server/$(DEPDIR) java/security/$(DEPDIR) java/security/acl/$(DEPDIR) java/security/cert/$(DEPDIR) java/security/interfaces/$(DEPDIR) java/security/spec/$(DEPDIR) java/sql/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/jar/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/prefs/$(DEPDIR) java/util/regex/$(DEPDIR) java/util/zip/$(DEPDIR) javax/accessibility/$(DEPDIR) javax/crypto/$(DEPDIR) javax/crypto/interfaces/$(DEPDIR) javax/crypto/spec/$(DEPDIR) javax/imageio/$(DEPDIR) javax/imageio/event/$(DEPDIR) javax/imageio/metadata/$(DEPDIR) javax/imageio/spi/$(DEPDIR) javax/imageio/stream/$(DEPDIR) javax/naming/$(DEPDIR) javax/naming/directory/$(DEPDIR) javax/naming/event/$(DEPDIR) javax/naming/ldap/$(DEPDIR) javax/naming/spi/$(DEPDIR) javax/net/$(DEPDIR) javax/net/ssl/$(DEPDIR) javax/print/$(DEPDIR) javax/print/attribute/$(DEPDIR) javax/print/attribute/standard/$(DEPDIR) javax/print/event/$(DEPDIR) javax/security/auth/$(DEPDIR) javax/security/auth/callback/$(DEPDIR) javax/security/auth/login/$(DEPDIR) javax/security/auth/x500/$(DEPDIR) javax/security/cert/$(DEPDIR) javax/security/sasl/$(DEPDIR) javax/sql/$(DEPDIR) javax/swing/$(DEPDIR) javax/swing/border/$(DEPDIR) javax/swing/colorchooser/$(DEPDIR) javax/swing/event/$(DEPDIR) javax/swing/filechooser/$(DEPDIR) javax/swing/plaf/$(DEPDIR) javax/swing/plaf/basic/$(DEPDIR) javax/swing/plaf/metal/$(DEPDIR) javax/swing/table/$(DEPDIR) javax/swing/text/$(DEPDIR) javax/swing/text/html/$(DEPDIR) javax/swing/text/html/parser/$(DEPDIR) javax/swing/tree/$(DEPDIR) javax/swing/undo/$(DEPDIR) javax/transaction/$(DEPDIR) javax/transaction/xa/$(DEPDIR) jni/classpath/$(DEPDIR) jni/gtk-peer/$(DEPDIR) org/ietf/jgss/$(DEPDIR) org/w3c/dom/$(DEPDIR) org/w3c/dom/ranges/$(DEPDIR) org/w3c/dom/traversal/$(DEPDIR) org/xml/sax/$(DEPDIR) org/xml/sax/ext/$(DEPDIR) org/xml/sax/helpers/$(DEPDIR) sysdep/$(DEPDIR)
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-libtool distclean-local distclean-tags
@@ -23327,7 +23633,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-recursive
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
        -rm -rf $(top_srcdir)/autom4te.cache
-       -rm -rf ./$(DEPDIR) gnu/awt/$(DEPDIR) gnu/awt/j2d/$(DEPDIR) gnu/awt/xlib/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/awt/$(DEPDIR) gnu/java/awt/image/$(DEPDIR) gnu/java/awt/peer/$(DEPDIR) gnu/java/awt/peer/gtk/$(DEPDIR) gnu/java/beans/$(DEPDIR) gnu/java/beans/editors/$(DEPDIR) gnu/java/beans/info/$(DEPDIR) gnu/java/io/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/lang/reflect/$(DEPDIR) gnu/java/locale/$(DEPDIR) gnu/java/math/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/net/protocol/file/$(DEPDIR) gnu/java/net/protocol/gcjlib/$(DEPDIR) gnu/java/net/protocol/http/$(DEPDIR) gnu/java/net/protocol/jar/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) gnu/java/nio/charset/$(DEPDIR) gnu/java/rmi/$(DEPDIR) gnu/java/rmi/dgc/$(DEPDIR) gnu/java/rmi/registry/$(DEPDIR) gnu/java/rmi/rmic/$(DEPDIR) gnu/java/rmi/server/$(DEPDIR) gnu/java/security/$(DEPDIR) gnu/java/security/action/$(DEPDIR) gnu/java/security/der/$(DEPDIR) gnu/java/security/provider/$(DEPDIR) gnu/java/security/util/$(DEPDIR) gnu/java/security/x509/$(DEPDIR) gnu/java/text/$(DEPDIR) gnu/java/util/$(DEPDIR) gnu/java/util/prefs/$(DEPDIR) gnu/regexp/$(DEPDIR) java/applet/$(DEPDIR) java/awt/$(DEPDIR) java/awt/color/$(DEPDIR) java/awt/datatransfer/$(DEPDIR) java/awt/dnd/$(DEPDIR) java/awt/dnd/peer/$(DEPDIR) java/awt/event/$(DEPDIR) java/awt/font/$(DEPDIR) java/awt/geom/$(DEPDIR) java/awt/im/$(DEPDIR) java/awt/im/spi/$(DEPDIR) java/awt/image/$(DEPDIR) java/awt/image/renderable/$(DEPDIR) java/awt/peer/$(DEPDIR) java/awt/print/$(DEPDIR) java/beans/$(DEPDIR) java/beans/beancontext/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/math/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/nio/channels/spi/$(DEPDIR) java/nio/charset/$(DEPDIR) java/nio/charset/spi/$(DEPDIR) java/rmi/$(DEPDIR) java/rmi/activation/$(DEPDIR) java/rmi/dgc/$(DEPDIR) java/rmi/registry/$(DEPDIR) java/rmi/server/$(DEPDIR) java/security/$(DEPDIR) java/security/acl/$(DEPDIR) java/security/cert/$(DEPDIR) java/security/interfaces/$(DEPDIR) java/security/spec/$(DEPDIR) java/sql/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/jar/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/prefs/$(DEPDIR) java/util/regex/$(DEPDIR) java/util/zip/$(DEPDIR) javax/accessibility/$(DEPDIR) javax/crypto/$(DEPDIR) javax/crypto/interfaces/$(DEPDIR) javax/crypto/spec/$(DEPDIR) javax/imageio/$(DEPDIR) javax/imageio/event/$(DEPDIR) javax/imageio/metadata/$(DEPDIR) javax/imageio/spi/$(DEPDIR) javax/imageio/stream/$(DEPDIR) javax/naming/$(DEPDIR) javax/naming/directory/$(DEPDIR) javax/naming/event/$(DEPDIR) javax/naming/ldap/$(DEPDIR) javax/naming/spi/$(DEPDIR) javax/net/$(DEPDIR) javax/net/ssl/$(DEPDIR) javax/print/$(DEPDIR) javax/print/attribute/$(DEPDIR) javax/print/attribute/standard/$(DEPDIR) javax/print/event/$(DEPDIR) javax/security/auth/$(DEPDIR) javax/security/auth/callback/$(DEPDIR) javax/security/auth/login/$(DEPDIR) javax/security/auth/x500/$(DEPDIR) javax/security/cert/$(DEPDIR) javax/security/sasl/$(DEPDIR) javax/sql/$(DEPDIR) javax/swing/$(DEPDIR) javax/swing/border/$(DEPDIR) javax/swing/colorchooser/$(DEPDIR) javax/swing/event/$(DEPDIR) javax/swing/filechooser/$(DEPDIR) javax/swing/plaf/$(DEPDIR) javax/swing/plaf/basic/$(DEPDIR) javax/swing/plaf/metal/$(DEPDIR) javax/swing/table/$(DEPDIR) javax/swing/text/$(DEPDIR) javax/swing/text/html/$(DEPDIR) javax/swing/text/html/parser/$(DEPDIR) javax/swing/tree/$(DEPDIR) javax/swing/undo/$(DEPDIR) javax/transaction/$(DEPDIR) javax/transaction/xa/$(DEPDIR) jni/classpath/$(DEPDIR) jni/gtk-peer/$(DEPDIR) org/ietf/jgss/$(DEPDIR) org/w3c/dom/$(DEPDIR) org/w3c/dom/ranges/$(DEPDIR) org/w3c/dom/traversal/$(DEPDIR) org/xml/sax/$(DEPDIR) org/xml/sax/ext/$(DEPDIR) org/xml/sax/helpers/$(DEPDIR) sysdep/$(DEPDIR)
+       -rm -rf ./$(DEPDIR) gnu/awt/$(DEPDIR) gnu/awt/j2d/$(DEPDIR) gnu/awt/xlib/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/awt/$(DEPDIR) gnu/java/awt/image/$(DEPDIR) gnu/java/awt/peer/$(DEPDIR) gnu/java/awt/peer/gtk/$(DEPDIR) gnu/java/beans/$(DEPDIR) gnu/java/beans/editors/$(DEPDIR) gnu/java/beans/info/$(DEPDIR) gnu/java/io/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/lang/reflect/$(DEPDIR) gnu/java/locale/$(DEPDIR) gnu/java/math/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/net/protocol/file/$(DEPDIR) gnu/java/net/protocol/gcjlib/$(DEPDIR) gnu/java/net/protocol/http/$(DEPDIR) gnu/java/net/protocol/jar/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) gnu/java/nio/charset/$(DEPDIR) gnu/java/rmi/$(DEPDIR) gnu/java/rmi/dgc/$(DEPDIR) gnu/java/rmi/registry/$(DEPDIR) gnu/java/rmi/rmic/$(DEPDIR) gnu/java/rmi/server/$(DEPDIR) gnu/java/security/$(DEPDIR) gnu/java/security/action/$(DEPDIR) gnu/java/security/der/$(DEPDIR) gnu/java/security/provider/$(DEPDIR) gnu/java/security/util/$(DEPDIR) gnu/java/security/x509/$(DEPDIR) gnu/java/security/x509/ext/$(DEPDIR) gnu/java/text/$(DEPDIR) gnu/java/util/$(DEPDIR) gnu/java/util/prefs/$(DEPDIR) gnu/regexp/$(DEPDIR) java/applet/$(DEPDIR) java/awt/$(DEPDIR) java/awt/color/$(DEPDIR) java/awt/datatransfer/$(DEPDIR) java/awt/dnd/$(DEPDIR) java/awt/dnd/peer/$(DEPDIR) java/awt/event/$(DEPDIR) java/awt/font/$(DEPDIR) java/awt/geom/$(DEPDIR) java/awt/im/$(DEPDIR) java/awt/im/spi/$(DEPDIR) java/awt/image/$(DEPDIR) java/awt/image/renderable/$(DEPDIR) java/awt/peer/$(DEPDIR) java/awt/print/$(DEPDIR) java/beans/$(DEPDIR) java/beans/beancontext/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/math/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/nio/channels/spi/$(DEPDIR) java/nio/charset/$(DEPDIR) java/nio/charset/spi/$(DEPDIR) java/rmi/$(DEPDIR) java/rmi/activation/$(DEPDIR) java/rmi/dgc/$(DEPDIR) java/rmi/registry/$(DEPDIR) java/rmi/server/$(DEPDIR) java/security/$(DEPDIR) java/security/acl/$(DEPDIR) java/security/cert/$(DEPDIR) java/security/interfaces/$(DEPDIR) java/security/spec/$(DEPDIR) java/sql/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/jar/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/prefs/$(DEPDIR) java/util/regex/$(DEPDIR) java/util/zip/$(DEPDIR) javax/accessibility/$(DEPDIR) javax/crypto/$(DEPDIR) javax/crypto/interfaces/$(DEPDIR) javax/crypto/spec/$(DEPDIR) javax/imageio/$(DEPDIR) javax/imageio/event/$(DEPDIR) javax/imageio/metadata/$(DEPDIR) javax/imageio/spi/$(DEPDIR) javax/imageio/stream/$(DEPDIR) javax/naming/$(DEPDIR) javax/naming/directory/$(DEPDIR) javax/naming/event/$(DEPDIR) javax/naming/ldap/$(DEPDIR) javax/naming/spi/$(DEPDIR) javax/net/$(DEPDIR) javax/net/ssl/$(DEPDIR) javax/print/$(DEPDIR) javax/print/attribute/$(DEPDIR) javax/print/attribute/standard/$(DEPDIR) javax/print/event/$(DEPDIR) javax/security/auth/$(DEPDIR) javax/security/auth/callback/$(DEPDIR) javax/security/auth/login/$(DEPDIR) javax/security/auth/x500/$(DEPDIR) javax/security/cert/$(DEPDIR) javax/security/sasl/$(DEPDIR) javax/sql/$(DEPDIR) javax/swing/$(DEPDIR) javax/swing/border/$(DEPDIR) javax/swing/colorchooser/$(DEPDIR) javax/swing/event/$(DEPDIR) javax/swing/filechooser/$(DEPDIR) javax/swing/plaf/$(DEPDIR) javax/swing/plaf/basic/$(DEPDIR) javax/swing/plaf/metal/$(DEPDIR) javax/swing/table/$(DEPDIR) javax/swing/text/$(DEPDIR) javax/swing/text/html/$(DEPDIR) javax/swing/text/html/parser/$(DEPDIR) javax/swing/tree/$(DEPDIR) javax/swing/undo/$(DEPDIR) javax/transaction/$(DEPDIR) javax/transaction/xa/$(DEPDIR) jni/classpath/$(DEPDIR) jni/gtk-peer/$(DEPDIR) org/ietf/jgss/$(DEPDIR) org/w3c/dom/$(DEPDIR) org/w3c/dom/ranges/$(DEPDIR) org/w3c/dom/traversal/$(DEPDIR) org/xml/sax/$(DEPDIR) org/xml/sax/ext/$(DEPDIR) org/xml/sax/helpers/$(DEPDIR) sysdep/$(DEPDIR)
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/libjava/gnu/java/security/provider/CollectionCertStoreImpl.java b/libjava/gnu/java/security/provider/CollectionCertStoreImpl.java
new file mode 100644 (file)
index 0000000..1b22cc8
--- /dev/null
@@ -0,0 +1,103 @@
+/* CollectionCertStore.java -- Collection-based cert store.
+   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.provider;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.cert.Certificate;
+import java.security.cert.CertSelector;
+import java.security.cert.CRL;
+import java.security.cert.CRLSelector;
+import java.security.cert.CertStoreException;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertStoreSpi;
+import java.security.cert.CollectionCertStoreParameters;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+public final class CollectionCertStoreImpl extends CertStoreSpi
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final Collection store;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  public CollectionCertStoreImpl(CertStoreParameters params)
+    throws InvalidAlgorithmParameterException
+  {
+    super(params);
+    if (! (params instanceof CollectionCertStoreParameters))
+      throw new InvalidAlgorithmParameterException("not a CollectionCertStoreParameters object");
+    store = ((CollectionCertStoreParameters) params).getCollection();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public Collection engineGetCertificates(CertSelector selector)
+    throws CertStoreException
+  {
+    LinkedList result = new LinkedList();
+    for (Iterator it = store.iterator(); it.hasNext(); )
+      {
+        Object o = it.next();
+        if ((o instanceof Certificate) && selector.match((Certificate) o))
+          result.add(o);
+      }
+    return result;
+  }
+
+  public Collection engineGetCRLs(CRLSelector selector)
+    throws CertStoreException
+  {
+    LinkedList result = new LinkedList();
+    for (Iterator it = store.iterator(); it.hasNext(); )
+      {
+        Object o = it.next();
+        if ((o instanceof CRL) && selector.match((CRL) o))
+          result.add(o);
+      }
+    return result;
+  }
+}
diff --git a/libjava/gnu/java/security/provider/EncodedKeyFactory.java b/libjava/gnu/java/security/provider/EncodedKeyFactory.java
new file mode 100644 (file)
index 0000000..e308d44
--- /dev/null
@@ -0,0 +1,310 @@
+/* EncodedKeyFactory.java -- encoded key factory.
+   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.provider;
+
+import java.io.IOException;
+
+import java.math.BigInteger;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyFactorySpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import javax.crypto.spec.DHParameterSpec;
+
+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;
+
+/**
+ * A factory for keys encoded in either the X.509 format (for public
+ * keys) or the PKCS#8 format (for private keys).
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class EncodedKeyFactory extends KeyFactorySpi
+{
+
+  // Constants.
+  // ------------------------------------------------------------------------
+
+  private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
+  private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
+  private static final OID ID_DH  = new OID("1.2.840.10046.2.1");
+
+  // Instance methods.
+  // ------------------------------------------------------------------------
+
+  public PublicKey engineGeneratePublic(KeySpec spec)
+    throws InvalidKeySpecException
+  {
+    if (!(spec instanceof X509EncodedKeySpec))
+      throw new InvalidKeySpecException("only supports X.509 key specs");
+    DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded());
+    try
+      {
+        DERValue spki = der.read();
+        if (!spki.isConstructed())
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        DERValue alg = der.read();
+        if (!alg.isConstructed())
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        DERValue val = der.read();
+        if (!(val.getValue() instanceof OID))
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        OID algId = (OID) val.getValue();
+        byte[] algParams = null;
+        if (alg.getLength() > val.getEncodedLength())
+          {
+            val = der.read();
+            algParams = val.getEncoded();
+            if (val.isConstructed())
+              der.skip(val.getLength());
+          }
+        val = der.read();
+        if (!(val.getValue() instanceof BitString))
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        byte[] publicKey = ((BitString) val.getValue()).toByteArray();
+        if (algId.equals(ID_DSA))
+          {
+            BigInteger p = null, g = null, q = null, Y;
+            if (algParams != null)
+              {
+                DERReader dsaParams = new DERReader(algParams);
+                val = dsaParams.read();
+                if (!val.isConstructed())
+                  throw new InvalidKeySpecException("malformed DSA parameters");
+                val = dsaParams.read();
+                if (!(val.getValue() instanceof BigInteger))
+                  throw new InvalidKeySpecException("malformed DSA parameters");
+                p = (BigInteger) val.getValue();
+                val = dsaParams.read();
+                if (!(val.getValue() instanceof BigInteger))
+                  throw new InvalidKeySpecException("malformed DSA parameters");
+                q = (BigInteger) val.getValue();
+                val = dsaParams.read();
+                if (!(val.getValue() instanceof BigInteger))
+                  throw new InvalidKeySpecException("malformed DSA parameters");
+                g = (BigInteger) val.getValue();
+              }
+            DERReader dsaPub = new DERReader(publicKey);
+            val = dsaPub.read();
+            if (!(val.getValue() instanceof BigInteger))
+              throw new InvalidKeySpecException("malformed DSA parameters");
+            Y = (BigInteger) val.getValue();
+            return new GnuDSAPublicKey(Y, p, q, g);
+          }
+        else if (algId.equals(ID_RSA))
+          {
+            DERReader rsaParams = new DERReader(publicKey);
+            if (!rsaParams.read().isConstructed())
+              {
+                throw new InvalidKeySpecException("malformed encoded key");
+              }
+            return new GnuRSAPublicKey(new RSAPublicKeySpec(
+              (BigInteger) rsaParams.read().getValue(),
+              (BigInteger) rsaParams.read().getValue()));
+          }
+        else if (algId.equals(ID_DH))
+          {
+            if (algParams == null)
+              throw new InvalidKeySpecException("missing DH parameters");
+            DERReader dhParams = new DERReader(algParams);
+            val = dhParams.read();
+            BigInteger p, g, q, Y;
+            if (!val.isConstructed())
+              throw new InvalidKeySpecException("malformed DH parameters");
+            val = dhParams.read();
+            if (!(val.getValue() instanceof BigInteger))
+              throw new InvalidKeySpecException("malformed DH parameters");
+            p = (BigInteger) val.getValue();
+            val = dhParams.read();
+            if (!(val.getValue() instanceof BigInteger))
+              throw new InvalidKeySpecException("malformed DH parameters");
+            g = (BigInteger) val.getValue();
+            val = dhParams.read();
+            if (!(val.getValue() instanceof BigInteger))
+              throw new InvalidKeySpecException("malformed DH parameters");
+            q = (BigInteger) val.getValue();
+            DERReader dhPub = new DERReader(publicKey);
+            val = dhPub.read();
+            if (!(val.getValue() instanceof BigInteger))
+              throw new InvalidKeySpecException("malformed DH parameters");
+            Y = (BigInteger) val.getValue();
+            return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q);
+          }
+        else
+          throw new InvalidKeySpecException("unknown algorithm: " + algId);
+      }
+    catch (IOException ioe)
+      {
+        throw new InvalidKeySpecException(ioe.getMessage());
+      }
+  }
+
+  public PrivateKey engineGeneratePrivate(KeySpec spec)
+    throws InvalidKeySpecException
+  {
+    if (!(spec instanceof PKCS8EncodedKeySpec))
+      {
+        throw new InvalidKeySpecException("only supports PKCS8 key specs");
+      }
+    DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded());
+    try
+      {
+        DERValue pki = der.read();
+        if (!pki.isConstructed())
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        DERValue val = der.read();
+        if (!(val.getValue() instanceof BigInteger))
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        DERValue alg = der.read();
+        if (!alg.isConstructed())
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        val = der.read();
+        if (!(val.getValue() instanceof OID))
+          {
+            throw new InvalidKeySpecException("malformed encoded key");
+          }
+        OID algId = (OID) val.getValue();
+        byte[] algParams = null;
+        if (alg.getLength() > val.getEncodedLength())
+          {
+            val = der.read();
+            algParams = val.getEncoded();
+            if (val.isConstructed())
+              der.skip(val.getLength());
+          }
+        byte[] privateKey = (byte[]) der.read().getValue();
+        if (algId.equals(ID_DSA))
+          {
+            if (algParams == null)
+              {
+                throw new InvalidKeySpecException("missing DSA parameters");
+              }
+            AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
+            params.init(algParams);
+            DSAParameterSpec dsaSpec = (DSAParameterSpec)
+              params.getParameterSpec(DSAParameterSpec.class);
+            DERReader dsaPriv = new DERReader(privateKey);
+            return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(),
+              dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG());
+          }
+        else if (algId.equals(ID_RSA))
+          {
+            DERReader rsaParams = new DERReader(privateKey);
+            if (!rsaParams.read().isConstructed())
+              throw new InvalidKeySpecException("malformed encoded key");
+            return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
+              (BigInteger) rsaParams.read().getValue(), // n
+              (BigInteger) rsaParams.read().getValue(), // e
+              (BigInteger) rsaParams.read().getValue(), // d
+              (BigInteger) rsaParams.read().getValue(), // p
+              (BigInteger) rsaParams.read().getValue(), // q
+              (BigInteger) rsaParams.read().getValue(), // d mod (p - 1)
+              (BigInteger) rsaParams.read().getValue(), // d mod (q - 1)
+              (BigInteger) rsaParams.read().getValue())); // (inv q) mod p
+          }
+        else
+          throw new InvalidKeySpecException("unknown algorithm: " + algId);
+      }
+    catch (InvalidParameterSpecException iapse)
+      {
+        throw new InvalidKeySpecException(iapse.getMessage());
+      }
+    catch (NoSuchAlgorithmException nsae)
+      {
+        throw new InvalidKeySpecException(nsae.getMessage());
+      }
+    catch (IOException ioe)
+      {
+        throw new InvalidKeySpecException(ioe.getMessage());
+      }
+  }
+
+  public KeySpec engineGetKeySpec(Key key, Class speClass)
+    throws InvalidKeySpecException
+  {
+    if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")
+        && speClass.isAssignableFrom(PKCS8EncodedKeySpec.class))
+      return new PKCS8EncodedKeySpec(key.getEncoded());
+    else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")
+        && speClass.isAssignableFrom(X509EncodedKeySpec.class))
+      return new X509EncodedKeySpec(key.getEncoded());
+    else
+      throw new InvalidKeySpecException();
+  }
+
+  public Key engineTranslateKey(Key key) throws InvalidKeyException
+  {
+    throw new InvalidKeyException("translating keys not supported");
+  }
+}
index 70a7d1df15ec8cf204be91ed3a621a3d0b5fd8c9..02f509dc2d58625e9cb8f44ca8e4dc1ccfecc3dd 100644 (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
@@ -37,75 +37,131 @@ exception statement from your version. */
 
 
 package gnu.java.security.provider;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.security.Provider;
 
 public final class Gnu extends Provider
 {
   public Gnu()
   {
-    super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, X.509 Certificates");
-
-    // Note that all implementation class names are referenced by using
-    // Class.getName(). That way when we staticly link the Gnu provider
-    // we automatically get all the implementation classes.
-
-    // Signature
-    put("Signature.SHA1withDSA",
-        gnu.java.security.provider.DSASignature.class.getName());
-
-    put("Alg.Alias.Signature.DSS", "SHA1withDSA");
-    put("Alg.Alias.Signature.DSA", "SHA1withDSA");
-    put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
-    put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA");
-    put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA");
-    put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
-    put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
-    put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
-    put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA");
-    put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
-    put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
-    put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
-
-    // Key Pair Generator
-    put("KeyPairGenerator.DSA",
-        gnu.java.security.provider.DSAKeyPairGenerator.class.getName());
-
-    put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
-    put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
-    put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
-
-    // Key Factory
-    put("KeyFactory.DSA",
-        gnu.java.security.provider.DSAKeyFactory.class.getName());
-
-    put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
-    put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
-    put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
-
-    // Message Digests
-    put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName());
-    put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName());
-
-    // Format "Alias", "Actual Name"
-    put("Alg.Alias.MessageDigest.SHA1", "SHA");
-    put("Alg.Alias.MessageDigest.SHA-1", "SHA");
-
-    // Algorithm Parameters
-    put("AlgorithmParameters.DSA",
-        gnu.java.security.provider.DSAParameters.class.getName());
-
-    // Algorithm Parameter Generator
-    put("AlgorithmParameterGenerator.DSA",
-        gnu.java.security.provider.DSAParameterGenerator.class.getName());
-
-    // SecureRandom
-    put("SecureRandom.SHA1PRNG",
-        gnu.java.security.provider.SHA1PRNG.class.getName());
-
-    // CertificateFactory
-    put("CertificateFactory.X.509",
-        gnu.java.security.provider.X509CertificateFactory.class.getName());
-
-    put("Alg.Alias.CertificateFactory.X509", "X.509");
+    super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 Certificates and CRLs, PKIX certificate path validators, Collection cert stores");
+
+    AccessController.doPrivileged (new PrivilegedAction()
+    {
+      public Object run()
+      {
+        // Note that all implementation class names are referenced by using
+        // Class.getName(). That way when we staticly link the Gnu provider
+        // we automatically get all the implementation classes.
+
+        // Signature
+        put("Signature.SHA1withDSA",
+            gnu.java.security.provider.DSASignature.class.getName());
+
+        put("Alg.Alias.Signature.DSS", "SHA1withDSA");
+        put("Alg.Alias.Signature.DSA", "SHA1withDSA");
+        put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
+        put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA");
+        put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA");
+        put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
+        put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
+        put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
+        put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA");
+        put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
+        put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
+        put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
+
+        put("Signature.MD2withRSA", MD2withRSA.class.getName());
+        put("Signature.MD2withRSA ImplementedIn", "Software");
+        put("Alg.Alias.Signature.md2WithRSAEncryption", "MD2withRSA");
+        put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", "MD2withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA");
+
+        put("Signature.MD4withRSA", MD4withRSA.class.getName());
+        put("Signature.MD4withRSA ImplementedIn", "Software");
+        put("Alg.Alias.Signature.md4WithRSAEncryption", "MD4withRSA");
+        put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.3", "MD4withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.3", "MD4withRSA");
+
+        put("Signature.MD5withRSA", MD5withRSA.class.getName());
+        put("Signature.MD5withRSA ImplementedIn", "Software");
+        put("Alg.Alias.Signature.md5WithRSAEncryption", "MD5withRSA");
+        put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
+
+        put("Signature.SHA1withRSA", SHA1withRSA.class.getName());
+        put("Signature.SHA1withRSA ImplementedIn", "Software");
+        put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA1withRSA");
+        put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
+
+        // Key Pair Generator
+        put("KeyPairGenerator.DSA",
+            gnu.java.security.provider.DSAKeyPairGenerator.class.getName());
+
+        put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
+        put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
+        put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
+
+        // Key Factory
+        put("KeyFactory.DSA",
+            gnu.java.security.provider.DSAKeyFactory.class.getName());
+
+        put("KeyFactory.Encoded", EncodedKeyFactory.class.getName());
+        put("KeyFactory.Encoded ImplementedIn", "Software");
+        put("Alg.Alias.KeyFactory.X.509", "Encoded");
+        put("Alg.Alias.KeyFactory.X509", "Encoded");
+        put("Alg.Alias.KeyFactory.PKCS#8", "Encoded");
+        put("Alg.Alias.KeyFactory.PKCS8", "Encoded");
+
+        put("KeyFactory.RSA", RSAKeyFactory.class.getName());
+
+        put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
+        put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
+        put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
+
+        // Message Digests
+        put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName());
+        put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName());
+
+        // Format "Alias", "Actual Name"
+        put("Alg.Alias.MessageDigest.SHA1", "SHA");
+        put("Alg.Alias.MessageDigest.SHA-1", "SHA");
+
+        // Algorithm Parameters
+        put("AlgorithmParameters.DSA",
+            gnu.java.security.provider.DSAParameters.class.getName());
+
+        put("Alg.Alias.AlgorithmParameters.DSS", "DSA");
+        put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSA");
+        put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSA");
+        put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSA");
+
+        // Algorithm Parameter Generator
+        put("AlgorithmParameterGenerator.DSA",
+            gnu.java.security.provider.DSAParameterGenerator.class.getName());
+
+        // SecureRandom
+        put("SecureRandom.SHA1PRNG",
+            gnu.java.security.provider.SHA1PRNG.class.getName());
+
+        // CertificateFactory
+        put("CertificateFactory.X509", X509CertificateFactory.class.getName());
+
+        put("CertificateFactory.X509 ImplementedIn", "Software");
+        put("Alg.Alias.CertificateFactory.X.509", "X509");
+
+        // CertPathValidator
+        put("CertPathValidator.PKIX", PKIXCertPathValidatorImpl.class.getName());
+        put("CertPathValidator.PKIX ImplementedIn", "Software");
+
+        // CertStore
+        put("CertStore.Collection", CollectionCertStoreImpl.class.getName());
+
+        return null;
+      }
+    });
   }
 }
diff --git a/libjava/gnu/java/security/provider/GnuDHPublicKey.java b/libjava/gnu/java/security/provider/GnuDHPublicKey.java
new file mode 100644 (file)
index 0000000..a650761
--- /dev/null
@@ -0,0 +1,117 @@
+/* GnuDHPublicKey.java -- A Diffie-Hellman public key.
+   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.provider;
+
+import java.math.BigInteger;
+
+import java.util.ArrayList;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+
+import gnu.java.security.OID;
+import gnu.java.security.der.BitString;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+import gnu.java.security.der.DERWriter;
+
+public class GnuDHPublicKey implements DHPublicKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private byte[] encoded;
+  private final DHParameterSpec params;
+  private final BigInteger Y;
+  private final BigInteger q;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q)
+  {
+    this.params = params;
+    this.Y = Y;
+    this.q = q;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public BigInteger getY()
+  {
+    return Y;
+  }
+
+  public DHParameterSpec getParams()
+  {
+    return params;
+  }
+
+  public String getAlgorithm()
+  {
+    return "DH";
+  }
+
+  public String getFormat()
+  {
+    return "X.509";
+  }
+
+  public byte[] getEncoded()
+  {
+    if (encoded != null)
+      return (byte[]) encoded.clone();
+    ArrayList spki = new ArrayList(2);
+    ArrayList alg = new ArrayList(2);
+    alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1")));
+    ArrayList param = new ArrayList(3);
+    param.add(new DERValue(DER.INTEGER, params.getP()));
+    param.add(new DERValue(DER.INTEGER, params.getG()));
+    param.add(new DERValue(DER.INTEGER, q));
+    alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param));
+    spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
+    spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray())));
+    encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded();
+    if (encoded != null)
+      return (byte[]) encoded.clone();
+    return null;
+  }
+}
diff --git a/libjava/gnu/java/security/provider/GnuRSAPrivateKey.java b/libjava/gnu/java/security/provider/GnuRSAPrivateKey.java
new file mode 100644 (file)
index 0000000..455326d
--- /dev/null
@@ -0,0 +1,166 @@
+/* GnuRSAPrivateKey.java -- GNU RSA private key.
+   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.provider;
+
+import java.math.BigInteger;
+
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.RSAPrivateCrtKeySpec;
+
+import java.util.ArrayList;
+
+import gnu.java.security.OID;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+
+class GnuRSAPrivateKey implements RSAPrivateCrtKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final RSAPrivateCrtKeySpec spec;
+  private byte[] encodedKey;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public GnuRSAPrivateKey(RSAPrivateCrtKeySpec spec)
+  {
+    this.spec = spec;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public BigInteger getModulus()
+  {
+    return spec.getModulus();
+  }
+
+  public BigInteger getPrivateExponent()
+  {
+    return spec.getPrivateExponent();
+  }
+
+  public BigInteger getCrtCoefficient()
+  {
+    return spec.getCrtCoefficient();
+  }
+
+  public BigInteger getPrimeExponentP()
+  {
+    return spec.getPrimeExponentP();
+  }
+
+  public BigInteger getPrimeExponentQ()
+  {
+    return spec.getPrimeExponentQ();
+  }
+
+  public BigInteger getPrimeP()
+  {
+    return spec.getPrimeP();
+  }
+
+  public BigInteger getPrimeQ()
+  {
+    return spec.getPrimeQ();
+  }
+
+  public BigInteger getPublicExponent()
+  {
+    return spec.getPublicExponent();
+  }
+
+  public String getAlgorithm()
+  {
+    return "RSA";
+  }
+
+  public String getFormat()
+  {
+    return "PKCS#8";
+  }
+
+  /**
+   * The encoded form is:
+   *
+   * <pre>
+   * RSAPrivateKey ::= SEQUENCE {
+   *   version Version,
+   *   modulus INTEGER, -- n
+   *   publicExponent INTEGER, -- e
+   *   privateExponent INTEGER, -- d
+   *   prime1 INTEGER, -- p
+   *   prime2 INTEGER, -- q
+   *   exponent1 INTEGER, -- d mod (p-1)
+   *   exponent2 INTEGER, -- d mod (q-1)
+   *   coefficient INTEGER -- (inverse of q) mod p }
+   * </pre>
+   *
+   * <p>Which is in turn encoded in a PrivateKeyInfo structure from PKCS#8.
+   */
+  public byte[] getEncoded()
+  {
+    if (encodedKey != null)
+      return (byte[]) encodedKey.clone();
+    ArrayList key = new ArrayList(9);
+    key.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
+    key.add(new DERValue(DER.INTEGER, getModulus()));
+    key.add(new DERValue(DER.INTEGER, getPublicExponent()));
+    key.add(new DERValue(DER.INTEGER, getPrivateExponent()));
+    key.add(new DERValue(DER.INTEGER, getPrimeP()));
+    key.add(new DERValue(DER.INTEGER, getPrimeQ()));
+    key.add(new DERValue(DER.INTEGER, getPrimeExponentP()));
+    key.add(new DERValue(DER.INTEGER, getPrimeExponentQ()));
+    key.add(new DERValue(DER.INTEGER, getCrtCoefficient()));
+    DERValue pk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key);
+    ArrayList pki = new ArrayList(3);
+    pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
+    ArrayList alg = new ArrayList(2);
+    alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
+                         new OID("1.2.840.113549.1.1.1")));
+    alg.add(new DERValue(DER.NULL, null));
+    pki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
+    pki.add(new DERValue(DER.OCTET_STRING, pk.getEncoded()));
+    encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, pki).getEncoded();
+    return (byte[]) encodedKey.clone();
+  }
+}
diff --git a/libjava/gnu/java/security/provider/GnuRSAPublicKey.java b/libjava/gnu/java/security/provider/GnuRSAPublicKey.java
new file mode 100644 (file)
index 0000000..502fccc
--- /dev/null
@@ -0,0 +1,109 @@
+/* GnuRSAPublicKey.java -- GNU RSA public key.
+   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.provider;
+
+import java.math.BigInteger;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.ArrayList;
+
+import gnu.java.security.OID;
+import gnu.java.security.der.BitString;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+
+class GnuRSAPublicKey implements RSAPublicKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final RSAPublicKeySpec spec;
+  private byte[] encodedKey;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public GnuRSAPublicKey(RSAPublicKeySpec spec)
+  {
+    this.spec = spec;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public BigInteger getModulus()
+  {
+    return spec.getModulus();
+  }
+
+  public BigInteger getPublicExponent()
+  {
+    return spec.getPublicExponent();
+  }
+
+  public String getAlgorithm()
+  {
+    return "RSA";
+  }
+
+  public String getFormat()
+  {
+    return "X.509";
+  }
+
+  public byte[] getEncoded()
+  {
+    if (encodedKey != null)
+      return (byte[]) encodedKey.clone();
+    ArrayList key = new ArrayList(2);
+    key.add(new DERValue(DER.INTEGER, getModulus()));
+    key.add(new DERValue(DER.INTEGER, getPublicExponent()));
+    DERValue rsapk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key);
+    ArrayList alg = new ArrayList(2);
+    alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
+                         new OID("1.2.840.113549.1.1.1")));
+    alg.add(new DERValue(DER.NULL, null));
+    ArrayList spki = new ArrayList(2);
+    spki.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, alg));
+    spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded())));
+    encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, spki).getEncoded();
+    return (byte[]) encodedKey.clone();
+  }
+}
diff --git a/libjava/gnu/java/security/provider/MD2withRSA.java b/libjava/gnu/java/security/provider/MD2withRSA.java
new file mode 100644 (file)
index 0000000..c43d07a
--- /dev/null
@@ -0,0 +1,54 @@
+/* MD2withRSA.java -- MD2 with RSA encryption signatures.
+   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.provider;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD2withRSA extends RSA
+{
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public MD2withRSA() throws NoSuchAlgorithmException
+  {
+    super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2));
+  }
+}
diff --git a/libjava/gnu/java/security/provider/MD4withRSA.java b/libjava/gnu/java/security/provider/MD4withRSA.java
new file mode 100644 (file)
index 0000000..86cd2be
--- /dev/null
@@ -0,0 +1,54 @@
+/* MD4withRSA.java -- MD4 with RSA encryption signatures.
+   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.provider;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD4withRSA extends RSA
+{
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public MD4withRSA() throws NoSuchAlgorithmException
+  {
+    super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4));
+  }
+}
diff --git a/libjava/gnu/java/security/provider/MD5withRSA.java b/libjava/gnu/java/security/provider/MD5withRSA.java
new file mode 100644 (file)
index 0000000..ec8370d
--- /dev/null
@@ -0,0 +1,54 @@
+/* MD5withRSA.java -- MD5 with RSA encryption signatures.
+   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.provider;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD5withRSA extends RSA
+{
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public MD5withRSA() throws NoSuchAlgorithmException
+  {
+    super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5));
+  }
+}
diff --git a/libjava/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/libjava/gnu/java/security/provider/PKIXCertPathValidatorImpl.java
new file mode 100644 (file)
index 0000000..7d1d857
--- /dev/null
@@ -0,0 +1,689 @@
+/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator.
+   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.provider;
+
+import java.io.IOException;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Principal;
+import java.security.PublicKey;
+
+import java.security.cert.*;
+
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAParameterSpec;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import gnu.java.security.x509.GnuPKIExtension;
+import gnu.java.security.x509.PolicyNodeImpl;
+import gnu.java.security.x509.X509CertSelectorImpl;
+import gnu.java.security.x509.X509CRLSelectorImpl;
+import gnu.java.security.x509.ext.*;
+import gnu.java.security.OID;
+
+/**
+ * An implementation of the Public Key Infrastructure's X.509
+ * certificate path validation algorithm.
+ *
+ * <p>See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Internet X.509 Public Key Infrastructure Certificate and
+ * Certificate Revocation List (CRL) Profile</a>.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
+{
+
+  // Constants.
+  // -------------------------------------------------------------------------
+
+  private static final boolean DEBUG = false;
+  private static void debug (String msg)
+  {
+    System.err.print (">> PKIXCertPathValidatorImpl: ");
+    System.err.println (msg);
+  }
+
+  public static final String ANY_POLICY = "2.5.29.32.0";
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public PKIXCertPathValidatorImpl()
+  {
+    super();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public CertPathValidatorResult engineValidate(CertPath path,
+                                                CertPathParameters params)
+    throws CertPathValidatorException, InvalidAlgorithmParameterException
+  {
+    if (!(params instanceof PKIXParameters))
+      throw new InvalidAlgorithmParameterException("not a PKIXParameters object");
+
+    // First check if the certificate path is valid.
+    //
+    // This means that:
+    //
+    //   (a)  for all x in {1, ..., n-1}, the subject of certificate x is
+    //        the issuer of certificate x+1;
+    //
+    //   (b)  for all x in {1, ..., n}, the certificate was valid at the
+    //        time in question.
+    //
+    // Because this is the X.509 algorithm, we also check if all
+    // cerificates are of type X509Certificate.
+
+    PolicyNodeImpl rootNode = new PolicyNodeImpl();
+    Set initPolicies = ((PKIXParameters) params).getInitialPolicies();
+    rootNode.setValidPolicy(ANY_POLICY);
+    rootNode.setCritical(false);
+    rootNode.setDepth(0);
+    if (initPolicies != null)
+      rootNode.addAllExpectedPolicies(initPolicies);
+    else
+      rootNode.addExpectedPolicy(ANY_POLICY);
+    List checks = ((PKIXParameters) params).getCertPathCheckers();
+    List l = path.getCertificates();
+    if (l == null || l.size() == 0)
+      throw new CertPathValidatorException();
+    X509Certificate[] p = null;
+    try
+      {
+        p = (X509Certificate[]) l.toArray(new X509Certificate[l.size()]);
+      }
+    catch (ClassCastException cce)
+      {
+        throw new CertPathValidatorException("invalid certificate path");
+      }
+
+    String sigProvider = ((PKIXParameters) params).getSigProvider();
+    PublicKey prevKey = null;
+    Date now = ((PKIXParameters) params).getDate();
+    if (now == null)
+      now = new Date();
+    LinkedList policyConstraints = new LinkedList();
+    for (int i = p.length - 1; i >= 0; i--)
+      {
+        try
+          {
+            p[i].checkValidity(now);
+          }
+        catch (CertificateException ce)
+          {
+            throw new CertPathValidatorException(ce.toString());
+          }
+        Set uce = getCritExts(p[i]);
+        for (Iterator check = checks.iterator(); check.hasNext(); )
+          {
+            try
+              {
+                ((PKIXCertPathChecker) check.next()).check(p[i], uce);
+              }
+            catch (Exception x)
+              {
+              }
+          }
+
+        PolicyConstraint constr = null;
+        if (p[i] instanceof GnuPKIExtension)
+          {
+            Extension pcx =
+              ((GnuPKIExtension) p[i]).getExtension (PolicyConstraint.ID);
+            if (pcx != null)
+              constr = (PolicyConstraint) pcx.getValue();
+          }
+        else
+          {
+            byte[] pcx = p[i].getExtensionValue (PolicyConstraint.ID.toString());
+            if (pcx != null)
+              {
+                try
+                  {
+                    constr = new PolicyConstraint (pcx);
+                  }
+                catch (Exception x)
+                  {
+                  }
+              }
+          }
+        if (constr != null && constr.getRequireExplicitPolicy() >= 0)
+          {
+            policyConstraints.add (new int[]
+              { p.length-i, constr.getRequireExplicitPolicy() });
+          }
+
+        updatePolicyTree(p[i], rootNode, p.length-i, (PKIXParameters) params,
+                         checkExplicitPolicy (p.length-i, policyConstraints));
+
+        // The rest of the tests involve this cert's relationship with the
+        // next in the path. If this cert is the end entity, we can stop.
+        if (i == 0)
+          break;
+
+        basicSanity(p, i);
+        PublicKey pubKey = null;
+        try
+          {
+            pubKey = p[i].getPublicKey();
+            if (pubKey instanceof DSAPublicKey)
+              {
+                DSAParams dsa = ((DSAPublicKey) pubKey).getParams();
+                // If the DSA public key is missing its parameters, use those
+                // from the previous cert's key.
+                if (dsa == null || dsa.getP() == null || dsa.getG() == null
+                      || dsa.getQ() == null)
+                  {
+                    if (prevKey == null)
+                      throw new InvalidKeyException("DSA keys not chainable");
+                    if (!(prevKey instanceof DSAPublicKey))
+                      throw new InvalidKeyException("DSA keys not chainable");
+                    dsa = ((DSAPublicKey) prevKey).getParams();
+                    pubKey = new GnuDSAPublicKey(((DSAPublicKey) pubKey).getY(),
+                      dsa.getP(), dsa.getQ(), dsa.getG());
+                  }
+              }
+            if (sigProvider == null)
+              p[i-1].verify(pubKey);
+            else
+              p[i-1].verify(pubKey, sigProvider);
+            prevKey = pubKey;
+          }
+        catch (Exception e)
+          {
+            throw new CertPathValidatorException(e.toString());
+          }
+        if (!p[i].getSubjectDN().equals(p[i-1].getIssuerDN()))
+          throw new CertPathValidatorException("issuer DN mismatch");
+        boolean[] issuerUid = p[i-1].getIssuerUniqueID();
+        boolean[] subjectUid = p[i].getSubjectUniqueID();
+        if (issuerUid != null && subjectUid != null)
+          if (!Arrays.equals(issuerUid, subjectUid))
+            throw new CertPathValidatorException("UID mismatch");
+
+        // Check the certificate against the revocation lists.
+        if (((PKIXParameters) params).isRevocationEnabled())
+          {
+            X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
+            try
+              {
+                selector.addIssuerName(p[i].getSubjectDN());
+              }
+            catch (IOException ioe)
+              {
+                throw new CertPathValidatorException("error selecting CRLs");
+              }
+            List certStores = ((PKIXParameters) params).getCertStores();
+            List crls = new LinkedList();
+            for (Iterator it = certStores.iterator(); it.hasNext(); )
+              {
+                CertStore cs = (CertStore) it.next();
+                try
+                  {
+                    Collection c = cs.getCRLs(selector);
+                    crls.addAll(c);
+                  }
+                catch (CertStoreException cse)
+                  {
+                  }
+              }
+            if (crls.isEmpty())
+              throw new CertPathValidatorException("no CRLs for issuer");
+            boolean certOk = false;
+            for (Iterator it = crls.iterator(); it.hasNext(); )
+              {
+                CRL crl = (CRL) it.next();
+                if (!(crl instanceof X509CRL))
+                  continue;
+                X509CRL xcrl = (X509CRL) crl;
+                if (!checkCRL(xcrl, p, now, p[i], pubKey, certStores))
+                  continue;
+                if (xcrl.isRevoked(p[i-1]))
+                  throw new CertPathValidatorException("certificate is revoked");
+                else
+                  certOk = true;
+              }
+            if (!certOk)
+              throw new CertPathValidatorException("certificate's validity could not be determined");
+          }
+      }
+    rootNode.setReadOnly();
+
+    // Now ensure that the first certificate in the chain was issued
+    // by a trust anchor.
+    Exception cause = null;
+    Set anchors = ((PKIXParameters) params).getTrustAnchors();
+    for (Iterator i = anchors.iterator(); i.hasNext(); )
+      {
+        TrustAnchor anchor = (TrustAnchor) i.next();
+        X509Certificate anchorCert = null;
+        PublicKey anchorKey = null;
+        if (anchor.getTrustedCert() != null)
+          {
+            anchorCert = anchor.getTrustedCert();
+            anchorKey = anchorCert.getPublicKey();
+          }
+        else
+          anchorKey = anchor.getCAPublicKey();
+        if (anchorKey == null)
+          continue;
+        try
+          {
+            if (anchorCert == null)
+              anchorCert.checkValidity(now);
+            p[p.length-1].verify(anchorKey);
+            if (anchorCert != null && anchorCert.getBasicConstraints() >= 0
+                && anchorCert.getBasicConstraints() < p.length)
+              continue;
+
+            if (((PKIXParameters) params).isRevocationEnabled())
+              {
+                X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
+                if (anchorCert != null)
+                  try
+                    {
+                      selector.addIssuerName(anchorCert.getSubjectDN());
+                    }
+                  catch (IOException ioe)
+                    {
+                    }
+                else
+                  selector.addIssuerName(anchor.getCAName());
+                List certStores = ((PKIXParameters) params).getCertStores();
+                List crls = new LinkedList();
+                for (Iterator it = certStores.iterator(); it.hasNext(); )
+                  {
+                    CertStore cs = (CertStore) it.next();
+                    try
+                      {
+                        Collection c = cs.getCRLs(selector);
+                        crls.addAll(c);
+                      }
+                    catch (CertStoreException cse)
+                      {
+                      }
+                  }
+                if (crls.isEmpty())
+                  continue;
+                for (Iterator it = crls.iterator(); it.hasNext(); )
+                  {
+                    CRL crl = (CRL) it.next();
+                    if (!(crl instanceof X509CRL))
+                      continue;
+                    X509CRL xcrl = (X509CRL) crl;
+                    try
+                      {
+                        xcrl.verify(anchorKey);
+                      }
+                    catch (Exception x)
+                      {
+                        continue;
+                      }
+                    Date nextUpdate = xcrl.getNextUpdate();
+                    if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
+                      continue;
+                    if (xcrl.isRevoked(p[p.length-1]))
+                      throw new CertPathValidatorException("certificate is revoked");
+                  }
+              }
+
+            // The chain is valid; return the result.
+            return new PKIXCertPathValidatorResult(anchor, rootNode,
+                                                   p[0].getPublicKey());
+          }
+        catch (Exception ignored)
+          {
+            cause = ignored;
+            continue;
+          }
+      }
+
+    // The path is not valid.
+    CertPathValidatorException cpve =
+      new CertPathValidatorException("path validation failed");
+    if (cause != null)
+      cpve.initCause (cause);
+    throw cpve;
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Check if a given CRL is acceptable for checking the revocation status
+   * of certificates in the path being checked.
+   *
+   * <p>The CRL is accepted iff:</p>
+   *
+   * <ol>
+   * <li>The <i>nextUpdate</i> field (if present) is in the future.</li>
+   * <li>The CRL does not contain any unsupported critical extensions.</li>
+   * <li>The CRL is signed by one of the certificates in the path, or,</li>
+   * <li>The CRL is signed by the given public key and was issued by the
+   * public key's subject, or,</li>
+   * <li>The CRL is signed by a certificate in the given cert stores, and
+   * that cert is signed by one of the certificates in the path.</li>
+   * </ol>
+   *
+   * @param crl The CRL being checked.
+   * @param path The path this CRL is being checked against.
+   * @param now The value to use as 'now'.
+   * @param pubKeySubject The subject of the public key.
+   * @param pubKey The public key to check.
+   * @return True if the CRL is acceptable.
+   */
+  private static boolean checkCRL(X509CRL crl, X509Certificate[] path, Date now,
+                                  X509Certificate pubKeyCert, PublicKey pubKey,
+                                  List certStores)
+  {
+    Date nextUpdate = crl.getNextUpdate();
+    if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
+      return false;
+    if (crl.hasUnsupportedCriticalExtension())
+      return false;
+    for (int i = 0; i < path.length; i++)
+      {
+        if (!path[i].getSubjectDN().equals(crl.getIssuerDN()))
+          continue;
+        boolean[] keyUsage = path[i].getKeyUsage();
+        if (keyUsage != null)
+          {
+            if (!keyUsage[KeyUsage.CRL_SIGN])
+              continue;
+          }
+        try
+          {
+            crl.verify(path[i].getPublicKey());
+            return true;
+          }
+        catch (Exception x)
+          {
+          }
+      }
+    if (crl.getIssuerDN().equals(pubKeyCert.getSubjectDN()))
+      {
+        try
+          {
+            boolean[] keyUsage = pubKeyCert.getKeyUsage();
+            if (keyUsage != null)
+              {
+                if (!keyUsage[KeyUsage.CRL_SIGN])
+                  throw new Exception();
+              }
+            crl.verify(pubKey);
+            return true;
+          }
+        catch (Exception x)
+          {
+          }
+      }
+    try
+      {
+        X509CertSelectorImpl select = new X509CertSelectorImpl();
+        select.addSubjectName(crl.getIssuerDN());
+        List certs = new LinkedList();
+        for (Iterator it = certStores.iterator(); it.hasNext(); )
+          {
+            CertStore cs = (CertStore) it.next();
+            try
+              {
+                certs.addAll(cs.getCertificates(select));
+              }
+            catch (CertStoreException cse)
+              {
+              }
+          }
+        for (Iterator it = certs.iterator(); it.hasNext(); )
+          {
+            X509Certificate c = (X509Certificate) it.next();
+            for (int i = 0; i < path.length; i++)
+              {
+                if (!c.getIssuerDN().equals(path[i].getSubjectDN()))
+                  continue;
+                boolean[] keyUsage = c.getKeyUsage();
+                if (keyUsage != null)
+                  {
+                    if (!keyUsage[KeyUsage.CRL_SIGN])
+                      continue;
+                  }
+                try
+                  {
+                    c.verify(path[i].getPublicKey());
+                    crl.verify(c.getPublicKey());
+                    return true;
+                  }
+                catch (Exception x)
+                  {
+                  }
+              }
+            if (c.getIssuerDN().equals(pubKeyCert.getSubjectDN()))
+              {
+                c.verify(pubKey);
+                crl.verify(c.getPublicKey());
+              }
+          }
+      }
+    catch (Exception x)
+      {
+      }
+    return false;
+  }
+
+  private static Set getCritExts(X509Certificate cert)
+  {
+    HashSet s = new HashSet();
+    if (cert instanceof GnuPKIExtension)
+      {
+        Collection exts = ((GnuPKIExtension) cert).getExtensions();
+        for (Iterator it = exts.iterator(); it.hasNext(); )
+          {
+            Extension ext = (Extension) it.next();
+            if (ext.isCritical() && !ext.isSupported())
+              s.add(ext.getOid().toString());
+          }
+      }
+    else
+      s.addAll(cert.getCriticalExtensionOIDs());
+    return s;
+  }
+
+  /**
+   * Perform a basic sanity check on the CA certificate at <code>index</code>.
+   */
+  private static void basicSanity(X509Certificate[] path, int index)
+    throws CertPathValidatorException
+  {
+    X509Certificate cert = path[index];
+    int pathLen = 0;
+    for (int i = index - 1; i > 0; i--)
+      {
+        if (!path[i].getIssuerDN().equals(path[i].getSubjectDN()))
+          pathLen++;
+      }
+    Extension e = null;
+    if (cert instanceof GnuPKIExtension)
+      {
+        e = ((GnuPKIExtension) cert).getExtension(BasicConstraints.ID);
+      }
+    else
+      {
+        try
+          {
+            e = new Extension(cert.getExtensionValue(BasicConstraints.ID.toString()));
+          }
+        catch (Exception x)
+          {
+          }
+      }
+    if (e == null)
+      throw new CertPathValidatorException("no basicConstraints");
+    BasicConstraints bc = (BasicConstraints) e.getValue();
+    if (!bc.isCA())
+      throw new CertPathValidatorException("certificate cannot be used to verify signatures");
+    if (bc.getPathLengthConstraint() >= 0 && bc.getPathLengthConstraint() < pathLen)
+      throw new CertPathValidatorException("path is too long");
+
+    boolean[] keyUsage = cert.getKeyUsage();
+    if (keyUsage != null)
+      {
+        if (!keyUsage[KeyUsage.KEY_CERT_SIGN])
+          throw new CertPathValidatorException("certificate cannot be used to sign certificates");
+      }
+  }
+
+  private static void updatePolicyTree(X509Certificate cert, PolicyNodeImpl root,
+                                       int depth, PKIXParameters params,
+                                       boolean explicitPolicy)
+    throws CertPathValidatorException
+  {
+    if (DEBUG) debug("updatePolicyTree depth == " + depth);
+    Set nodes = new HashSet();
+    LinkedList stack = new LinkedList();
+    Iterator current = null;
+    stack.addLast(Collections.singleton(root).iterator());
+    do
+      {
+        current = (Iterator) stack.removeLast();
+        while (current.hasNext())
+          {
+            PolicyNodeImpl p = (PolicyNodeImpl) current.next();
+            if (DEBUG) debug("visiting node == " + p);
+            if (p.getDepth() == depth - 1)
+              {
+                if (DEBUG) debug("added node");
+                nodes.add(p);
+              }
+            else
+              {
+                if (DEBUG) debug("skipped node");
+                stack.addLast(current);
+                current = p.getChildren();
+              }
+          }
+      }
+    while (!stack.isEmpty());
+
+    Extension e = null;
+    CertificatePolicies policies = null;
+    List qualifierInfos = null;
+    if (cert instanceof GnuPKIExtension)
+      {
+        e = ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID);
+        if (e != null)
+          policies = (CertificatePolicies) e.getValue();
+      }
+
+    List cp = null;
+    if (policies != null)
+      cp = policies.getPolicies();
+    else
+      cp = Collections.EMPTY_LIST;
+    boolean match = false;
+    if (DEBUG) debug("nodes are == " + nodes);
+    if (DEBUG) debug("cert policies are == " + cp);
+    for (Iterator it = nodes.iterator(); it.hasNext(); )
+      {
+        PolicyNodeImpl parent = (PolicyNodeImpl) it.next();
+        if (DEBUG) debug("adding policies to " + parent);
+        for (Iterator it2 = cp.iterator(); it2.hasNext(); )
+          {
+            OID policy = (OID) it2.next();
+            if (DEBUG) debug("trying to add policy == " + policy);
+            if (policy.toString().equals(ANY_POLICY) &&
+                params.isAnyPolicyInhibited())
+              continue;
+            PolicyNodeImpl child = new PolicyNodeImpl();
+            child.setValidPolicy(policy.toString());
+            child.addExpectedPolicy(policy.toString());
+            if (parent.getExpectedPolicies().contains(policy.toString()))
+              {
+                parent.addChild(child);
+                match = true;
+              }
+            else if (parent.getExpectedPolicies().contains(ANY_POLICY))
+              {
+                parent.addChild(child);
+                match = true;
+              }
+            else if (ANY_POLICY.equals (policy.toString()))
+              {
+                parent.addChild (child);
+                match = true;
+              }
+            if (match && policies != null)
+              {
+                List qualifiers = policies.getPolicyQualifierInfos (policy);
+                if (qualifiers != null)
+                  child.addAllPolicyQualifiers (qualifiers);
+              }
+          }
+      }
+    if (!match && (params.isExplicitPolicyRequired() || explicitPolicy))
+      throw new CertPathValidatorException("policy tree building failed");
+  }
+
+  private boolean checkExplicitPolicy (int depth, List explicitPolicies)
+  {
+    if (DEBUG) debug ("checkExplicitPolicy depth=" + depth);
+    for (Iterator it = explicitPolicies.iterator(); it.hasNext(); )
+      {
+        int[] i = (int[]) it.next();
+        int caDepth = i[0];
+        int limit = i[1];
+        if (DEBUG) debug ("  caDepth=" + caDepth + " limit=" + limit);
+        if (depth - caDepth >= limit)
+          return true;
+      }
+    return false;
+  }
+}
diff --git a/libjava/gnu/java/security/provider/RSA.java b/libjava/gnu/java/security/provider/RSA.java
new file mode 100644 (file)
index 0000000..5afa8b7
--- /dev/null
@@ -0,0 +1,314 @@
+/* RSA.java -- RSA PKCS#1 signatures.
+   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.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import java.math.BigInteger;
+
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import java.util.ArrayList;
+
+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.der.DERWriter;
+
+public abstract class RSA extends SignatureSpi implements Cloneable
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * digestAlgorithm OBJECT IDENTIFIER ::=
+   *   { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) }
+   */
+  protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2");
+
+  protected final OID digestAlgorithm;
+  protected final MessageDigest md;
+  protected RSAPrivateKey signerKey;
+  protected RSAPublicKey verifierKey;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  protected RSA(MessageDigest md, OID digestAlgorithm)
+  {
+    super();
+    this.md = md;
+    this.digestAlgorithm = digestAlgorithm;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public Object clone() throws CloneNotSupportedException
+  {
+    return super.clone();
+  }
+
+  protected Object engineGetParameter(String param)
+  {
+    throw new UnsupportedOperationException("deprecated");
+  }
+
+  protected void engineSetParameter(String param, Object value)
+  {
+    throw new UnsupportedOperationException("deprecated");
+  }
+
+  protected void engineInitSign(PrivateKey privateKey)
+    throws InvalidKeyException
+  {
+    if (!(privateKey instanceof RSAPrivateKey))
+      throw new InvalidKeyException();
+    verifierKey = null;
+    signerKey = (RSAPrivateKey) privateKey;
+  }
+
+  protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
+    throws InvalidKeyException
+  {
+    // This class does not need random bytes.
+    engineInitSign(privateKey);
+  }
+
+  protected void engineInitVerify(PublicKey publicKey)
+    throws InvalidKeyException
+  {
+    if (!(publicKey instanceof RSAPublicKey))
+      throw new InvalidKeyException();
+    signerKey = null;
+    verifierKey = (RSAPublicKey) publicKey;
+  }
+
+  protected void engineUpdate(byte b) throws SignatureException
+  {
+    if (signerKey == null && verifierKey == null)
+      throw new SignatureException("not initialized");
+    md.update(b);
+  }
+
+  protected void engineUpdate(byte[] buf, int off, int len)
+    throws SignatureException
+  {
+    if (signerKey == null && verifierKey == null)
+      throw new SignatureException("not initialized");
+    md.update(buf, off, len);
+  }
+
+  protected byte[] engineSign() throws SignatureException
+  {
+    if (signerKey == null)
+      throw new SignatureException("not initialized for signing");
+    //
+    // The signature will be the RSA encrypted BER representation of
+    // the following:
+    //
+    //   DigestInfo ::= SEQUENCE {
+    //     digestAlgorithm  DigestAlgorithmIdentifier,
+    //     digest           Digest }
+    //
+    //   DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+    //
+    //   Digest ::= OCTET STRING
+    //
+    ArrayList digestAlg = new ArrayList(2);
+    digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm));
+    digestAlg.add(new DERValue(DER.NULL, null));
+    ArrayList digestInfo = new ArrayList(2);
+    digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg));
+    digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest()));
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    try
+      {
+        DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo));
+      }
+    catch (IOException ioe)
+      {
+        throw new SignatureException(ioe.toString());
+      }
+    byte[] buf = out.toByteArray();
+    md.reset();
+
+    // k = octect length of the modulus.
+    int k = signerKey.getModulus().bitLength();
+    k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
+    if (buf.length < k - 3)
+      {
+        throw new SignatureException("RSA modulus too small");
+      }
+    byte[] d = new byte[k];
+
+    // Padding type 1:
+    //     00 | 01 | FF | ... | FF | 00 | D
+    d[1] = 0x01;
+    for (int i = 2; i < k - buf.length - 1; i++)
+      d[i] = (byte) 0xFF;
+    System.arraycopy(buf, 0, d, k - buf.length, buf.length);
+
+    BigInteger eb = new BigInteger(d);
+
+    byte[] ed = eb.modPow(signerKey.getPrivateExponent(),
+                          signerKey.getModulus()).toByteArray();
+
+    // Ensure output is k octets long.
+    if (ed.length < k)
+      {
+        byte[] b = new byte[k];
+        System.arraycopy(eb, 0, b, k - ed.length, ed.length);
+        ed = b;
+      }
+    else if (ed.length > k)
+      {
+        if (ed.length != k + 1)
+          {
+            throw new SignatureException("modPow result is larger than the modulus");
+          }
+        // Maybe an extra 00 octect.
+        byte[] b = new byte[k];
+        System.arraycopy(ed, 1, b, 0, k);
+        ed = b;
+      }
+
+    return ed;
+  }
+
+  protected int engineSign(byte[] out, int off, int len)
+    throws SignatureException
+  {
+    if (out == null || off < 0 || len < 0 || off+len > out.length)
+      throw new SignatureException("illegal output argument");
+    byte[] result = engineSign();
+    if (result.length > len)
+      throw new SignatureException("not enough space for signature");
+    System.arraycopy(result, 0, out, off, result.length);
+    return result.length;
+  }
+
+  protected boolean engineVerify(byte[] sig) throws SignatureException
+  {
+    if (verifierKey == null)
+      throw new SignatureException("not initialized for verifying");
+    if (sig == null)
+      throw new SignatureException("no signature specified");
+    int k = verifierKey.getModulus().bitLength();
+    k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
+    if (sig.length != k)
+      throw new SignatureException("signature is the wrong size (expecting "
+                                   + k + " bytes, got " + sig.length + ")");
+    BigInteger ed = new BigInteger(1, sig);
+    byte[] eb = ed.modPow(verifierKey.getPublicExponent(),
+                          verifierKey.getModulus()).toByteArray();
+
+    int i = 0;
+    if (eb[0] == 0x00)
+      {
+        for (i = 1; i < eb.length && eb[i] == 0x00; i++);
+        if (i == 1)
+          throw new SignatureException("wrong RSA padding");
+        i--;
+      }
+    else if (eb[0] == 0x01)
+      {
+        for (i = 1; i < eb.length && eb[i] != 0x00; i++)
+          if (eb[i] != (byte) 0xFF)
+            throw new IllegalArgumentException("wrong RSA padding");
+      }
+    else
+      throw new SignatureException("wrong RSA padding type");
+
+    byte[] d = new byte[eb.length-i-1];
+    System.arraycopy(eb, i+1, d, 0, eb.length-i-1);
+
+    DERReader der = new DERReader(d);
+    try
+      {
+        DERValue val = der.read();
+        if (val.getTag() != DER.SEQUENCE)
+          throw new SignatureException("failed to parse DigestInfo");
+        val = der.read();
+        if (val.getTag() != DER.SEQUENCE)
+          throw new SignatureException("failed to parse DigestAlgorithmIdentifier");
+        boolean sequenceIsBer = val.getLength() == 0;
+        val = der.read();
+        if (val.getTag() != DER.OBJECT_IDENTIFIER)
+          throw new SignatureException("failed to parse object identifier");
+        if (!val.getValue().equals(digestAlgorithm))
+          throw new SignatureException("digest algorithms do not match");
+        val = der.read();
+        // We should never see parameters here, since they are never used.
+        if (val.getTag() != DER.NULL)
+          throw new SignatureException("cannot handle digest parameters");
+        if (sequenceIsBer)
+          der.skip(1); // end-of-sequence byte.
+        val = der.read();
+        if (val.getTag() != DER.OCTET_STRING)
+          throw new SignatureException("failed to parse Digest");
+        return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue());
+      }
+    catch (IOException ioe)
+      {
+        throw new SignatureException(ioe.toString());
+      }
+  }
+
+  protected boolean engineVerify(byte[] sig, int off, int len)
+    throws SignatureException
+  {
+    if (sig == null || off < 0 || len < 0 || off+len > sig.length)
+      throw new SignatureException("illegal parameter");
+    byte[] buf = new byte[len];
+    System.arraycopy(sig, off, buf, 0, len);
+    return engineVerify(buf);
+  }
+}
diff --git a/libjava/gnu/java/security/provider/RSAKeyFactory.java b/libjava/gnu/java/security/provider/RSAKeyFactory.java
new file mode 100644 (file)
index 0000000..33c8c22
--- /dev/null
@@ -0,0 +1,181 @@
+/* RSAKeyFactory.java -- RSA key factory.
+   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.provider;
+
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactorySpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class RSAKeyFactory extends KeyFactorySpi
+{
+
+  // Default constructor.
+  // -------------------------------------------------------------------------
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  protected PrivateKey engineGeneratePrivate(KeySpec spec)
+    throws InvalidKeySpecException
+  {
+    if (spec instanceof RSAPrivateCrtKeySpec)
+      {
+        return new GnuRSAPrivateKey((RSAPrivateCrtKeySpec) spec);
+      }
+    if (spec instanceof RSAPrivateKeySpec)
+      {
+        return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
+          ((RSAPrivateKeySpec) spec).getModulus(), null,
+          ((RSAPrivateKeySpec) spec).getPrivateExponent(), null,
+          null, null, null, null));
+      }
+    if (spec instanceof PKCS8EncodedKeySpec)
+      {
+        EncodedKeyFactory ekf = new EncodedKeyFactory();
+        PrivateKey pk = ekf.engineGeneratePrivate(spec);
+        if (pk instanceof RSAPrivateKey)
+          return pk;
+      }
+    throw new InvalidKeySpecException();
+  }
+
+  protected PublicKey engineGeneratePublic(KeySpec spec)
+    throws InvalidKeySpecException
+  {
+    if (spec instanceof RSAPublicKeySpec)
+      {
+        return new GnuRSAPublicKey((RSAPublicKeySpec) spec);
+      }
+    if (spec instanceof X509EncodedKeySpec)
+      {
+        EncodedKeyFactory ekf = new EncodedKeyFactory();
+        PublicKey pk = ekf.engineGeneratePublic(spec);
+        if (pk instanceof RSAPublicKey)
+          return pk;
+      }
+    throw new InvalidKeySpecException();
+  }
+
+  protected KeySpec engineGetKeySpec(Key key, Class keySpec)
+    throws InvalidKeySpecException
+  {
+    if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class)
+        && (key instanceof RSAPrivateCrtKey))
+      {
+        return new RSAPrivateCrtKeySpec(
+          ((RSAPrivateCrtKey) key).getModulus(),
+          ((RSAPrivateCrtKey) key).getPublicExponent(),
+          ((RSAPrivateCrtKey) key).getPrivateExponent(),
+          ((RSAPrivateCrtKey) key).getPrimeP(),
+          ((RSAPrivateCrtKey) key).getPrimeQ(),
+          ((RSAPrivateCrtKey) key).getPrimeExponentP(),
+          ((RSAPrivateCrtKey) key).getPrimeExponentQ(),
+          ((RSAPrivateCrtKey) key).getCrtCoefficient());
+      }
+    if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class)
+        && (key instanceof RSAPrivateKey))
+      {
+        return new RSAPrivateKeySpec(
+          ((RSAPrivateCrtKey) key).getModulus(),
+          ((RSAPrivateCrtKey) key).getPrivateExponent());
+      }
+    if (keySpec.isAssignableFrom(RSAPublicKeySpec.class)
+        && (key instanceof RSAPublicKey))
+      {
+        return new RSAPublicKeySpec(
+          ((RSAPrivateCrtKey) key).getModulus(),
+          ((RSAPrivateCrtKey) key).getPublicExponent());
+      }
+    if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)
+        && key.getFormat().equalsIgnoreCase("PKCS#8"))
+      {
+        return new PKCS8EncodedKeySpec(key.getEncoded());
+      }
+    if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)
+        && key.getFormat().equalsIgnoreCase("X.509"))
+      {
+        return new X509EncodedKeySpec(key.getEncoded());
+      }
+    throw new InvalidKeySpecException();
+  }
+
+  protected Key engineTranslateKey(Key key) throws InvalidKeyException
+  {
+    if (key instanceof RSAPrivateCrtKey)
+      {
+        return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
+          ((RSAPrivateCrtKey) key).getModulus(),
+          ((RSAPrivateCrtKey) key).getPublicExponent(),
+          ((RSAPrivateCrtKey) key).getPrivateExponent(),
+          ((RSAPrivateCrtKey) key).getPrimeP(),
+          ((RSAPrivateCrtKey) key).getPrimeQ(),
+          ((RSAPrivateCrtKey) key).getPrimeExponentP(),
+          ((RSAPrivateCrtKey) key).getPrimeExponentQ(),
+          ((RSAPrivateCrtKey) key).getCrtCoefficient()));
+      }
+    if (key instanceof RSAPrivateKey)
+      {
+        return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
+          ((RSAPrivateKey) key).getModulus(), null,
+          ((RSAPrivateKey) key).getPrivateExponent(), null,
+          null, null, null, null));
+      }
+    if (key instanceof RSAPublicKey)
+      {
+        return new GnuRSAPublicKey(new RSAPublicKeySpec(
+          ((RSAPrivateCrtKey) key).getModulus(),
+          ((RSAPrivateCrtKey) key).getPublicExponent()));
+      }
+    throw new InvalidKeyException();
+  }
+}
diff --git a/libjava/gnu/java/security/provider/SHA1withRSA.java b/libjava/gnu/java/security/provider/SHA1withRSA.java
new file mode 100644 (file)
index 0000000..64e93f9
--- /dev/null
@@ -0,0 +1,61 @@
+/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures.
+   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.provider;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import gnu.java.security.OID;
+
+public class SHA1withRSA extends RSA
+{
+
+  // Constant.
+  // -------------------------------------------------------------------------
+
+  private static final OID SHA1 = new OID("1.3.14.3.2.26");
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public SHA1withRSA() throws NoSuchAlgorithmException
+  {
+    super(MessageDigest.getInstance("SHA-160"), SHA1);
+  }
+}
index 62d3d38af626daeb9b806d612ec5a1aaea1f7e16..753300651b99add685b9280d40aff639f5383d14 100644 (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,16 +44,21 @@ import java.io.InputStream;
 import java.io.IOException;
 
 import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactorySpi;
+import java.security.cert.CertPath;
 import java.security.cert.CRL;
 import java.security.cert.CRLException;
 
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 
 import gnu.java.io.Base64InputStream;
 import gnu.java.security.x509.X509Certificate;
+import gnu.java.security.x509.X509CertPath;
 import gnu.java.security.x509.X509CRL;
 
 public class X509CertificateFactory extends CertificateFactorySpi
@@ -87,7 +92,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
       }
     catch (IOException ioe)
       {
-        throw new CertificateException(ioe.toString());
+        CertificateException ce = new CertificateException(ioe.getMessage());
+        ce.initCause (ioe);
+        throw ce;
       }
   }
 
@@ -107,7 +114,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
           }
         catch (IOException ioe)
           {
-            throw new CertificateException(ioe.toString());
+            CertificateException ce = new CertificateException(ioe.getMessage());
+            ce.initCause (ioe);
+            throw ce;
           }
       }
     return certs;
@@ -121,7 +130,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
       }
     catch (IOException ioe)
       {
-        throw new CRLException(ioe.toString());
+        CRLException crle = new CRLException(ioe.getMessage());
+        crle.initCause (ioe);
+        throw crle;
       }
   }
 
@@ -141,18 +152,44 @@ public class X509CertificateFactory extends CertificateFactorySpi
           }
         catch (IOException ioe)
           {
-            throw new CRLException(ioe.toString());
+            CRLException crle = new CRLException(ioe.getMessage());
+            crle.initCause (ioe);
+            throw crle;
           }
       }
     return crls;
   }
 
+  public CertPath engineGenerateCertPath(List certs)
+  {
+    return new X509CertPath(certs);
+  }
+
+  public CertPath engineGenerateCertPath(InputStream in)
+    throws CertificateEncodingException
+  {
+    return new X509CertPath(in);
+  }
+
+  public CertPath engineGenerateCertPath(InputStream in, String encoding)
+    throws CertificateEncodingException
+  {
+    return new X509CertPath(in, encoding);
+  }
+
+  public Iterator engineGetCertPathEncodings()
+  {
+    return X509CertPath.ENCODINGS.iterator();
+  }
+
   // Own methods.
   // ------------------------------------------------------------------------
 
   private X509Certificate generateCert(InputStream inStream)
     throws IOException, CertificateException
   {
+    if (inStream == null)
+      throw new CertificateException("missing input stream");
     if (!inStream.markSupported())
       inStream = new BufferedInputStream(inStream, 8192);
     inStream.mark(20);
@@ -211,6 +248,8 @@ public class X509CertificateFactory extends CertificateFactorySpi
   private X509CRL generateCRL(InputStream inStream)
     throws IOException, CRLException
   {
+    if (inStream == null)
+      throw new CRLException("missing input stream");
     if (!inStream.markSupported())
       inStream = new BufferedInputStream(inStream, 8192);
     inStream.mark(20);
@@ -265,5 +304,4 @@ public class X509CertificateFactory extends CertificateFactorySpi
         return new X509CRL(inStream);
       }
   }
-
 }
diff --git a/libjava/gnu/java/security/x509/GnuPKIExtension.java b/libjava/gnu/java/security/x509/GnuPKIExtension.java
new file mode 100644 (file)
index 0000000..8294e65
--- /dev/null
@@ -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();
+}
diff --git a/libjava/gnu/java/security/x509/PolicyNodeImpl.java b/libjava/gnu/java/security/x509/PolicyNodeImpl.java
new file mode 100644 (file)
index 0000000..d3d4bd9
--- /dev/null
@@ -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();
+  }
+}
diff --git a/libjava/gnu/java/security/x509/Util.java b/libjava/gnu/java/security/x509/Util.java
new file mode 100644 (file)
index 0000000..3bbbff2
--- /dev/null
@@ -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;
+  }
+}
index 8a715677befddb603bf63fcfe87f0312d1fa3582..64e320bef82ebe623efbdbf08c4bd469866d6eeb 100644 (file)
@@ -1,5 +1,5 @@
-/* X500DistinguishedName.java -- X.500 name.
-   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
+/* X500DistinguishedName.java -- X.500 distinguished name.
+   Copyright (C) 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
@@ -38,121 +38,35 @@ exception statement from your version. */
 
 package gnu.java.security.x509;
 
-import gnu.java.io.ASN1ParsingException;
-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.der.DERWriter;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
 import java.io.InputStream;
 import java.io.IOException;
-import java.io.StreamTokenizer;
+import java.io.Reader;
 import java.io.StringReader;
+
+import java.security.Principal;
+
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
 
-/**
- * A X.500 distinguished name. Distinguished names are sequences of
- * ATTRIB=VALUE pairs, where ATTRIB is one of the following:
- *
- * <table cellpadding="0" cellspacing="0" border="0">
- * <tr>
- * <th bgcolor="#CCCCFF" align="left">Name</th>
- * <th bgcolor="#CCCCFF" align="left">X.500 AttributeType</th>
- * <th bgcolor="#CCCCFF" align="left">ObjectIdentifier</th>
- * </tr>
- * <tr>
- * <td align="left">CN</td>
- * <td align="left">commonName</td>
- * <td align="left">2.5.4.3</td>
- * </tr>
- * <tr>
- * <td align="left">C</td>
- * <td align="left">countryName</td>
- * <td align="left">2.5.4.6</td>
- * </tr>
- * <tr>
- * <td align="left">L</td>
- * <td align="left">localityName</td>
- * <td align="left">2.5.4.7</td>
- * </tr>
- * <tr>
- * <td align="left">ST</td>
- * <td align="left">stateOrProvinceName</td>
- * <td align="left">2.5.4.8</td>
- * </tr>
- * <tr>
- * <td align="left">STREET</td>
- * <td align="left">streetAddress</td>
- * <td align="left">2.5.4.9</td>
- * </tr>
- * <tr>
- * <td align="left">O</td>
- * <td align="left">organizationName</td>
- * <td align="left">2.5.4.10</td>
- * </tr>
- * <tr>
- * <td align="left">OU</td>
- * <td align="left">organizationUnitName</td>
- * <td align="left">2.5.4.11</td>
- * </tr>
- * <tr>
- * <td align="left">DC</td>
- * <td align="left">domainComponent</td>
- * <td align="left">0.9.2342.19200300.100.1.25</td>
- * </tr>
- * <tr>
- * <td align="left">UID</td>
- * <td align="left">userid</td>
- * <td align="left"0.9.2342.19200300.100.1.1></td>
- * </tr>
- * <tr>
- * <td align="left">DNQ or DNQUALIFIER(*)</td>
- * <td align="left">domainNameQualifier</td>
- * <td align="left">2.5.4.46</td>
- * </tr>
- * <tr>
- * <td align="left">SURNAME(*)</td>
- * <td align="left">name</td>
- * <td align="left">2.5.4.41</td>
- * </tr>
- * <tr>
- * <td align="left">GIVENNAME(*)</td>
- * <td align="left">givenName</td>
- * <td align="left">2.5.4.42</td>
- * </tr>
- * <tr>
- * <td align="left">INITIALS(*)</td>
- * <td align="left">initials</td>
- * <td align="left">2.5.4.43</td>
- * </tr>
- * <tr>
- * <td align="left">EMAILADDRESS(*)</td>
- * <td align="left">emailAddress</td>
- * <td align="left">2.5.4.44</td>
- * </tr>
- * </table>
- *
- * <p><i>(*) = attributes not specified in RFC1779 or RFC2253, but
- * recognized anyway.</i>
- *
- * <p>Distinguished names of this form are used in the lightweight
- * directory access protocol (LDAP) and in the issuer and subject fields
- * of X.509 certificates.
- *
- * @author Casey Marshall (rsdio@metastatic.org)
- * @see javax.security.auth.x500.X500Principal
- * @status DER decoding/encoding works, RFC1779 and RFC2253 need to be
- *         made more robust.
- */
-public class X500DistinguishedName
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERReader;
+import gnu.java.security.der.DERValue;
+import gnu.java.security.OID;
+
+public class X500DistinguishedName implements Principal
 {
 
   // Constants and fields.
-  // ------------------------------------------------------------------------
+  // -------------------------------------------------------------------------
 
   public static final OID CN         = new OID("2.5.4.3");
   public static final OID C          = new OID("2.5.4.6");
@@ -171,651 +85,467 @@ public class X500DistinguishedName
   public static final OID DC         = new OID("0.9.2342.19200300.100.1.25");
   public static final OID UID        = new OID("0.9.2342.19200300.100.1.1");
 
-  private String commonName;
-  private String country;
-  private String locality;
-  private String orgUnit;
-  private String organization;
-  private String street;
-  private String state;
-  private String title;
-  private String dnQualifier;
-  private String surname;
-  private String givenName;
-  private String initials;
-  private String generation;
-  private String email;
-  private String domainComponent;
-  private String userid;
-
-  private String nameRFC1779;
-  private String nameRFC2253;
-  private String nameCanonical;
-
-  private transient byte[] encoded;
+  private List components;
+  private Map currentRdn;
+  private boolean fixed;
+  private String stringRep;
+  private byte[] encoded;
 
   // Constructors.
-  // ------------------------------------------------------------------------
-
-  /**
-   * Create a new X500DistinguishedName from the RFC1779 or RFC2253
-   * encoded form.
-   *
-   * @param name The encoded name.
-   * @throws IllegalArgumentException If the name cannot be parsed.
-   */
+  // -------------------------------------------------------------------------
+
+  public X500DistinguishedName()
+  {
+    components = new LinkedList();
+    currentRdn = new LinkedHashMap();
+    components.add(currentRdn);
+  }
+
   public X500DistinguishedName(String name)
   {
-    if (name == null)
-      throw new NullPointerException();
+    this();
     try
       {
-        parseDN(name, true);
+        parseString(name);
       }
-    catch (Exception e)
+    catch (IOException ioe)
       {
-        parseDN(name, false);
+        throw new IllegalArgumentException(ioe.toString());
       }
   }
 
-  /**
-   * Create a new X500DistinguishedName from the DER encoded bytes.
-   *
-   * @param encoded The encoded form.
-   * @throws IOException If the bytes are not a valid DER construct.
-   */
   public X500DistinguishedName(byte[] encoded) throws IOException
   {
-    this(new ByteArrayInputStream(encoded));
+    this();
+    parseDer(new DERReader(encoded));
   }
 
-  /**
-   * Create a new X500DistinguishedName from the DER encoded bytes.
-   *
-   * @param encoded The encoded form.
-   * @throws IOException If the bytes are not a valid DER construct.
-   */
   public X500DistinguishedName(InputStream encoded) throws IOException
   {
-    parseDER(encoded);
+    this();
+    parseDer(new DERReader(encoded));
   }
 
   // Instance methods.
-  // ------------------------------------------------------------------------
-
-  public boolean equals(Object o)
-  {
-    return 
-      (commonName != null &&
-       commonName.equals(((X500DistinguishedName) o).commonName)) &&
-      (country != null &&
-       country.equals(((X500DistinguishedName) o).country)) &&
-      (locality != null &&
-       locality.equals(((X500DistinguishedName) o).locality)) &&
-      (orgUnit != null &&
-       orgUnit.equals(((X500DistinguishedName) o).orgUnit)) &&
-      (organization != null &&
-       organization.equals(((X500DistinguishedName) o).organization)) &&
-      (street != null &&
-       street.equals(((X500DistinguishedName) o).street)) &&
-      (state != null &&
-       state.equals(((X500DistinguishedName) o).state)) &&
-      (domainComponent != null &&
-       domainComponent.equals(((X500DistinguishedName) o).domainComponent)) &&
-      (title != null &&
-       title.equals(((X500DistinguishedName) o).title)) &&
-      (dnQualifier != null &&
-       dnQualifier.equals(((X500DistinguishedName) o).dnQualifier)) &&
-      (surname != null &&
-       surname.equals(((X500DistinguishedName) o).surname)) &&
-      (givenName != null &&
-       givenName.equals(((X500DistinguishedName) o).givenName)) &&
-      (initials != null &&
-       initials.equals(((X500DistinguishedName) o).initials)) &&
-      (generation != null &&
-       generation.equals(((X500DistinguishedName) o).generation)) &&
-      (email != null &&
-       email.equals(((X500DistinguishedName) o).email)) &&
-      (userid != null &&
-       userid.equals(((X500DistinguishedName) o).userid));
-  }
-
-  public byte[] getEncoded()
-  {
-    if (encoded == null)
-      encoded = encodeDER();
-    return (byte[]) encoded.clone();
-  }
-
-  private static String quote(String str)
-  {
-    if (str.indexOf(" ")  > 0 || str.indexOf("\f") > 0 ||
-        str.indexOf("\n") > 0 || str.indexOf("\r") > 0 ||
-        str.indexOf("\t") > 0)
-      str = '"' + str + '"';
-    // XXX needs regex
-    //return str.replaceAll("([,+\"\\<>;])", "\\\1");
-    return str;
-  }
-
-  public String toRFC1779()
-  {
-    if (nameRFC1779 != null)
-      return nameRFC1779;
-    StringBuffer buf = new StringBuffer();
-    if (commonName != null)
-      buf.append("CN=").append(quote(commonName)).append(", ");
-    if (country != null)
-      buf.append("C=").append(quote(country)).append(", ");
-    if (locality != null)
-      buf.append("L=").append(quote(locality)).append(", ");
-    if (orgUnit != null)
-      buf.append("OU=").append(quote(orgUnit)).append(", ");
-    if (organization != null)
-      buf.append("O=").append(quote(organization)).append(", ");
-    if (street != null)
-      buf.append("STREET=").append(quote(street)).append(", ");
-    if (state != null)
-      buf.append("ST=").append(quote(state)).append(", ");
-    if (title != null)
-      buf.append(T).append("=").append(quote(title)).append(", ");
-    if (dnQualifier != null)
-      buf.append(DNQ).append("=").append(quote(dnQualifier)).append(", ");
-    if (surname != null)
-      buf.append(NAME).append("=").append(quote(surname)).append(", ");
-    if (givenName != null)
-      buf.append(GIVENNAME).append("=").append(quote(givenName)).append(", ");
-    if (initials != null)
-      buf.append(INITIALS).append("=").append(quote(initials)).append(", ");
-    if (generation != null)
-      buf.append(GENERATION).append("=").append(quote(generation)).append(", ");
-    if (email != null)
-      buf.append(EMAIL).append("=").append(quote(email)).append(", ");
-    if (domainComponent != null)
-      buf.append(DC).append("=").append(quote(domainComponent)).append(", ");
-    if (userid != null)
-      buf.append(UID).append("=").append(quote(userid)).append(", ");
-    // XXX escapes
-    return (nameRFC1779 = buf.substring(0, buf.length()-2));
-  }
-
-  public String toRFC2253()
-  {
-    if (nameRFC2253 != null)
-      return nameRFC2253;
-    StringBuffer buf = new StringBuffer();
-    if (commonName != null)
-      buf.append("CN=").append(quote(commonName)).append(",");
-    if (country != null)
-      buf.append("C=").append(quote(country)).append(",");
-    if (locality != null)
-      buf.append("L=").append(quote(locality)).append(",");
-    if (orgUnit != null)
-      buf.append("OU=").append(quote(orgUnit)).append(",");
-    if (organization != null)
-      buf.append("O=").append(quote(organization)).append(",");
-    if (street != null)
-      buf.append("STREET=").append(quote(street)).append(",");
-    if (state != null)
-      buf.append("ST=").append(quote(state)).append(",");
-    if (title != null)
-      buf.append(T).append("=").append(quote(title)).append(",");
-    if (dnQualifier != null)
-      buf.append(DNQ).append("=").append(quote(dnQualifier)).append(",");
-    if (surname != null)
-      buf.append(NAME).append("=").append(quote(surname)).append(",");
-    if (givenName != null)
-      buf.append(GIVENNAME).append("=").append(quote(givenName)).append(",");
-    if (initials != null)
-      buf.append(INITIALS).append("=").append(quote(initials)).append(",");
-    if (generation != null)
-      buf.append(GENERATION).append("=").append(quote(generation)).append(",");
-    if (email != null)
-      buf.append(EMAIL).append("=").append(quote(email)).append(",");
-    if (domainComponent != null)
-      buf.append(DC).append("=").append(quote(domainComponent)).append(",");
-    if (userid != null)
-      buf.append(UID).append("=").append(quote(userid)).append(",");
-    // XXX escapes.
-    return (nameRFC2253 = buf.substring(0, buf.length()-1));
-  }
+  // -------------------------------------------------------------------------
 
-  public String toCanonical()
+  public String getName()
   {
-    if (nameCanonical != null)
-      return nameCanonical;
-    nameCanonical = toRFC2253();
-    return nameCanonical; // XXX canonicalize
+    return toString();
   }
 
-  public String getCommonName()
+  public void newRelativeDistinguishedName()
   {
-    return commonName;
+    if (fixed || currentRdn.isEmpty()) return;
+    currentRdn = new LinkedHashMap();
+    components.add(currentRdn);
   }
 
-  public String getCountry()
+  public int size()
   {
-    return country;
+    return components.size();
   }
 
-  public String getLocality()
+  public int countComponents()
   {
-    return locality;
+    int count = 0;
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        count += ((Map) it.next()).size();
+      }
+    return count;
   }
 
-  public String getOrganizationalUnit()
+  public boolean containsComponent(OID oid, String value)
   {
-    return orgUnit;
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map rdn = (Map) it.next();
+        String s = (String) rdn.get(oid);
+        if (s == null)
+          continue;
+        if (compressWS(value).equalsIgnoreCase(compressWS(s)))
+          return true;
+      }
+    return false;
   }
 
-  public String getOrganization()
+  public String getComponent(OID oid)
   {
-    return organization;
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map rdn = (Map) it.next();
+        if (rdn.containsKey(oid))
+          return (String) rdn.get(oid);
+      }
+    return null;
   }
 
-  public String getStreet()
+  public String getComponent(OID oid, int rdn)
   {
-    return street;
+    if (rdn >= size())
+      return null;
+    return (String) ((Map) components.get(rdn)).get(oid);
   }
 
-  public String getState()
+  public void putComponent(OID oid, String value)
   {
-    return state;
+    currentRdn.put(oid, value);
   }
 
-  public String getTitle()
+  public void putComponent(String name, String value)
   {
-    return title;
+    name = name.trim().toLowerCase();
+    if (name.equals("cn"))
+      putComponent(CN, value);
+    else if (name.equals("c"))
+      putComponent(C, value);
+    else if (name.equals("l"))
+      putComponent(L, value);
+    else if (name.equals("street"))
+      putComponent(STREET, value);
+    else if (name.equals("st"))
+      putComponent(ST, value);
+    else if (name.equals("t"))
+      putComponent(T, value);
+    else if (name.equals("dnq"))
+      putComponent(DNQ, value);
+    else if (name.equals("name"))
+      putComponent(NAME, value);
+    else if (name.equals("givenname"))
+      putComponent(GIVENNAME, value);
+    else if (name.equals("initials"))
+      putComponent(INITIALS, value);
+    else if (name.equals("generation"))
+      putComponent(GENERATION, value);
+    else if (name.equals("email"))
+      putComponent(EMAIL, value);
+    else if (name.equals("dc"))
+      putComponent(DC, value);
+    else if (name.equals("uid"))
+      putComponent(UID, value);
+    else
+      putComponent(new OID(name), value);
   }
 
-  public String getDNQualifier()
+  public void setUnmodifiable()
   {
-    return dnQualifier;
+    if (fixed) return;
+    fixed = true;
+    List newComps = new ArrayList(components.size());
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map rdn = (Map) it.next();
+        rdn = Collections.unmodifiableMap(rdn);
+        newComps.add(rdn);
+      }
+    components = Collections.unmodifiableList(newComps);
+    currentRdn = Collections.EMPTY_MAP;
   }
 
-  public String getSurname()
+  public int hashCode()
   {
-    return surname;
+    int sum = 0;
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map m = (Map) it.next();
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry e = (Map.Entry) it2.next();
+            sum += e.getKey().hashCode();
+            sum += e.getValue().hashCode();
+          }
+      }
+    return sum;
   }
 
-  public String getGivenName()
+  public boolean equals(Object o)
   {
-    return givenName;
+    if (!(o instanceof X500DistinguishedName))
+      return false;
+    if (size() != ((X500DistinguishedName) o).size())
+      return false;
+    for (int i = 0; i < size(); i++)
+      {
+        Map m = (Map) components.get(i);
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry e = (Map.Entry) it2.next();
+            OID oid = (OID) e.getKey();
+            String v1 = (String) e.getValue();
+            String v2 = ((X500DistinguishedName) o).getComponent(oid, i);
+            if (!compressWS(v1).equalsIgnoreCase(compressWS(v2)))
+              return false;
+          }
+      }
+    return true;
   }
 
-  public String getInitials()
+  public String toString()
   {
-    return initials;
+    if (fixed && stringRep != null)
+      return stringRep;
+    StringBuffer str = new StringBuffer();
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map m = (Map) it.next();
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry entry = (Map.Entry) it2.next();
+            OID oid = (OID) entry.getKey();
+            String value = (String) entry.getValue();
+            if (oid.equals(CN))
+              str.append("CN");
+            else if (oid.equals(C))
+              str.append("C");
+            else if (oid.equals(L))
+              str.append("L");
+            else if (oid.equals(ST))
+              str.append("ST");
+            else if (oid.equals(STREET))
+              str.append("STREET");
+            else if (oid.equals(O))
+              str.append("O");
+            else if (oid.equals(OU))
+              str.append("OU");
+            else if (oid.equals(T))
+              str.append("T");
+            else if (oid.equals(DNQ))
+              str.append("DNQ");
+            else if (oid.equals(NAME))
+              str.append("NAME");
+            else
+              str.append(oid.toString());
+            str.append('=');
+            str.append(value);
+            if (it2.hasNext())
+              str.append("+");
+          }
+        if (it.hasNext())
+          str.append(',');
+      }
+    return (stringRep = str.toString());
   }
 
-  public String getGeneration()
+  public byte[] getDer()
   {
-    return generation;
+    if (fixed && encoded != null)
+      return (byte[]) encoded.clone();
+    ArrayList name = new ArrayList(components.size());
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map m = (Map) it.next();
+        if (m.isEmpty())
+          continue;
+        Set rdn = new HashSet();
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry e = (Map.Entry) it.next();
+            ArrayList atav = new ArrayList(2);
+            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, e.getKey()));
+            atav.add(new DERValue(DER.UTF8_STRING, e.getValue()));
+            rdn.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, atav));
+          }
+        name.add(new DERValue(DER.SET|DER.CONSTRUCTED, rdn));
+      }
+    DERValue val = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, name);
+    return (byte[]) (encoded = val.getEncoded()).clone();
   }
 
-  public String getEmail()
-  {
-    return email;
-  }
+  // Own methods.
+  // -------------------------------------------------------------------------
 
-  public String getDomain()
-  {
-    return domainComponent;
-  }
+  private int sep;
 
-  public String getUserID()
+  private void parseString(String str) throws IOException
   {
-    return userid;
+    Reader in = new StringReader(str);
+    while (true)
+      {
+        String key = readAttributeType(in);
+        if (key == null)
+          break;
+        String value = readAttributeValue(in);
+        putComponent(key, value);
+        if (sep == ',')
+          newRelativeDistinguishedName();
+      }
+    setUnmodifiable();
   }
 
-  // Own methods.
-  // ------------------------------------------------------------------------
-
-  private static String unquote(String str)
+  private String readAttributeType(Reader in) throws IOException
   {
-    if (str.startsWith("\"") && str.endsWith("\""))
-      str = str.substring(1, str.length()-1);
-    // XXX needs regex
-    //return str.replaceAll("\\([,+\"\\<>;])", "\1");
-    return str;
+    StringBuffer buf = new StringBuffer();
+    int ch;
+    while ((ch = in.read()) != '=')
+      {
+        if (ch == -1)
+          {
+            if (buf.length() > 0)
+              throw new EOFException();
+            return null;
+          }
+        if (ch > 127)
+          throw new IOException("Invalid char: " + (char) ch);
+        if (Character.isLetterOrDigit((char) ch) || ch == '-' || ch == '.')
+          buf.append((char) ch);
+        else
+          throw new IOException("Invalid char: " + (char) ch);
+      }
+    return buf.toString();
   }
 
-  private void parseDN(String name, boolean rfc2253)
+  private String readAttributeValue(Reader in) throws IOException
   {
-    if (name.length() == 0)
-      throw new IllegalArgumentException("zero-length distinguished name");
-    StreamTokenizer parse = new StreamTokenizer(new StringReader(name));
-    parse.resetSyntax();
-    parse.wordChars('\000', '~');
-    parse.ordinaryChar('#');
-    parse.ordinaryChar(',');
-    parse.ordinaryChar('=');
-    parse.ordinaryChar('<');
-    parse.ordinaryChar('>');
-    parse.ordinaryChar(';');
-    parse.ordinaryChar('\\');
-    parse.quoteChar('"');
-    String attrib = null;
-    String value = null;
-    int token, lastToken = ',';
-    while (true)
+    StringBuffer buf = new StringBuffer();
+    int ch = in.read();
+    if (ch == '#')
       {
-        try
+        while (true)
           {
-            token = parse.nextToken();
+            ch = in.read();
+            if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                || Character.isDigit((char) ch))
+              buf.append((char) ch);
+            else if (ch == '+' || ch == ',')
+              {
+                sep = ch;
+                String hex = buf.toString();
+                return new String(Util.toByteArray(hex));
+              }
+            else
+              throw new IOException("illegal character: " + (char) ch);
           }
-        catch (IOException ioe)
+      }
+    else if (ch == '"')
+      {
+        while (true)
           {
-            throw new IllegalArgumentException();
+            ch = in.read();
+            if (ch == '"')
+              break;
+            else if (ch == '\\')
+              {
+                ch = in.read();
+                if (ch == -1)
+                  throw new EOFException();
+                if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                    || Character.isDigit((char) ch))
+                  {
+                    int i = Character.digit((char) ch, 16) << 4;
+                    ch = in.read();
+                    if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                          || Character.isDigit((char) ch)))
+                      throw new IOException("illegal hex char");
+                    i |= Character.digit((char) ch, 16);
+                    buf.append((char) i);
+                  }
+                else
+                  buf.append((char) ch);
+              }
+            else
+              buf.append((char) ch);
           }
-        switch (token)
+        sep = in.read();
+        if (sep != '+' || sep != ',')
+          throw new IOException("illegal character: " + (char) ch);
+        return buf.toString();
+      }
+    else
+      {
+        while (true)
           {
-            case StreamTokenizer.TT_WORD:
-              if (lastToken == ',' || lastToken == '+' ||
-                  (!rfc2253 && lastToken == ';'))
-                attrib = parse.sval.trim();
-              else if (lastToken == '=')
-                value = unquote(parse.sval.trim());
-              else
-                throw new IllegalArgumentException();
-              break;
-            case '"':
-              if (lastToken == '=')
-                value = parse.sval;
-              else
-                throw new IllegalArgumentException();
-              break;
-            case ';':
-              if (rfc2253)
-                throw new IllegalArgumentException();
-            case ',':
-            case '+':
-              if (attrib == null || value == null)
-                throw new IllegalArgumentException("extraneous separator");
-              try
-                {
-                  setAttribute(new OID(attrib), value);
-                }
-              catch (Exception x)
-                {
-                  setAttribute(attrib, value);
-                }
-              attrib = null;
-              value = null;
-              break;
-            case '=':
-              break;
-            case StreamTokenizer.TT_EOF:
-              return;
-            default:
-              throw new IllegalArgumentException("unknown token " + (char)token
-                + " (" + token + ")");
+            switch (ch)
+              {
+              case '+':
+              case ',':
+                sep = ch;
+                return buf.toString();
+              case '\\':
+                ch = in.read();
+                if (ch == -1)
+                  throw new EOFException();
+                if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                    || Character.isDigit((char) ch))
+                  {
+                    int i = Character.digit((char) ch, 16) << 4;
+                    ch = in.read();
+                    if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                          || Character.isDigit((char) ch)))
+                      throw new IOException("illegal hex char");
+                    i |= Character.digit((char) ch, 16);
+                    buf.append((char) i);
+                  }
+                else
+                  buf.append((char) ch);
+                break;
+              case '=':
+              case '<':
+              case '>':
+              case '#':
+              case ';':
+                throw new IOException("illegal character: " + (char) ch);
+              case -1:
+                throw new EOFException();
+              default:
+                buf.append((char) ch);
+              }
           }
-        lastToken = token;
       }
   }
 
-  private void parseDER(InputStream in) throws IOException
+  private void parseDer(DERReader der) throws IOException
   {
-    DERReader der = new DERReader(in);
     DERValue name = der.read();
     if (!name.isConstructed())
-      throw new ASN1ParsingException("badly formed Name");
+      throw new IOException("malformed Name");
+    encoded = name.getEncoded();
     int len = 0;
     while (len < name.getLength())
       {
         DERValue rdn = der.read();
-        if (rdn.getValue() != DER.CONSTRUCTED_VALUE)
-          throw new ASN1ParsingException("badly formed RDNSequence");
+        if (!rdn.isConstructed())
+          throw new IOException("badly formed RDNSequence");
         int len2 = 0;
         while (len2 < rdn.getLength())
           {
             DERValue atav = der.read();
-            if (atav.getValue() != DER.CONSTRUCTED_VALUE)
-              throw new ASN1ParsingException(
-                "badly formed AttributeTypeAndValue");
-            OID atype = (OID) der.read().getValue();
-            String aval = (String) der.read().getValue();
-            setAttribute(atype, aval);
-            len2 += 1 + atav.getLength()
-                 + DERWriter.definiteEncodingSize(atav.getLength());
+            if (!atav.isConstructed())
+              throw new IOException("badly formed AttributeTypeAndValue");
+            DERValue val = der.read();
+            if (val.getTag() != DER.OBJECT_IDENTIFIER)
+              throw new IOException("badly formed AttributeTypeAndValue");
+            OID oid = (OID) val.getValue();
+            val = der.read();
+            if (!(val.getValue() instanceof String))
+              throw new IOException("badly formed AttributeTypeAndValue");
+            String value = (String) val.getValue();
+            putComponent(oid, value);
+            len2 += atav.getEncodedLength();
           }
-        len += len2 + 1 + DERWriter.definiteEncodingSize(name.getLength());
+        len += rdn.getEncodedLength();
+        if (len < name.getLength())
+          newRelativeDistinguishedName();
       }
+    setUnmodifiable();
   }
 
-  private byte[] encodeDER()
+  private static String compressWS(String str)
   {
-    try
+    StringBuffer buf = new StringBuffer();
+    char lastChar = 0;
+    for (int i = 0; i < str.length(); i++)
       {
-        LinkedList name = new LinkedList();
-        if (commonName != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, CN));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, commonName));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (country != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, C));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, country));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (locality != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, L));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, locality));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (orgUnit != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, OU));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, orgUnit));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (organization != null)
+        char c = str.charAt(i);
+        if (Character.isWhitespace(c))
           {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, O));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, organization));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
+            if (!Character.isWhitespace(lastChar))
+              buf.append(' ');
           }
-        if (street != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, STREET));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, street));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (state != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, ST));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, state));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (title != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, T));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, title));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (dnQualifier != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, DNQ));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, dnQualifier));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (surname != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, NAME));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, surname));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (givenName != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, GIVENNAME));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, givenName));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (initials != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, INITIALS));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, initials));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (generation != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, GENERATION));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, generation));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (email != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, EMAIL));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, email));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (domainComponent != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, DC));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, domainComponent));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        if (userid != null)
-          {
-            HashSet rdn = new HashSet();
-            LinkedList atav = new LinkedList();
-            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, UID));
-            atav.add(new DERValue(DER.PRINTABLE_STRING, userid));
-            rdn.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, atav));
-            name.add(new DERValue(DER.CONSTRUCTED | DER.SET, rdn));
-          }
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, name));
-        return out.toByteArray();
-      }
-    catch (IOException ioe)
-      {
-        throw new Error(ioe);
+        else
+          buf.append(c);
+        lastChar = c;
       }
-  }
-
-  private void setAttribute(String atype, String aval)
-  {
-    if (atype.equals("CN"))
-      commonName = aval;
-    else if (atype.equals("C"))
-      country = aval;
-    else if (atype.equals("L"))
-      locality = aval;
-    else if (atype.equals("ST"))
-      state = aval;
-    else if (atype.equals("STREET"))
-      street = aval;
-    else if (atype.equals("O"))
-      organization = aval;
-    else if (atype.equals("OU"))
-      orgUnit = aval;
-    else if (atype.equals("T"))
-      title = aval;
-    else if (atype.equals("DNQ") || atype.equals("DNQUALIFIER"))
-      dnQualifier = aval;
-    else if (atype.equals("SURNAME"))
-      surname = aval;
-    else if (atype.equals("GIVENNAME"))
-      givenName = aval;
-    else if (atype.equals("INITIALS"))
-      initials = aval;
-    else if (atype.equals("GENERATION"))
-      generation = aval;
-    else if (atype.equals("EMAILADDRESS"))
-      email = aval;
-    else if (atype.equals("DC"))
-      domainComponent = aval;
-    else if (atype.equals("UID"))
-      userid = aval;
-    else
-      throw new IllegalArgumentException("unknown attribute " + atype);
-  }
-
-  private void setAttribute(OID atype, String aval)
-  {
-    if (atype.equals(CN))
-      commonName = aval;
-    else if (atype.equals(C))
-      country = aval;
-    else if (atype.equals(L))
-      locality = aval;
-    else if (atype.equals(ST))
-      state = aval;
-    else if (atype.equals(STREET))
-      street = aval;
-    else if (atype.equals(O))
-      organization = aval;
-    else if (atype.equals(OU))
-      orgUnit = aval;
-    else if (atype.equals(T))
-      title = aval;
-    else if (atype.equals(DNQ))
-      dnQualifier = aval;
-    else if (atype.equals(NAME))
-      surname = aval;
-    else if (atype.equals(GIVENNAME))
-      givenName = aval;
-    else if (atype.equals(INITIALS))
-      initials = aval;
-    else if (atype.equals(GENERATION))
-      generation = aval;
-    else if (atype.equals(EMAIL))
-      email = aval;
-    else if (atype.equals(DC))
-      domainComponent = aval;
-    else if (atype.equals(UID))
-      userid = aval;
-    else
-      throw new IllegalArgumentException("unknown attribute " + atype);
+    return buf.toString().trim();
   }
 }
index e31a85df7b9856cb46ba1b4972477fc9192a6531..adaa003f3cb3a434f462d3803d93456c59237e02 100644 (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;
           }
+        val = der.read();
       }
-    if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0)
+
+    //    crlExtensions   [0] EXPLICIT Extensions OPTIONAL
+    //                        -- if present MUST be v2
+    if (val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0)
       {
-        val = der.read();
+        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 < val.getLength())
+        while (len < exts.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 (!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();
       }
 
-    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();
   }
index 4057c60a22afd6c0753c5883eeddf1768d9cd36e..252737c0eaa3fb40fa12d4483eadfb50c7b72d19 100644 (file)
@@ -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;
   }
 
+  // GnuPKIExtension method.
+  // -------------------------------------------------------------------------
+
+  public Extension getExtension(OID oid)
+  {
+    return (Extension) extensions.get(oid);
+  }
+
+  public Collection getExtensions()
+  {
+    return extensions.values();
+  }
+
   // Own methods.
-  // ------------------------------------------------------------------------
+  // -------------------------------------------------------------------------
 
-  private void parse(int version, InputStream in) throws Exception
+  private void parse(int version, DERReader der) throws Exception
   {
-    DERReader der = new DERReader(in);
+    // 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);
           }
       }
   }
diff --git a/libjava/gnu/java/security/x509/X509CRLSelectorImpl.java b/libjava/gnu/java/security/x509/X509CRLSelectorImpl.java
new file mode 100644 (file)
index 0000000..c409779
--- /dev/null
@@ -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;
+  }
+}
+
diff --git a/libjava/gnu/java/security/x509/X509CertPath.java b/libjava/gnu/java/security/x509/X509CertPath.java
new file mode 100644 (file)
index 0000000..0990abd
--- /dev/null
@@ -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();
+      }
+  }
+}
diff --git a/libjava/gnu/java/security/x509/X509CertSelectorImpl.java b/libjava/gnu/java/security/x509/X509CertSelectorImpl.java
new file mode 100644 (file)
index 0000000..4535cce
--- /dev/null
@@ -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;
+  }
+}
+
index 1ec2e87c2c6cfea2561960c6e78e7c659d688014..25a56d4a8ef343beeb549129fe3be946708b5e14 100644 (file)
@@ -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;
   }
 
 \f// 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, ">>>> "));
   }
 }
diff --git a/libjava/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java b/libjava/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java
new file mode 100644 (file)
index 0000000..6f4e00b
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/BasicConstraints.java b/libjava/gnu/java/security/x509/ext/BasicConstraints.java
new file mode 100644 (file)
index 0000000..f720d22
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/CRLNumber.java b/libjava/gnu/java/security/x509/ext/CRLNumber.java
new file mode 100644 (file)
index 0000000..556aa30
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/CertificatePolicies.java b/libjava/gnu/java/security/x509/ext/CertificatePolicies.java
new file mode 100644 (file)
index 0000000..206fa7e
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/ExtendedKeyUsage.java b/libjava/gnu/java/security/x509/ext/ExtendedKeyUsage.java
new file mode 100644 (file)
index 0000000..e2a98e0
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/Extension.java b/libjava/gnu/java/security/x509/ext/Extension.java
new file mode 100644 (file)
index 0000000..ccbd60c
--- /dev/null
@@ -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, ':');
+    }
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/GeneralNames.java b/libjava/gnu/java/security/x509/ext/GeneralNames.java
new file mode 100644 (file)
index 0000000..fc9a73b
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/IssuerAlternativeNames.java b/libjava/gnu/java/security/x509/ext/IssuerAlternativeNames.java
new file mode 100644 (file)
index 0000000..0d0beb0
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/KeyUsage.java b/libjava/gnu/java/security/x509/ext/KeyUsage.java
new file mode 100644 (file)
index 0000000..7d5d7c6
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/PolicyConstraint.java b/libjava/gnu/java/security/x509/ext/PolicyConstraint.java
new file mode 100644 (file)
index 0000000..0949b50
--- /dev/null
@@ -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
+      + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/PolicyMappings.java b/libjava/gnu/java/security/x509/ext/PolicyMappings.java
new file mode 100644 (file)
index 0000000..827e83f
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java b/libjava/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java
new file mode 100644 (file)
index 0000000..108af4b
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/ReasonCode.java b/libjava/gnu/java/security/x509/ext/ReasonCode.java
new file mode 100644 (file)
index 0000000..779611d
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/SubjectAlternativeNames.java b/libjava/gnu/java/security/x509/ext/SubjectAlternativeNames.java
new file mode 100644 (file)
index 0000000..19c0bde
--- /dev/null
@@ -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 + " ]";
+  }
+}
diff --git a/libjava/gnu/java/security/x509/ext/SubjectKeyIdentifier.java b/libjava/gnu/java/security/x509/ext/SubjectKeyIdentifier.java
new file mode 100644 (file)
index 0000000..2d48f7c
--- /dev/null
@@ -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, ':') + " ]";
+  }
+}
index 4758cf73d7bda40504b4ae92a2384a582d507a6b..448b855b16fd8c1120a8f53eea04184e5efdcc83 100644 (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
@@ -140,7 +140,7 @@ public class TrustAnchor
   public final String getCAName()
   {
     if (caName != null)
-      return caName.toRFC2253();
+      return caName.toString();
     return null;
   }
 
@@ -179,7 +179,7 @@ public class TrustAnchor
   {
     if (trustedCert == null)
       return "[ Trusted CA Public Key=" + caKey + ", Trusted CA Issuer Name="
-        + caName.toRFC2253() + " ]";
+        + caName.toString() + " ]";
     return "[ Trusted CA Certificate=" + trustedCert + " ]";
   }
 }