summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/java/security/provider
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/security/provider')
-rw-r--r--libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java102
-rw-r--r--libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java134
-rw-r--r--libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java171
-rw-r--r--libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java128
-rw-r--r--libjava/classpath/gnu/java/security/provider/DSAParameters.java150
-rw-r--r--libjava/classpath/gnu/java/security/provider/DSASignature.java251
-rw-r--r--libjava/classpath/gnu/java/security/provider/DefaultPolicy.java68
-rw-r--r--libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java303
-rw-r--r--libjava/classpath/gnu/java/security/provider/Gnu.java168
-rw-r--r--libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java115
-rw-r--r--libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java147
-rw-r--r--libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java137
-rw-r--r--libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java164
-rw-r--r--libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java109
-rw-r--r--libjava/classpath/gnu/java/security/provider/MD2withRSA.java54
-rw-r--r--libjava/classpath/gnu/java/security/provider/MD4withRSA.java54
-rw-r--r--libjava/classpath/gnu/java/security/provider/MD5.java338
-rw-r--r--libjava/classpath/gnu/java/security/provider/MD5withRSA.java54
-rw-r--r--libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java701
-rw-r--r--libjava/classpath/gnu/java/security/provider/RSA.java311
-rw-r--r--libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java181
-rw-r--r--libjava/classpath/gnu/java/security/provider/SHA.java242
-rw-r--r--libjava/classpath/gnu/java/security/provider/SHA1PRNG.java137
-rw-r--r--libjava/classpath/gnu/java/security/provider/SHA1withRSA.java61
-rw-r--r--libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java305
-rw-r--r--libjava/classpath/gnu/java/security/provider/package.html46
26 files changed, 4631 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java b/libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java
new file mode 100644
index 00000000000..4bf3d5434ef
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java
@@ -0,0 +1,102 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.CRL;
+import java.security.cert.CRLSelector;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStoreException;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertStoreSpi;
+import java.security.cert.Certificate;
+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/classpath/gnu/java/security/provider/DSAKeyFactory.java b/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java
new file mode 100644
index 00000000000..7e154e27473
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java
@@ -0,0 +1,134 @@
+/* DSAKeyFactory.java -- DSA key factory.
+ Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+/**
+ * DSA key factory.
+ *
+ * @author Casey Marshall (rsdio@metastatic.org)
+ */
+public class DSAKeyFactory extends KeyFactorySpi
+{
+
+ // Constructor.
+ // ------------------------------------------------------------------------
+
+ public DSAKeyFactory()
+ {
+ super();
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (!(keySpec instanceof DSAPrivateKeySpec))
+ throw new InvalidKeySpecException();
+ return new GnuDSAPrivateKey(
+ ((DSAPrivateKeySpec) keySpec).getX(),
+ ((DSAPrivateKeySpec) keySpec).getP(),
+ ((DSAPrivateKeySpec) keySpec).getQ(),
+ ((DSAPrivateKeySpec) keySpec).getG());
+ }
+
+ protected PublicKey engineGeneratePublic(KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (!(keySpec instanceof DSAPublicKeySpec))
+ throw new InvalidKeySpecException();
+ return new GnuDSAPublicKey(
+ ((DSAPublicKeySpec) keySpec).getY(),
+ ((DSAPublicKeySpec) keySpec).getP(),
+ ((DSAPublicKeySpec) keySpec).getQ(),
+ ((DSAPublicKeySpec) keySpec).getG());
+ }
+
+ protected KeySpec engineGetKeySpec(Key key, Class keySpec)
+ throws InvalidKeySpecException
+ {
+ if ((key instanceof DSAPublicKey) &&
+ keySpec.isAssignableFrom(DSAPublicKeySpec.class))
+ {
+ return new DSAPublicKeySpec(((DSAPublicKey) key).getY(),
+ ((DSAPublicKey) key).getParams().getP(),
+ ((DSAPublicKey) key).getParams().getQ(),
+ ((DSAPublicKey) key).getParams().getG());
+ }
+ if ((key instanceof DSAPrivateKey) &&
+ keySpec.isAssignableFrom(DSAPrivateKeySpec.class))
+ {
+ return new DSAPrivateKeySpec(((DSAPrivateKey) key).getX(),
+ ((DSAPrivateKey) key).getParams().getP(),
+ ((DSAPrivateKey) key).getParams().getQ(),
+ ((DSAPrivateKey) key).getParams().getG());
+ }
+ throw new InvalidKeySpecException();
+ }
+
+ protected Key engineTranslateKey(Key key) throws InvalidKeyException
+ {
+ if ((key instanceof GnuDSAPublicKey) || (key instanceof GnuDSAPrivateKey))
+ return key;
+ if (key instanceof DSAPublicKey)
+ return new GnuDSAPublicKey(((DSAPublicKey) key).getY(),
+ ((DSAPublicKey) key).getParams().getP(),
+ ((DSAPublicKey) key).getParams().getQ(),
+ ((DSAPublicKey) key).getParams().getG());
+ if (key instanceof DSAPrivateKey)
+ return new GnuDSAPrivateKey(((DSAPrivateKey) key).getX(),
+ ((DSAPrivateKey) key).getParams().getP(),
+ ((DSAPrivateKey) key).getParams().getQ(),
+ ((DSAPrivateKey) key).getParams().getG());
+ throw new InvalidKeyException();
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java
new file mode 100644
index 00000000000..2c643d5c367
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java
@@ -0,0 +1,171 @@
+/* GnuDSAKeyPairGenerator.java --- Gnu DSA Key Pair Generator
+ Copyright (C) 1999 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGeneratorSpi;
+import java.security.SecureRandom;
+import java.security.interfaces.DSAParams;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.util.Random;
+
+public class DSAKeyPairGenerator extends KeyPairGeneratorSpi
+ implements java.security.interfaces.DSAKeyPairGenerator
+{
+int keysize;
+SecureRandom random;
+private BigInteger q = null; // the small prime
+private BigInteger p = null; // the big prime
+private BigInteger g = null;
+
+DSAKeyPairGenerator()
+{
+ keysize = 1024;
+}
+
+public void initialize(int keysize, SecureRandom random)
+{
+ //if( ((keysize % 64) != 0) || (keysize < 512) || (keysize > 1024) )
+ // throw new InvalidAlgorithmParameterException("Invalid key size");
+
+ this.keysize = keysize;
+ this.random = random;
+}
+
+public void initialize(AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+{
+ if( !( params instanceof DSAParameterSpec ) )
+ throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec");
+
+ DSAParameterSpec dsaparameterspec = (DSAParameterSpec)params;
+ p = dsaparameterspec.getP();
+ q = dsaparameterspec.getQ();
+ g = dsaparameterspec.getG();
+ this.random = random;
+}
+
+public void initialize(DSAParams params, SecureRandom random)
+ throws InvalidParameterException
+{
+ if(params.getP() != null)
+ p = params.getP();
+ else
+ throw new InvalidParameterException();
+
+ if(params.getQ() != null)
+ q = params.getQ();
+ else
+ throw new InvalidParameterException();
+
+ if(params.getG() != null)
+ g = params.getG();
+ else
+ throw new InvalidParameterException();
+
+ this.random = random;
+}
+
+public void initialize(int modlen, boolean genParams, SecureRandom random)
+ throws InvalidParameterException
+{
+ if( ((modlen % 64) != 0) || (modlen < 512) || (modlen > 1024) )
+ throw new InvalidParameterException();
+
+ if( (genParams == false) && (modlen != 512) && (modlen != 768) && (modlen != 1024) )
+ throw new InvalidParameterException();
+ this.keysize = modlen;
+ this.random = random;
+ p = null;
+ q = null;
+ g = null;
+}
+
+public KeyPair generateKeyPair()
+{
+ if( getDefaults() == false) {
+ try {
+ AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA");
+ AlgorithmParameters apDSA = apgDSA.generateParameters();
+ DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class );
+ p = dsaparameterspec.getP();
+ q = dsaparameterspec.getQ();
+ g = dsaparameterspec.getG();
+ } catch ( Exception e ) {
+ return null;
+ }
+ }
+
+ BigInteger x = new BigInteger( 159, new Random() );
+
+ BigInteger y = g.modPow( x, p );
+
+ return new KeyPair( new GnuDSAPublicKey(y,p,q,g), new GnuDSAPrivateKey(x,p,q,g));
+ //return new KeyPair( public, private );
+}
+
+//These constants are Sun's Constants copied from the
+//Cryptography Specification
+private boolean getDefaults()
+{
+ if( keysize == 512) {
+ p = new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16);
+ q = new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16);
+ g = new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16);
+ return true;
+ } else if( keysize == 768) {
+ p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16);
+ q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16);
+ g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16);
+ } else if( keysize == 512) {
+ p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16);
+ q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16);
+ g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16);
+ }
+ return false;
+}
+
+}
diff --git a/libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java b/libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java
new file mode 100644
index 00000000000..ccec1136cd3
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java
@@ -0,0 +1,128 @@
+/* DSAParameterGenerator.java --- DSA Parameter Generator Implementation
+ Copyright (C) 1999 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.util.Prime;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameterGeneratorSpi;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Random;
+
+public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi
+{
+ private int size;
+ private SecureRandom random = null;
+
+ public DSAParameterGenerator()
+ {
+ size = 1024;
+ }
+
+ public void engineInit(int size, SecureRandom random)
+ {
+ if( (size < 512) || (size > 1024) || ( (size % 64) != 0) )
+ //throw new InvalidAlgorithmParameterException("Invalid Size");
+ return;
+ this.size = size;
+ this.random = random;
+ }
+
+ public void engineInit(AlgorithmParameterSpec genParamSpec, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if( !( genParamSpec instanceof DSAParameterSpec ) )
+ throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec");
+
+ DSAParameterSpec dsaparameterspec = (DSAParameterSpec)genParamSpec;
+ int tmp = dsaparameterspec.getP().bitLength();
+
+ if( (tmp < 512) || (tmp > 1024) || ( (tmp % 64) != 0) )
+ throw new InvalidAlgorithmParameterException("Invalid Size");
+
+ this.random = random;
+ }
+
+ //For more information see IEEE P1363 A.16.1 (10/05/98 Draft)
+ public AlgorithmParameters engineGenerateParameters()
+ {
+ DSAParameterSpec dsaparameterspec;
+
+ int L = size;
+ BigInteger r, p, k, h, g;
+
+ //q 2^159 < q < 2^160
+ r = Prime.generateRandomPrime( 159, 160, BigInteger.valueOf(1));
+
+ // 2^(L-1) < p < 2^L
+ p = Prime.generateRandomPrime( r, BigInteger.valueOf(1), L - 1, L, BigInteger.valueOf(1));
+
+ k = p.subtract( BigInteger.valueOf(1) );
+ k = k.divide( r );
+
+ Random rand = new Random();
+ h = BigInteger.valueOf(1);
+
+ for(;;) {
+ h = h.add(BigInteger.valueOf( 1 ) );
+
+ g = h.modPow(k, p);
+
+ if( g.compareTo( BigInteger.valueOf(1) ) != 1 )
+ break;
+ }
+
+ try {
+ dsaparameterspec = new DSAParameterSpec(p, r, g);
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
+ ap.init( dsaparameterspec );
+ return ap;
+ } catch ( NoSuchAlgorithmException nsae ) {
+ return null;
+ } catch ( InvalidParameterSpecException ipse) {
+ return null;
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/DSAParameters.java b/libjava/classpath/gnu/java/security/provider/DSAParameters.java
new file mode 100644
index 00000000000..77d648956ee
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/DSAParameters.java
@@ -0,0 +1,150 @@
+/* DSAParameters.java --- DSA Parameters Implementation
+ Copyright (C) 1999, 2003, 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.io.ASN1ParsingException;
+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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.ArrayList;
+
+/*
+ ASN.1 Encoding for DSA from rfc2459
+
+ id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040)
+ x9cm(4) 1 }
+
+ Dss-Parms ::= SEQUENCE {
+ p INTEGER,
+ q INTEGER,
+ g INTEGER }
+
+*/
+public class DSAParameters extends AlgorithmParametersSpi
+{
+private BigInteger q; // the small prime
+private BigInteger p; // the big prime
+private BigInteger g;
+
+
+public void engineInit(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+{
+ if( paramSpec instanceof DSAParameterSpec ) {
+ DSAParameterSpec dsaParamSpec = (DSAParameterSpec)paramSpec;
+ p = dsaParamSpec.getP();
+ q = dsaParamSpec.getQ();
+ g = dsaParamSpec.getG();
+ }
+ else
+ throw new InvalidParameterSpecException("Only accepts DSAParameterSpec");
+}
+
+public void engineInit(byte[] params)
+ throws IOException
+{
+ DERReader in = new DERReader(params);
+ DERValue val = in.read();
+ if (val.getValue() != DER.CONSTRUCTED_VALUE)
+ throw new ASN1ParsingException("badly formed parameters");
+ try
+ {
+ p = (BigInteger) in.read().getValue();
+ q = (BigInteger) in.read().getValue();
+ g = (BigInteger) in.read().getValue();
+ }
+ catch (Exception x)
+ {
+ throw new ASN1ParsingException("badly formed parameters");
+ }
+}
+
+public void engineInit(byte[] params, String format)
+ throws IOException
+{
+ if( !format.equals("ASN.1") )
+ throw new IOException("Invalid Format: Only accepts ASN.1");
+ engineInit( params );
+}
+
+public AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec)
+ throws InvalidParameterSpecException
+{
+ if( paramSpec.isAssignableFrom(DSAParameterSpec.class) )
+ return new DSAParameterSpec(p, q, g);
+ else
+ throw new InvalidParameterSpecException("Only accepts DSAParameterSpec");
+}
+
+public byte[] engineGetEncoded()
+ throws IOException
+{
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ArrayList seq = new ArrayList(3);
+ seq.add(new DERValue(DER.INTEGER, p));
+ seq.add(new DERValue(DER.INTEGER, q));
+ seq.add(new DERValue(DER.INTEGER, g));
+ DERWriter.write(bout, new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, seq));
+ return bout.toByteArray();
+}
+
+
+public byte[] engineGetEncoded(String format)
+ throws IOException
+{
+ if( !format.equals("ASN.1") )
+ throw new IOException("Invalid Format: Only accepts ASN.1");
+ return engineGetEncoded();
+}
+
+public String engineToString()
+{
+ return ("q: " + q + " p: " + p + " g: " + g);
+}
+
+}
diff --git a/libjava/classpath/gnu/java/security/provider/DSASignature.java b/libjava/classpath/gnu/java/security/provider/DSASignature.java
new file mode 100644
index 00000000000..1d3875d28e3
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/DSASignature.java
@@ -0,0 +1,251 @@
+/* DSASignature.java --
+ Copyright (C) 1999, 2003, 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Random;
+
+public class DSASignature extends SignatureSpi
+{
+ private DSAPublicKey publicKey;
+ private DSAPrivateKey privateKey;
+ private final MessageDigest digest;
+ private final SecureRandom random;
+
+ public DSASignature() throws NoSuchAlgorithmException
+ {
+ random = new SecureRandom();
+ digest = MessageDigest.getInstance ("SHA1");
+ }
+
+ private void init()
+ {
+ digest.reset();
+ }
+
+ public void engineInitVerify (PublicKey publicKey)
+ throws InvalidKeyException
+ {
+ if (publicKey instanceof DSAPublicKey)
+ this.publicKey = (DSAPublicKey) publicKey;
+ else
+ throw new InvalidKeyException();
+ init();
+ }
+
+ public void engineInitSign (PrivateKey privateKey)
+ throws InvalidKeyException
+ {
+ if (privateKey instanceof DSAPrivateKey)
+ this.privateKey = (DSAPrivateKey) privateKey;
+ else
+ throw new InvalidKeyException ("not a DSA private key");
+
+ init();
+ }
+
+ public void engineInitSign (PrivateKey privateKey,
+ SecureRandom random)
+ throws InvalidKeyException
+ {
+ if (privateKey instanceof DSAPrivateKey)
+ this.privateKey = (DSAPrivateKey) privateKey;
+ else
+ throw new InvalidKeyException ("not a DSA private key");
+
+ appRandom = random;
+ init();
+ }
+
+ public void engineUpdate(byte b)
+ throws SignatureException
+ {
+ digest.update (b);
+ }
+
+ public void engineUpdate (byte[] b, int off, int len)
+ throws SignatureException
+ {
+ digest.update (b, off, len);
+ }
+
+ public byte[] engineSign() throws SignatureException
+ {
+ if (privateKey == null)
+ throw new SignatureException ("not initialized for signing");
+
+ try
+ {
+ BigInteger g = privateKey.getParams().getG();
+ BigInteger p = privateKey.getParams().getP();
+ BigInteger q = privateKey.getParams().getQ();
+
+ BigInteger x = privateKey.getX();
+
+ BigInteger k = new BigInteger (159, appRandom != null ? appRandom : random);
+
+ BigInteger r = g.modPow(k, p);
+ r = r.mod(q);
+
+ byte bytes[] = digest.digest();
+ BigInteger sha = new BigInteger (1, bytes);
+
+ BigInteger s = sha.add (x.multiply (r));
+ s = s.multiply (k.modInverse(q)).mod (q);
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ArrayList seq = new ArrayList (2);
+ seq.add(0, new DERValue (DER.INTEGER, r));
+ seq.add(1, new DERValue (DER.INTEGER, s));
+ DERWriter.write (bout, new DERValue (DER.CONSTRUCTED | DER.SEQUENCE, seq));
+ return bout.toByteArray();
+ }
+ catch (IOException ioe)
+ {
+ SignatureException se = new SignatureException();
+ se.initCause (ioe);
+ throw se;
+ }
+ catch (ArithmeticException ae)
+ {
+ SignatureException se = new SignatureException();
+ se.initCause (ae);
+ throw se;
+ }
+ }
+
+ public int engineSign (byte[] outbuf, int offset, int len)
+ throws SignatureException
+ {
+ byte tmp[] = engineSign();
+ if (tmp.length > len)
+ throw new SignatureException ("output buffer too short");
+ System.arraycopy (tmp, 0, outbuf, offset, tmp.length);
+ return tmp.length;
+ }
+
+ public boolean engineVerify (byte[] sigBytes)
+ throws SignatureException
+ {
+ // Decode sigBytes from ASN.1 DER encoding
+ try
+ {
+ DERReader in = new DERReader (sigBytes);
+ DERValue val = in.read();
+ if (!val.isConstructed())
+ throw new SignatureException ("badly formed signature");
+ BigInteger r = (BigInteger) in.read().getValue();
+ BigInteger s = (BigInteger) in.read().getValue();
+
+ BigInteger g = publicKey.getParams().getG();
+ BigInteger p = publicKey.getParams().getP();
+ BigInteger q = publicKey.getParams().getQ();
+
+ BigInteger y = publicKey.getY();
+
+ BigInteger w = s.modInverse (q);
+
+ byte bytes[] = digest.digest();
+ BigInteger sha = new BigInteger (1, bytes);
+
+ BigInteger u1 = w.multiply (sha).mod ( q );
+
+ BigInteger u2 = r.multiply (w).mod(q);
+
+ BigInteger v = g.modPow (u1, p).multiply (y.modPow (u2, p)).mod (p).mod (q);
+
+ if (v.equals (r))
+ return true;
+ else
+ return false;
+ }
+ catch (IOException ioe)
+ {
+ SignatureException se = new SignatureException ("badly formed signature");
+ se.initCause (ioe);
+ throw se;
+ }
+ }
+
+ public void engineSetParameter (String param,
+ Object value)
+ throws InvalidParameterException
+ {
+ throw new InvalidParameterException();
+ }
+
+ public void engineSetParameter (AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidParameterException();
+
+ }
+
+ public Object engineGetParameter (String param)
+ throws InvalidParameterException
+ {
+ throw new InvalidParameterException();
+ }
+
+ public Object clone() throws CloneNotSupportedException
+ {
+ return super.clone();
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/DefaultPolicy.java b/libjava/classpath/gnu/java/security/provider/DefaultPolicy.java
new file mode 100644
index 00000000000..d42be6c908f
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/DefaultPolicy.java
@@ -0,0 +1,68 @@
+/* DefaultPolicy.java --
+ Copyright (C) 2001, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+
+/**
+ * This is just a stub policy implementation which grants all permissions
+ * to any code source. FIXME: This should be replaced with a real
+ * implementation that reads the policy configuration from a file, like
+ * $JAVA_HOME/jre/lib/security/java.security.
+ */
+public class DefaultPolicy extends Policy
+{
+ static Permission allPermission = new AllPermission();
+
+ public PermissionCollection getPermissions(CodeSource codesource)
+ {
+ Permissions perms = new Permissions();
+ perms.add(allPermission);
+ return perms;
+ }
+
+ public void refresh()
+ {
+ // Nothing.
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java b/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java
new file mode 100644
index 00000000000..2bf0fff809e
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java
@@ -0,0 +1,303 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+import gnu.java.security.der.BitString;
+import gnu.java.security.der.DERReader;
+import gnu.java.security.der.DERValue;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Key;
+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.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+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;
+
+/**
+ * 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");
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/Gnu.java b/libjava/classpath/gnu/java/security/provider/Gnu.java
new file mode 100644
index 00000000000..849f63c1601
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/Gnu.java
@@ -0,0 +1,168 @@
+/* Gnu.java --- Gnu provider main class
+ Copyright (C) 1999, 2002, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.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, 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");
+ put("Alg.Alias.MessageDigest.SHA-160", "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/classpath/gnu/java/security/provider/GnuDHPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java
new file mode 100644
index 00000000000..6e13f6bf20f
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java
@@ -0,0 +1,115 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+import gnu.java.security.der.BitString;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+
+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/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java b/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java
new file mode 100644
index 00000000000..aac2faab229
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java
@@ -0,0 +1,147 @@
+/* GnuDSAPrivateKey.java --- Gnu DSA Private Key
+ Copyright (C) 1999,2003,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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+import gnu.java.security.der.DERWriter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.spec.DSAParameterSpec;
+import java.util.ArrayList;
+
+public class GnuDSAPrivateKey implements DSAPrivateKey
+{
+ private byte[] encodedKey;
+ BigInteger x;
+ BigInteger p;
+ BigInteger q;
+ BigInteger g;
+
+ public GnuDSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g )
+ {
+ this.x = x;
+ this.p = p;
+ this.q = q;
+ this.g = g;
+ }
+
+ public String getAlgorithm()
+ {
+ return "DSA";
+ }
+
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Encodes this key as a <code>PrivateKeyInfo</code>, as described in
+ * PKCS #8. The ASN.1 specification for this structure is:
+ *
+ * <blockquote><pre>
+ * PrivateKeyInfo ::= SEQUENCE {
+ * version Version,
+ * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ * privateKey PrivateKey,
+ * attributes [0] IMPLICIT Attributes OPTIONAL }
+ *
+ * Version ::= INTEGER
+ *
+ * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * PrivateKey ::= OCTET STRING
+ *
+ * Attributes ::= SET OF Attribute
+ * </pre></blockquote>
+ *
+ * <p>DSA private keys (in Classpath at least) have no attributes.
+ */
+ public byte[] getEncoded()
+ {
+ if (encodedKey != null)
+ return (byte[]) encodedKey.clone();
+ try
+ {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ArrayList pki = new ArrayList(3);
+ pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
+ ArrayList algId = new ArrayList(2);
+ algId.add(new DERValue(DER.OBJECT_IDENTIFIER,
+ new OID("1.2.840.10040.4.1")));
+ ArrayList algParams = new ArrayList(3);
+ algParams.add(new DERValue(DER.INTEGER, p));
+ algParams.add(new DERValue(DER.INTEGER, q));
+ algParams.add(new DERValue(DER.INTEGER, g));
+ algId.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algParams));
+ pki.add(new DERValue(DER.OCTET_STRING, x.toByteArray()));
+ DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pki));
+ return (byte[]) (encodedKey = out.toByteArray()).clone();
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ }
+
+ public DSAParams getParams()
+ {
+ return (DSAParams)(new DSAParameterSpec(p,q,g));
+ }
+
+ public BigInteger getX()
+ {
+ return x;
+ }
+
+ public String toString()
+ {
+ return "GnuDSAPrivateKey: x="
+ + (x != null ? x.toString(16) : "null") + " p="
+ + (p != null ? p.toString(16) : "null") + " q="
+ + (q != null ? q.toString(16) : "null") + " g="
+ + (g != null ? g.toString(16) : "null");
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java
new file mode 100644
index 00000000000..41195fa992c
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java
@@ -0,0 +1,137 @@
+/* GnuDSAPublicKey.java --- Gnu DSA Public Key
+ Copyright (C) 1999,2003,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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAParameterSpec;
+import java.util.ArrayList;
+
+public class GnuDSAPublicKey implements DSAPublicKey
+{
+ private byte[] encodedKey;
+ BigInteger y;
+ BigInteger p;
+ BigInteger q;
+ BigInteger g;
+
+ public GnuDSAPublicKey(BigInteger y, BigInteger p, BigInteger q, BigInteger g )
+ {
+ this.y = y;
+ this.p = p;
+ this.q = q;
+ this.g = g;
+ }
+
+ public String getAlgorithm()
+ {
+ return "DSA";
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ /**
+ * The encoded form of DSA public keys is:
+ *
+ * <blockquote><pre>
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ * </pre></blockquote>
+ */
+ public byte[] getEncoded()
+ {
+ if (encodedKey != null)
+ return (byte[]) encodedKey.clone();
+ try
+ {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ArrayList spki = new ArrayList(2);
+ ArrayList alg = new ArrayList(2);
+ alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
+ new OID("1.2.840.113549.1.1.1")));
+ ArrayList params = new ArrayList(3);
+ params.add(new DERValue(DER.INTEGER, p));
+ params.add(new DERValue(DER.INTEGER, q));
+ params.add(new DERValue(DER.INTEGER, g));
+ alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, params));
+ spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
+ spki.add(new DERValue(DER.BIT_STRING, new BitString(y.toByteArray())));
+ DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki));
+ return (byte[]) (encodedKey = out.toByteArray()).clone();
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ }
+
+ public DSAParams getParams()
+ {
+ if (p == null || q == null || g == null)
+ return null;
+ return (DSAParams)(new DSAParameterSpec(p,q,g));
+ }
+
+ public BigInteger getY()
+ {
+ return y;
+ }
+
+ public String toString()
+ {
+ return
+ "GnuDSAPublicKey: y=" + (y != null ? y.toString(16) : "(null)") +
+ " p=" + (p != null ? p.toString(16) : "(null)") +
+ " q=" + (q != null ? q.toString(16) : "(null)") +
+ " g=" + (g != null ? g.toString(16) : "(null)");
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java b/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java
new file mode 100644
index 00000000000..b09fc88bc5c
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java
@@ -0,0 +1,164 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+
+import java.math.BigInteger;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.util.ArrayList;
+
+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/classpath/gnu/java/security/provider/GnuRSAPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java
new file mode 100644
index 00000000000..a35e761c066
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+import gnu.java.security.der.BitString;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERValue;
+
+import java.math.BigInteger;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.ArrayList;
+
+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/classpath/gnu/java/security/provider/MD2withRSA.java b/libjava/classpath/gnu/java/security/provider/MD2withRSA.java
new file mode 100644
index 00000000000..a72ae5588dc
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/MD2withRSA.java
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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/classpath/gnu/java/security/provider/MD4withRSA.java b/libjava/classpath/gnu/java/security/provider/MD4withRSA.java
new file mode 100644
index 00000000000..76a6a1ad033
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/MD4withRSA.java
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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/classpath/gnu/java/security/provider/MD5.java b/libjava/classpath/gnu/java/security/provider/MD5.java
new file mode 100644
index 00000000000..1534eb91089
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/MD5.java
@@ -0,0 +1,338 @@
+/* MD5.java -- Class implementing the MD5 algorithm as specified in RFC1321.
+ Copyright (C) 1999, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+/**
+ This class implements the MD5 algorithm as described in RFC1321.
+
+ @see java.security.MessageDigest
+*/
+public class MD5 extends MessageDigest implements Cloneable
+{
+ private final int W[] = new int[16];
+ private long bytecount;
+ private int A;
+ private int B;
+ private int C;
+ private int D;
+
+ public MD5()
+ {
+ super("MD5");
+ engineReset ();
+ }
+
+ public Object clone()
+ {
+ return new MD5 (this);
+ }
+
+ private MD5 (MD5 copy)
+ {
+ this ();
+ bytecount = copy.bytecount;
+ A = copy.A;
+ B = copy.B;
+ C = copy.C;
+ D = copy.D;
+ System.arraycopy (copy.W, 0, W, 0, 16);
+ }
+
+ public int engineGetDigestLength()
+ {
+ return 16;
+ }
+
+ // Intialize the A,B,C,D needed for the hash
+ public void engineReset()
+ {
+ bytecount = 0;
+ A = 0x67452301;
+ B = 0xefcdab89;
+ C = 0x98badcfe;
+ D = 0x10325476;
+ for(int i = 0; i < 16; i++)
+ W[i] = 0;
+ }
+
+ public void engineUpdate (byte b)
+ {
+ int i = (int)bytecount % 64;
+ int shift = (3 - i % 4) * 8;
+ int idx = i / 4;
+
+ // if you could index ints, this would be: W[idx][shift/8] = b
+ W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift);
+
+ // if we've filled up a block, then process it
+ if ((++ bytecount) % 64 == 0)
+ munch ();
+ }
+
+ public void engineUpdate (byte bytes[], int off, int len)
+ {
+ if (len < 0)
+ throw new ArrayIndexOutOfBoundsException ();
+
+ int end = off + len;
+ while (off < end)
+ engineUpdate (bytes[off++]);
+ }
+
+ public byte[] engineDigest()
+ {
+ long bitcount = bytecount * 8;
+ engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding
+
+ // add the rest of the padding to fill this block out, but leave 8
+ // bytes to put in the original bytecount
+ while ((int)bytecount % 64 != 56)
+ engineUpdate ((byte)0);
+
+ // add the length of the original, unpadded block to the end of
+ // the padding
+ W[14] = SWAP((int)(0xffffffff & bitcount));
+ W[15] = SWAP((int)(0xffffffff & (bitcount >>> 32)));
+ bytecount += 8;
+
+ // digest the fully padded block
+ munch ();
+
+ A = SWAP(A);
+ B = SWAP(B);
+ C = SWAP(C);
+ D = SWAP(D);
+ byte[] result = new byte[] {(byte)(A >>> 24), (byte)(A >>> 16),
+ (byte)(A >>> 8), (byte)A,
+ (byte)(B >>> 24), (byte)(B >>> 16),
+ (byte)(B >>> 8), (byte)B,
+ (byte)(C >>> 24), (byte)(C >>> 16),
+ (byte)(C >>> 8), (byte)C,
+ (byte)(D >>> 24), (byte)(D >>> 16),
+ (byte)(D >>> 8), (byte)D};
+
+ engineReset ();
+ return result;
+ }
+
+ private int F( int X, int Y, int Z)
+ {
+ return ((X & Y) | (~X & Z));
+ }
+
+ private int G( int X, int Y, int Z)
+ {
+ return ((X & Z) | (Y & ~Z));
+ }
+
+ private int H( int X, int Y, int Z)
+ {
+ return (X ^ Y ^ Z);
+ }
+
+ private int I( int X, int Y, int Z)
+ {
+ return (Y ^ (X | ~Z));
+ }
+
+ private int rotateLeft( int i, int count)
+ {
+ //Taken from FIPS 180-1
+ return ( (i << count) | (i >>> (32 - count)) ) ;
+ }
+
+ /* Round 1. */
+ private int FF( int a, int b, int c, int d, int k, int s, int i)
+ {
+ /* Let [abcd k s i] denote the operation */
+ a += F(b,c,d) + k + i;
+ return b + rotateLeft(a, s);
+ }
+ /* Round 2. */
+ private int GG( int a, int b, int c, int d, int k, int s, int i)
+ {
+ /* Let [abcd k s i] denote the operation */
+ a += G(b,c,d) + k + i;
+ return b + rotateLeft(a, s);
+ }
+ /* Round 3. */
+ private int HH( int a, int b, int c, int d, int k, int s, int i)
+ {
+ /* Let [abcd k s t] denote the operation */
+ a += H(b,c,d) + k + i;
+ return b + rotateLeft(a, s);
+ }
+
+ /* Round 4. */
+ private int II( int a, int b, int c, int d, int k, int s, int i)
+ {
+ /* Let [abcd k s t] denote the operation */
+ a += I(b,c,d) + k + i;
+ return b + rotateLeft(a, s);
+ }
+
+ private int SWAP(int n)
+ {
+ //Copied from md5.c in FSF Gnu Privacy Guard 0.9.2
+ return (( (0xff & n) << 24) | ((n & 0xff00) << 8) | ((n >>> 8) & 0xff00) | (n >>> 24));
+ }
+
+ private void munch()
+ {
+ int AA,BB,CC,DD, j;
+ int X[] = new int[16];
+
+ /* Copy block i into X. */
+ for(j = 0; j < 16; j++)
+ X[j] = SWAP(W[j]);
+
+ /* Save A as AA, B as BB, C as CC, and D as DD. */
+ AA = A;
+ BB = B;
+ CC = C;
+ DD = D;
+
+ /* The hex constants are from md5.c
+ in FSF Gnu Privacy Guard 0.9.2 */
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ A = FF(A,B,C,D, X[0], 7, 0xd76aa478);
+ D = FF(D,A,B,C, X[1], 12, 0xe8c7b756);
+ C = FF(C,D,A,B, X[2], 17, 0x242070db);
+ B = FF(B,C,D,A, X[3], 22, 0xc1bdceee);
+
+ A = FF(A,B,C,D, X[4], 7, 0xf57c0faf);
+ D = FF(D,A,B,C, X[5], 12, 0x4787c62a);
+ C = FF(C,D,A,B, X[6], 17, 0xa8304613);
+ B = FF(B,C,D,A, X[7], 22, 0xfd469501);
+
+ A = FF(A,B,C,D, X[8], 7, 0x698098d8);
+ D = FF(D,A,B,C, X[9], 12, 0x8b44f7af);
+ C = FF(C,D,A,B, X[10], 17, 0xffff5bb1);
+ B = FF(B,C,D,A, X[11], 22, 0x895cd7be);
+
+ A = FF(A,B,C,D, X[12], 7, 0x6b901122);
+ D = FF(D,A,B,C, X[13], 12, 0xfd987193);
+ C = FF(C,D,A,B, X[14], 17, 0xa679438e);
+ B = FF(B,C,D,A, X[15], 22, 0x49b40821);
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ A = GG(A,B,C,D, X[1], 5, 0xf61e2562);
+ D = GG(D,A,B,C, X[6], 9, 0xc040b340);
+ C = GG(C,D,A,B, X[11], 14, 0x265e5a51);
+ B = GG(B,C,D,A, X[0], 20, 0xe9b6c7aa);
+
+ A = GG(A,B,C,D, X[5], 5, 0xd62f105d);
+ D = GG(D,A,B,C, X[10], 9, 0x02441453);
+ C = GG(C,D,A,B, X[15], 14, 0xd8a1e681);
+ B = GG(B,C,D,A, X[4], 20, 0xe7d3fbc8);
+
+ A = GG(A,B,C,D, X[9], 5, 0x21e1cde6);
+ D = GG(D,A,B,C, X[14], 9, 0xc33707d6);
+ C = GG(C,D,A,B, X[3], 14, 0xf4d50d87);
+ B = GG(B,C,D,A, X[8], 20, 0x455a14ed);
+
+ A = GG(A,B,C,D, X[13], 5, 0xa9e3e905);
+ D = GG(D,A,B,C, X[2], 9, 0xfcefa3f8);
+ C = GG(C,D,A,B, X[7], 14, 0x676f02d9);
+ B = GG(B,C,D,A, X[12], 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ A = HH(A,B,C,D, X[5], 4, 0xfffa3942);
+ D = HH(D,A,B,C, X[8], 11, 0x8771f681);
+ C = HH(C,D,A,B, X[11], 16, 0x6d9d6122);
+ B = HH(B,C,D,A, X[14], 23, 0xfde5380c);
+
+ A = HH(A,B,C,D, X[1], 4, 0xa4beea44);
+ D = HH(D,A,B,C, X[4], 11, 0x4bdecfa9);
+ C = HH(C,D,A,B, X[7], 16, 0xf6bb4b60);
+ B = HH(B,C,D,A, X[10], 23, 0xbebfbc70);
+
+ A = HH(A,B,C,D, X[13], 4, 0x289b7ec6);
+ D = HH(D,A,B,C, X[0], 11, 0xeaa127fa);
+ C = HH(C,D,A,B, X[3], 16, 0xd4ef3085);
+ B = HH(B,C,D,A, X[6], 23, 0x04881d05);
+
+ A = HH(A,B,C,D, X[9], 4, 0xd9d4d039);
+ D = HH(D,A,B,C, X[12], 11, 0xe6db99e5);
+ C = HH(C,D,A,B, X[15], 16, 0x1fa27cf8);
+ B = HH(B,C,D,A, X[2], 23, 0xc4ac5665);
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ A = II(A,B,C,D, X[0], 6, 0xf4292244);
+ D = II(D,A,B,C, X[7], 10, 0x432aff97);
+ C = II(C,D,A,B, X[14], 15, 0xab9423a7);
+ B = II(B,C,D,A, X[5], 21, 0xfc93a039);
+
+ A = II(A,B,C,D, X[12], 6, 0x655b59c3);
+ D = II(D,A,B,C, X[3], 10, 0x8f0ccc92);
+ C = II(C,D,A,B, X[10], 15, 0xffeff47d);
+ B = II(B,C,D,A, X[1], 21, 0x85845dd1);
+
+ A = II(A,B,C,D, X[8], 6, 0x6fa87e4f);
+ D = II(D,A,B,C, X[15], 10, 0xfe2ce6e0);
+ C = II(C,D,A,B, X[6], 15, 0xa3014314);
+ B = II(B,C,D,A, X[13], 21, 0x4e0811a1);
+
+ A = II(A,B,C,D, X[4], 6, 0xf7537e82);
+ D = II(D,A,B,C, X[11], 10, 0xbd3af235);
+ C = II(C,D,A,B, X[2], 15, 0x2ad7d2bb);
+ B = II(B,C,D,A, X[9], 21, 0xeb86d391);
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ A = A + AA;
+ B = B + BB;
+ C = C + CC;
+ D = D + DD;
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/MD5withRSA.java b/libjava/classpath/gnu/java/security/provider/MD5withRSA.java
new file mode 100644
index 00000000000..721d897ed24
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/MD5withRSA.java
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java
new file mode 100644
index 00000000000..1268b169d9b
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java
@@ -0,0 +1,701 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+import gnu.java.security.x509.GnuPKIExtension;
+import gnu.java.security.x509.PolicyNodeImpl;
+import gnu.java.security.x509.X509CRLSelectorImpl;
+import gnu.java.security.x509.X509CertSelectorImpl;
+import gnu.java.security.x509.ext.BasicConstraints;
+import gnu.java.security.x509.ext.CertificatePolicies;
+import gnu.java.security.x509.ext.Extension;
+import gnu.java.security.x509.ext.KeyUsage;
+import gnu.java.security.x509.ext.PolicyConstraint;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.PublicKey;
+import java.security.cert.CRL;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathParameters;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorResult;
+import java.security.cert.CertPathValidatorSpi;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.CertificateException;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.PKIXCertPathValidatorResult;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+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;
+
+/**
+ * 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/classpath/gnu/java/security/provider/RSA.java b/libjava/classpath/gnu/java/security/provider/RSA.java
new file mode 100644
index 00000000000..c3cfbbf79f1
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/RSA.java
@@ -0,0 +1,311 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 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.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;
+
+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/classpath/gnu/java/security/provider/RSAKeyFactory.java b/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java
new file mode 100644
index 00000000000..d13cbe510a1
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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/classpath/gnu/java/security/provider/SHA.java b/libjava/classpath/gnu/java/security/provider/SHA.java
new file mode 100644
index 00000000000..e3b09bc5603
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/SHA.java
@@ -0,0 +1,242 @@
+/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1].
+ Copyright (C) 1999, 2000, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+/**
+ This class implements the SHA-1 algorithm as described in [1].
+
+ [1] Federal Information Processing Standards Publication 180-1.
+ Specifications for the Secure Hash Standard. April 17, 1995.
+
+ @see java.security.MessageDigest
+*/
+public class SHA extends MessageDigest implements Cloneable
+{
+ public SHA ()
+ {
+ super("SHA");
+ engineReset ();
+ }
+
+ public int engineGetDigestLength()
+ {
+ return 20;
+ }
+
+ public void engineUpdate (byte b)
+ {
+ int i = ((int)bytecount) & 0x3f; //wgs
+ int shift = (3 - i % 4) << 3;
+ int idx = i / 4;
+
+ i = (int)b;
+ W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift);
+
+ // if we've filled up a block, then process it
+ if (((++bytecount) & 0x3f) == 0)
+ munch ();
+ }
+
+ // This could be optimized.
+ public void engineUpdate (byte bytes[], int off, int len)
+ {
+ if (len < 0)
+ throw new ArrayIndexOutOfBoundsException ();
+
+ int end = off + len;
+ while (off < end)
+ engineUpdate (bytes[off++]);
+ }
+
+ public void engineReset ()
+ {
+ bytecount = 0;
+ // magic numbers from [1] p. 10.
+ H0 = 0x67452301;
+ H1 = 0xefcdab89;
+ H2 = 0x98badcfe;
+ H3 = 0x10325476;
+ H4 = 0xc3d2e1f0;
+ }
+
+ public byte[] engineDigest ()
+ {
+ long bitcount = bytecount << 3;
+ engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding
+
+ // add the rest of the padding to fill this block out, but leave 8
+ // bytes to put in the original bytecount
+ while ((bytecount & 0x3f) != 56)
+ engineUpdate ((byte)0);
+
+ // add the length of the original, unpadded block to the end of
+ // the padding
+ W[14] = (int)(bitcount >>> 32);
+ W[15] = (int)bitcount;
+ bytecount += 8;
+
+ // digest the fully padded block
+ munch ();
+
+ byte[] result
+ = new byte[] {(byte)(H0 >>> 24), (byte)(H0 >>> 16),
+ (byte)(H0 >>> 8), (byte)H0,
+ (byte)(H1 >>> 24), (byte)(H1 >>> 16),
+ (byte)(H1 >>> 8), (byte)H1,
+ (byte)(H2 >>> 24), (byte)(H2 >>> 16),
+ (byte)(H2 >>> 8), (byte)H2,
+ (byte)(H3 >>> 24), (byte)(H3 >>> 16),
+ (byte)(H3 >>> 8), (byte)H3,
+ (byte)(H4 >>> 24), (byte)(H4 >>> 16),
+ (byte)(H4 >>> 8), (byte)H4};
+
+ engineReset ();
+ return result;
+ }
+
+ // Process a single block. This is pretty much copied verbatim from
+ // [1] pp. 9, 10.
+ private void munch ()
+ {
+ for (int t = 16; t < 80; ++ t)
+ {
+ int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+ W[t] = Wt << 1 | Wt >>> 31;
+ }
+
+ int A = H0;
+ int B = H1;
+ int C = H2;
+ int D = H3;
+ int E = H4;
+
+ for (int t = 0; t < 20; ++ t)
+ {
+ int TEMP = (A << 5 | A >>> 27) // S^5(A)
+ + ((B & C) | (~B & D)) // f_t(B,C,D)
+ + E + W[t]
+ + 0x5a827999; // K_t
+
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2; // S^30(B)
+ B = A;
+ A = TEMP;
+ }
+
+ for (int t = 20; t < 40; ++ t)
+ {
+ int TEMP = (A << 5 | A >>> 27) // S^5(A)
+ + (B ^ C ^ D) // f_t(B,C,D)
+ + E + W[t]
+ + 0x6ed9eba1; // K_t
+
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2; // S^30(B)
+ B = A;
+ A = TEMP;
+ }
+
+ for (int t = 40; t < 60; ++ t)
+ {
+ int TEMP = (A << 5 | A >>> 27) // S^5(A)
+ + (B & C | B & D | C & D) // f_t(B,C,D)
+ + E + W[t]
+ + 0x8f1bbcdc; // K_t
+
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2; // S^30(B)
+ B = A;
+ A = TEMP;
+ }
+
+ for (int t = 60; t < 80; ++ t)
+ {
+ int TEMP = (A << 5 | A >>> 27) // S^5(A)
+ + (B ^ C ^ D) // f_t(B,C,D)
+ + E + W[t]
+ + 0xca62c1d6; // K_t
+
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2; // S^30(B)
+ B = A;
+ A = TEMP;
+ }
+
+ H0 += A;
+ H1 += B;
+ H2 += C;
+ H3 += D;
+ H4 += E;
+
+ // Reset W by clearing it.
+ for (int t = 0; t < 80; ++ t)
+ W[t] = 0;
+ }
+
+ public Object clone ()
+ {
+ return new SHA (this);
+ }
+
+ private SHA (SHA copy)
+ {
+ this ();
+ bytecount = copy.bytecount;
+ H0 = copy.H0;
+ H1 = copy.H1;
+ H2 = copy.H2;
+ H3 = copy.H3;
+ H4 = copy.H4;
+ System.arraycopy (copy.W, 0, W, 0, 80);
+ }
+
+ private final int W[] = new int[80];
+ private long bytecount;
+ private int H0;
+ private int H1;
+ private int H2;
+ private int H3;
+ private int H4;
+}
diff --git a/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java b/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java
new file mode 100644
index 00000000000..e4058e3079b
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java
@@ -0,0 +1,137 @@
+/* SHA1PRNG.java --- Secure Random SPI SHA1PRNG
+ Copyright (C) 1999, 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.Serializable;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandomSpi;
+import java.util.Random;
+
+public class SHA1PRNG extends SecureRandomSpi implements Serializable
+{
+ MessageDigest digest;
+ byte seed[];
+ byte data[];
+ int seedpos;
+ int datapos;
+ private boolean seeded = false; // set to true when we seed this
+ /**
+ * The size of seed.
+ */
+ private static final int SEED_SIZE = 20;
+ /**
+ * The size of data.
+ */
+ private static final int DATA_SIZE = 40;
+
+ /**
+ * Create a new SHA-1 pseudo-random number generator.
+ */
+ public SHA1PRNG()
+ {
+ try {
+ digest = MessageDigest.getInstance("SHA");
+ } catch ( NoSuchAlgorithmException nsae) {
+// System.out.println("Failed to find SHA Message Digest: " + nsae);
+// nsae.printStackTrace();
+ throw new InternalError ("no SHA implementation found");
+ }
+
+ seed = new byte[SEED_SIZE];
+ seedpos = 0;
+ data = new byte[DATA_SIZE];
+ datapos = SEED_SIZE; // try to force hashing a first block
+ }
+
+ public void engineSetSeed(byte[] seed)
+ {
+ for(int i = 0; i < seed.length; i++)
+ this.seed[seedpos++ % SEED_SIZE] ^= seed[i];
+ seedpos %= SEED_SIZE;
+
+ }
+
+ public void engineNextBytes(byte[] bytes)
+ {
+ ensureIsSeeded ();
+ int loc = 0;
+ while (loc < bytes.length)
+ {
+ int copy = Math.min (bytes.length - loc, SEED_SIZE - datapos);
+
+ if (copy > 0)
+ {
+ System.arraycopy (data, datapos, bytes, loc, copy);
+ datapos += copy;
+ loc += copy;
+ }
+ else
+ {
+ // No data ready for copying, so refill our buffer.
+ System.arraycopy( seed, 0, data, SEED_SIZE, SEED_SIZE);
+ byte[] digestdata = digest.digest( data );
+ System.arraycopy( digestdata, 0, data, 0, SEED_SIZE);
+ datapos = 0;
+ }
+ }
+ }
+
+ public byte[] engineGenerateSeed(int numBytes)
+ {
+ byte tmp[] = new byte[numBytes];
+
+ engineNextBytes( tmp );
+ return tmp;
+ }
+
+ private void ensureIsSeeded()
+ {
+ if (!seeded)
+ {
+ new Random(0L).nextBytes(seed);
+
+ byte[] digestdata = digest.digest(data);
+ System.arraycopy(digestdata, 0, data, 0, SEED_SIZE);
+
+ seeded = true;
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java b/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java
new file mode 100644
index 00000000000..0e63fdeeb52
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.security.OID;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+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);
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java b/libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java
new file mode 100644
index 00000000000..1a415eabb05
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java
@@ -0,0 +1,305 @@
+/* X509CertificateFactory.java -- generates X.509 certificates.
+ Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.io.Base64InputStream;
+import gnu.java.security.x509.X509CRL;
+import gnu.java.security.x509.X509CertPath;
+import gnu.java.security.x509.X509Certificate;
+
+import java.io.BufferedInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.CRL;
+import java.security.cert.CRLException;
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactorySpi;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class X509CertificateFactory extends CertificateFactorySpi
+{
+
+ // Constants.
+ // ------------------------------------------------------------------------
+
+ public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
+ public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
+ public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
+ public static final String END_X509_CRL = "-----END X509 CRL-----";
+
+ // Constructors.
+ // ------------------------------------------------------------------------
+
+ public X509CertificateFactory()
+ {
+ super();
+ }
+
+ // Instance methods.
+ // ------------------------------------------------------------------------
+
+ public Certificate engineGenerateCertificate(InputStream inStream)
+ throws CertificateException
+ {
+ try
+ {
+ return generateCert(inStream);
+ }
+ catch (IOException ioe)
+ {
+ CertificateException ce = new CertificateException(ioe.getMessage());
+ ce.initCause (ioe);
+ throw ce;
+ }
+ }
+
+ public Collection engineGenerateCertificates(InputStream inStream)
+ throws CertificateException
+ {
+ LinkedList certs = new LinkedList();
+ while (true)
+ {
+ try
+ {
+ certs.add(generateCert(inStream));
+ }
+ catch (EOFException eof)
+ {
+ break;
+ }
+ catch (IOException ioe)
+ {
+ CertificateException ce = new CertificateException(ioe.getMessage());
+ ce.initCause (ioe);
+ throw ce;
+ }
+ }
+ return certs;
+ }
+
+ public CRL engineGenerateCRL(InputStream inStream) throws CRLException
+ {
+ try
+ {
+ return generateCRL(inStream);
+ }
+ catch (IOException ioe)
+ {
+ CRLException crle = new CRLException(ioe.getMessage());
+ crle.initCause (ioe);
+ throw crle;
+ }
+ }
+
+ public Collection engineGenerateCRLs(InputStream inStream)
+ throws CRLException
+ {
+ LinkedList crls = new LinkedList();
+ while (true)
+ {
+ try
+ {
+ crls.add(generateCRL(inStream));
+ }
+ catch (EOFException eof)
+ {
+ break;
+ }
+ catch (IOException ioe)
+ {
+ 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);
+ int i = inStream.read();
+ if (i == -1)
+ throw new EOFException();
+
+ // If the input is in binary DER format, the first byte MUST be
+ // 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
+ // UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
+ //
+ // So if we do not see 0x30 here we will assume it is in Base-64.
+ if (i != 0x30)
+ {
+ inStream.reset();
+ StringBuffer line = new StringBuffer(80);
+ do
+ {
+ line.setLength(0);
+ do
+ {
+ i = inStream.read();
+ if (i == -1)
+ throw new EOFException();
+ if (i != '\n' && i != '\r')
+ line.append((char) i);
+ }
+ while (i != '\n' && i != '\r');
+ }
+ while (!line.toString().equals(BEGIN_CERTIFICATE));
+ X509Certificate ret = new X509Certificate(
+ new BufferedInputStream(new Base64InputStream(inStream), 8192));
+ line.setLength(0);
+ line.append('-'); // Base64InputStream will eat this.
+ do
+ {
+ i = inStream.read();
+ if (i == -1)
+ throw new EOFException();
+ if (i != '\n' && i != '\r')
+ line.append((char) i);
+ }
+ while (i != '\n' && i != '\r');
+ // XXX ???
+ if (!line.toString().equals(END_CERTIFICATE))
+ throw new CertificateException("no end-of-certificate marker");
+ return ret;
+ }
+ else
+ {
+ inStream.reset();
+ return new X509Certificate(inStream);
+ }
+ }
+
+ 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);
+ int i = inStream.read();
+ if (i == -1)
+ throw new EOFException();
+
+ // If the input is in binary DER format, the first byte MUST be
+ // 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
+ // UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
+ //
+ // So if we do not see 0x30 here we will assume it is in Base-64.
+ if (i != 0x30)
+ {
+ inStream.reset();
+ StringBuffer line = new StringBuffer(80);
+ do
+ {
+ line.setLength(0);
+ do
+ {
+ i = inStream.read();
+ if (i == -1)
+ throw new EOFException();
+ if (i != '\n' && i != '\r')
+ line.append((char) i);
+ }
+ while (i != '\n' && i != '\r');
+ }
+ while (!line.toString().startsWith(BEGIN_X509_CRL));
+ X509CRL ret = new X509CRL(
+ new BufferedInputStream(new Base64InputStream(inStream), 8192));
+ line.setLength(0);
+ line.append('-'); // Base64InputStream will eat this.
+ do
+ {
+ i = inStream.read();
+ if (i == -1)
+ throw new EOFException();
+ if (i != '\n' && i != '\r')
+ line.append((char) i);
+ }
+ while (i != '\n' && i != '\r');
+ // XXX ???
+ if (!line.toString().startsWith(END_X509_CRL))
+ throw new CRLException("no end-of-CRL marker");
+ return ret;
+ }
+ else
+ {
+ inStream.reset();
+ return new X509CRL(inStream);
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/provider/package.html b/libjava/classpath/gnu/java/security/provider/package.html
new file mode 100644
index 00000000000..641a22aff77
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/provider/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.security.provider package.
+ Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.security.provider</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
OpenPOWER on IntegriCloud