diff options
Diffstat (limited to 'libjava/classpath/gnu/java/security/provider')
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> |