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

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

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

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

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

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

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

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

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

From-SVN: r90682
This commit is contained in:
Andreas Tobler
2004-11-15 21:02:08 +01:00
parent fcb94d103b
commit 507148866c
43 changed files with 6698 additions and 1138 deletions
@@ -0,0 +1,103 @@
/* CollectionCertStore.java -- Collection-based cert store.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.InvalidAlgorithmParameterException;
import java.security.cert.Certificate;
import java.security.cert.CertSelector;
import java.security.cert.CRL;
import java.security.cert.CRLSelector;
import java.security.cert.CertStoreException;
import java.security.cert.CertStoreParameters;
import java.security.cert.CertStoreSpi;
import java.security.cert.CollectionCertStoreParameters;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
public final class CollectionCertStoreImpl extends CertStoreSpi
{
// Fields.
// -------------------------------------------------------------------------
private final Collection store;
// Constructors.
// -------------------------------------------------------------------------
public CollectionCertStoreImpl(CertStoreParameters params)
throws InvalidAlgorithmParameterException
{
super(params);
if (! (params instanceof CollectionCertStoreParameters))
throw new InvalidAlgorithmParameterException("not a CollectionCertStoreParameters object");
store = ((CollectionCertStoreParameters) params).getCollection();
}
// Instance methods.
// -------------------------------------------------------------------------
public Collection engineGetCertificates(CertSelector selector)
throws CertStoreException
{
LinkedList result = new LinkedList();
for (Iterator it = store.iterator(); it.hasNext(); )
{
Object o = it.next();
if ((o instanceof Certificate) && selector.match((Certificate) o))
result.add(o);
}
return result;
}
public Collection engineGetCRLs(CRLSelector selector)
throws CertStoreException
{
LinkedList result = new LinkedList();
for (Iterator it = store.iterator(); it.hasNext(); )
{
Object o = it.next();
if ((o instanceof CRL) && selector.match((CRL) o))
result.add(o);
}
return result;
}
}
@@ -0,0 +1,310 @@
/* EncodedKeyFactory.java -- encoded key factory.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.io.IOException;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyFactorySpi;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.spec.DHParameterSpec;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
/**
* A factory for keys encoded in either the X.509 format (for public
* keys) or the PKCS#8 format (for private keys).
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class EncodedKeyFactory extends KeyFactorySpi
{
// Constants.
// ------------------------------------------------------------------------
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
private static final OID ID_DH = new OID("1.2.840.10046.2.1");
// Instance methods.
// ------------------------------------------------------------------------
public PublicKey engineGeneratePublic(KeySpec spec)
throws InvalidKeySpecException
{
if (!(spec instanceof X509EncodedKeySpec))
throw new InvalidKeySpecException("only supports X.509 key specs");
DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded());
try
{
DERValue spki = der.read();
if (!spki.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue alg = der.read();
if (!alg.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue val = der.read();
if (!(val.getValue() instanceof OID))
{
throw new InvalidKeySpecException("malformed encoded key");
}
OID algId = (OID) val.getValue();
byte[] algParams = null;
if (alg.getLength() > val.getEncodedLength())
{
val = der.read();
algParams = val.getEncoded();
if (val.isConstructed())
der.skip(val.getLength());
}
val = der.read();
if (!(val.getValue() instanceof BitString))
{
throw new InvalidKeySpecException("malformed encoded key");
}
byte[] publicKey = ((BitString) val.getValue()).toByteArray();
if (algId.equals(ID_DSA))
{
BigInteger p = null, g = null, q = null, Y;
if (algParams != null)
{
DERReader dsaParams = new DERReader(algParams);
val = dsaParams.read();
if (!val.isConstructed())
throw new InvalidKeySpecException("malformed DSA parameters");
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
p = (BigInteger) val.getValue();
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
q = (BigInteger) val.getValue();
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
g = (BigInteger) val.getValue();
}
DERReader dsaPub = new DERReader(publicKey);
val = dsaPub.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
Y = (BigInteger) val.getValue();
return new GnuDSAPublicKey(Y, p, q, g);
}
else if (algId.equals(ID_RSA))
{
DERReader rsaParams = new DERReader(publicKey);
if (!rsaParams.read().isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
return new GnuRSAPublicKey(new RSAPublicKeySpec(
(BigInteger) rsaParams.read().getValue(),
(BigInteger) rsaParams.read().getValue()));
}
else if (algId.equals(ID_DH))
{
if (algParams == null)
throw new InvalidKeySpecException("missing DH parameters");
DERReader dhParams = new DERReader(algParams);
val = dhParams.read();
BigInteger p, g, q, Y;
if (!val.isConstructed())
throw new InvalidKeySpecException("malformed DH parameters");
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
p = (BigInteger) val.getValue();
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
g = (BigInteger) val.getValue();
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
q = (BigInteger) val.getValue();
DERReader dhPub = new DERReader(publicKey);
val = dhPub.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
Y = (BigInteger) val.getValue();
return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q);
}
else
throw new InvalidKeySpecException("unknown algorithm: " + algId);
}
catch (IOException ioe)
{
throw new InvalidKeySpecException(ioe.getMessage());
}
}
public PrivateKey engineGeneratePrivate(KeySpec spec)
throws InvalidKeySpecException
{
if (!(spec instanceof PKCS8EncodedKeySpec))
{
throw new InvalidKeySpecException("only supports PKCS8 key specs");
}
DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded());
try
{
DERValue pki = der.read();
if (!pki.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue val = der.read();
if (!(val.getValue() instanceof BigInteger))
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue alg = der.read();
if (!alg.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
val = der.read();
if (!(val.getValue() instanceof OID))
{
throw new InvalidKeySpecException("malformed encoded key");
}
OID algId = (OID) val.getValue();
byte[] algParams = null;
if (alg.getLength() > val.getEncodedLength())
{
val = der.read();
algParams = val.getEncoded();
if (val.isConstructed())
der.skip(val.getLength());
}
byte[] privateKey = (byte[]) der.read().getValue();
if (algId.equals(ID_DSA))
{
if (algParams == null)
{
throw new InvalidKeySpecException("missing DSA parameters");
}
AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
params.init(algParams);
DSAParameterSpec dsaSpec = (DSAParameterSpec)
params.getParameterSpec(DSAParameterSpec.class);
DERReader dsaPriv = new DERReader(privateKey);
return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(),
dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG());
}
else if (algId.equals(ID_RSA))
{
DERReader rsaParams = new DERReader(privateKey);
if (!rsaParams.read().isConstructed())
throw new InvalidKeySpecException("malformed encoded key");
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
(BigInteger) rsaParams.read().getValue(), // n
(BigInteger) rsaParams.read().getValue(), // e
(BigInteger) rsaParams.read().getValue(), // d
(BigInteger) rsaParams.read().getValue(), // p
(BigInteger) rsaParams.read().getValue(), // q
(BigInteger) rsaParams.read().getValue(), // d mod (p - 1)
(BigInteger) rsaParams.read().getValue(), // d mod (q - 1)
(BigInteger) rsaParams.read().getValue())); // (inv q) mod p
}
else
throw new InvalidKeySpecException("unknown algorithm: " + algId);
}
catch (InvalidParameterSpecException iapse)
{
throw new InvalidKeySpecException(iapse.getMessage());
}
catch (NoSuchAlgorithmException nsae)
{
throw new InvalidKeySpecException(nsae.getMessage());
}
catch (IOException ioe)
{
throw new InvalidKeySpecException(ioe.getMessage());
}
}
public KeySpec engineGetKeySpec(Key key, Class speClass)
throws InvalidKeySpecException
{
if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")
&& speClass.isAssignableFrom(PKCS8EncodedKeySpec.class))
return new PKCS8EncodedKeySpec(key.getEncoded());
else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")
&& speClass.isAssignableFrom(X509EncodedKeySpec.class))
return new X509EncodedKeySpec(key.getEncoded());
else
throw new InvalidKeySpecException();
}
public Key engineTranslateKey(Key key) throws InvalidKeyException
{
throw new InvalidKeyException("translating keys not supported");
}
}
+107 -51
View File
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -37,75 +37,131 @@ exception statement from your version. */
package gnu.java.security.provider;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Provider;
public final class Gnu extends Provider
{
public Gnu()
{
super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, X.509 Certificates");
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");
// 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.
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());
// 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("Alg.Alias.Signature.DSS", "SHA1withDSA");
put("Alg.Alias.Signature.DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA");
put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA");
put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA");
put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
// Key Pair Generator
put("KeyPairGenerator.DSA",
gnu.java.security.provider.DSAKeyPairGenerator.class.getName());
put("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("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");
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");
// Key Factory
put("KeyFactory.DSA",
gnu.java.security.provider.DSAKeyFactory.class.getName());
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("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");
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");
// Message Digests
put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName());
put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName());
// Key Pair Generator
put("KeyPairGenerator.DSA",
gnu.java.security.provider.DSAKeyPairGenerator.class.getName());
// Format "Alias", "Actual Name"
put("Alg.Alias.MessageDigest.SHA1", "SHA");
put("Alg.Alias.MessageDigest.SHA-1", "SHA");
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");
// Algorithm Parameters
put("AlgorithmParameters.DSA",
gnu.java.security.provider.DSAParameters.class.getName());
// Key Factory
put("KeyFactory.DSA",
gnu.java.security.provider.DSAKeyFactory.class.getName());
// Algorithm Parameter Generator
put("AlgorithmParameterGenerator.DSA",
gnu.java.security.provider.DSAParameterGenerator.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");
// SecureRandom
put("SecureRandom.SHA1PRNG",
gnu.java.security.provider.SHA1PRNG.class.getName());
put("KeyFactory.RSA", RSAKeyFactory.class.getName());
// CertificateFactory
put("CertificateFactory.X.509",
gnu.java.security.provider.X509CertificateFactory.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");
put("Alg.Alias.CertificateFactory.X509", "X.509");
// Message Digests
put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName());
put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName());
// Format "Alias", "Actual Name"
put("Alg.Alias.MessageDigest.SHA1", "SHA");
put("Alg.Alias.MessageDigest.SHA-1", "SHA");
// Algorithm Parameters
put("AlgorithmParameters.DSA",
gnu.java.security.provider.DSAParameters.class.getName());
put("Alg.Alias.AlgorithmParameters.DSS", "DSA");
put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSA");
put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSA");
put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSA");
// Algorithm Parameter Generator
put("AlgorithmParameterGenerator.DSA",
gnu.java.security.provider.DSAParameterGenerator.class.getName());
// SecureRandom
put("SecureRandom.SHA1PRNG",
gnu.java.security.provider.SHA1PRNG.class.getName());
// CertificateFactory
put("CertificateFactory.X509", X509CertificateFactory.class.getName());
put("CertificateFactory.X509 ImplementedIn", "Software");
put("Alg.Alias.CertificateFactory.X.509", "X509");
// CertPathValidator
put("CertPathValidator.PKIX", PKIXCertPathValidatorImpl.class.getName());
put("CertPathValidator.PKIX ImplementedIn", "Software");
// CertStore
put("CertStore.Collection", CollectionCertStoreImpl.class.getName());
return null;
}
});
}
}
@@ -0,0 +1,117 @@
/* GnuDHPublicKey.java -- A Diffie-Hellman public key.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.math.BigInteger;
import java.util.ArrayList;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
public class GnuDHPublicKey implements DHPublicKey
{
// Fields.
// -------------------------------------------------------------------------
private byte[] encoded;
private final DHParameterSpec params;
private final BigInteger Y;
private final BigInteger q;
// Constructor.
// -------------------------------------------------------------------------
public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q)
{
this.params = params;
this.Y = Y;
this.q = q;
}
// Instance methods.
// -------------------------------------------------------------------------
public BigInteger getY()
{
return Y;
}
public DHParameterSpec getParams()
{
return params;
}
public String getAlgorithm()
{
return "DH";
}
public String getFormat()
{
return "X.509";
}
public byte[] getEncoded()
{
if (encoded != null)
return (byte[]) encoded.clone();
ArrayList spki = new ArrayList(2);
ArrayList alg = new ArrayList(2);
alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1")));
ArrayList param = new ArrayList(3);
param.add(new DERValue(DER.INTEGER, params.getP()));
param.add(new DERValue(DER.INTEGER, params.getG()));
param.add(new DERValue(DER.INTEGER, q));
alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param));
spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray())));
encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded();
if (encoded != null)
return (byte[]) encoded.clone();
return null;
}
}
@@ -0,0 +1,166 @@
/* GnuRSAPrivateKey.java -- GNU RSA private key.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.ArrayList;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
class GnuRSAPrivateKey implements RSAPrivateCrtKey
{
// Fields.
// -------------------------------------------------------------------------
private final RSAPrivateCrtKeySpec spec;
private byte[] encodedKey;
// Constructor.
// -------------------------------------------------------------------------
public GnuRSAPrivateKey(RSAPrivateCrtKeySpec spec)
{
this.spec = spec;
}
// Instance methods.
// -------------------------------------------------------------------------
public BigInteger getModulus()
{
return spec.getModulus();
}
public BigInteger getPrivateExponent()
{
return spec.getPrivateExponent();
}
public BigInteger getCrtCoefficient()
{
return spec.getCrtCoefficient();
}
public BigInteger getPrimeExponentP()
{
return spec.getPrimeExponentP();
}
public BigInteger getPrimeExponentQ()
{
return spec.getPrimeExponentQ();
}
public BigInteger getPrimeP()
{
return spec.getPrimeP();
}
public BigInteger getPrimeQ()
{
return spec.getPrimeQ();
}
public BigInteger getPublicExponent()
{
return spec.getPublicExponent();
}
public String getAlgorithm()
{
return "RSA";
}
public String getFormat()
{
return "PKCS#8";
}
/**
* The encoded form is:
*
* <pre>
* RSAPrivateKey ::= SEQUENCE {
* version Version,
* modulus INTEGER, -- n
* publicExponent INTEGER, -- e
* privateExponent INTEGER, -- d
* prime1 INTEGER, -- p
* prime2 INTEGER, -- q
* exponent1 INTEGER, -- d mod (p-1)
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER -- (inverse of q) mod p }
* </pre>
*
* <p>Which is in turn encoded in a PrivateKeyInfo structure from PKCS#8.
*/
public byte[] getEncoded()
{
if (encodedKey != null)
return (byte[]) encodedKey.clone();
ArrayList key = new ArrayList(9);
key.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
key.add(new DERValue(DER.INTEGER, getModulus()));
key.add(new DERValue(DER.INTEGER, getPublicExponent()));
key.add(new DERValue(DER.INTEGER, getPrivateExponent()));
key.add(new DERValue(DER.INTEGER, getPrimeP()));
key.add(new DERValue(DER.INTEGER, getPrimeQ()));
key.add(new DERValue(DER.INTEGER, getPrimeExponentP()));
key.add(new DERValue(DER.INTEGER, getPrimeExponentQ()));
key.add(new DERValue(DER.INTEGER, getCrtCoefficient()));
DERValue pk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key);
ArrayList pki = new ArrayList(3);
pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
ArrayList alg = new ArrayList(2);
alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
new OID("1.2.840.113549.1.1.1")));
alg.add(new DERValue(DER.NULL, null));
pki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
pki.add(new DERValue(DER.OCTET_STRING, pk.getEncoded()));
encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, pki).getEncoded();
return (byte[]) encodedKey.clone();
}
}
@@ -0,0 +1,109 @@
/* GnuRSAPublicKey.java -- GNU RSA public key.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
class GnuRSAPublicKey implements RSAPublicKey
{
// Fields.
// -------------------------------------------------------------------------
private final RSAPublicKeySpec spec;
private byte[] encodedKey;
// Constructor.
// -------------------------------------------------------------------------
public GnuRSAPublicKey(RSAPublicKeySpec spec)
{
this.spec = spec;
}
// Instance methods.
// -------------------------------------------------------------------------
public BigInteger getModulus()
{
return spec.getModulus();
}
public BigInteger getPublicExponent()
{
return spec.getPublicExponent();
}
public String getAlgorithm()
{
return "RSA";
}
public String getFormat()
{
return "X.509";
}
public byte[] getEncoded()
{
if (encodedKey != null)
return (byte[]) encodedKey.clone();
ArrayList key = new ArrayList(2);
key.add(new DERValue(DER.INTEGER, getModulus()));
key.add(new DERValue(DER.INTEGER, getPublicExponent()));
DERValue rsapk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key);
ArrayList alg = new ArrayList(2);
alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
new OID("1.2.840.113549.1.1.1")));
alg.add(new DERValue(DER.NULL, null));
ArrayList spki = new ArrayList(2);
spki.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, alg));
spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded())));
encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, spki).getEncoded();
return (byte[]) encodedKey.clone();
}
}
@@ -0,0 +1,54 @@
/* MD2withRSA.java -- MD2 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD2withRSA extends RSA
{
// Constructor.
// -------------------------------------------------------------------------
public MD2withRSA() throws NoSuchAlgorithmException
{
super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2));
}
}
@@ -0,0 +1,54 @@
/* MD4withRSA.java -- MD4 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD4withRSA extends RSA
{
// Constructor.
// -------------------------------------------------------------------------
public MD4withRSA() throws NoSuchAlgorithmException
{
super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4));
}
}
@@ -0,0 +1,54 @@
/* MD5withRSA.java -- MD5 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5withRSA extends RSA
{
// Constructor.
// -------------------------------------------------------------------------
public MD5withRSA() throws NoSuchAlgorithmException
{
super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5));
}
}
@@ -0,0 +1,689 @@
/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.cert.*;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAParameterSpec;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import gnu.java.security.x509.GnuPKIExtension;
import gnu.java.security.x509.PolicyNodeImpl;
import gnu.java.security.x509.X509CertSelectorImpl;
import gnu.java.security.x509.X509CRLSelectorImpl;
import gnu.java.security.x509.ext.*;
import gnu.java.security.OID;
/**
* An implementation of the Public Key Infrastructure's X.509
* certificate path validation algorithm.
*
* <p>See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
* Internet X.509 Public Key Infrastructure Certificate and
* Certificate Revocation List (CRL) Profile</a>.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
{
// Constants.
// -------------------------------------------------------------------------
private static final boolean DEBUG = false;
private static void debug (String msg)
{
System.err.print (">> PKIXCertPathValidatorImpl: ");
System.err.println (msg);
}
public static final String ANY_POLICY = "2.5.29.32.0";
// Constructor.
// -------------------------------------------------------------------------
public PKIXCertPathValidatorImpl()
{
super();
}
// Instance methods.
// -------------------------------------------------------------------------
public CertPathValidatorResult engineValidate(CertPath path,
CertPathParameters params)
throws CertPathValidatorException, InvalidAlgorithmParameterException
{
if (!(params instanceof PKIXParameters))
throw new InvalidAlgorithmParameterException("not a PKIXParameters object");
// First check if the certificate path is valid.
//
// This means that:
//
// (a) for all x in {1, ..., n-1}, the subject of certificate x is
// the issuer of certificate x+1;
//
// (b) for all x in {1, ..., n}, the certificate was valid at the
// time in question.
//
// Because this is the X.509 algorithm, we also check if all
// cerificates are of type X509Certificate.
PolicyNodeImpl rootNode = new PolicyNodeImpl();
Set initPolicies = ((PKIXParameters) params).getInitialPolicies();
rootNode.setValidPolicy(ANY_POLICY);
rootNode.setCritical(false);
rootNode.setDepth(0);
if (initPolicies != null)
rootNode.addAllExpectedPolicies(initPolicies);
else
rootNode.addExpectedPolicy(ANY_POLICY);
List checks = ((PKIXParameters) params).getCertPathCheckers();
List l = path.getCertificates();
if (l == null || l.size() == 0)
throw new CertPathValidatorException();
X509Certificate[] p = null;
try
{
p = (X509Certificate[]) l.toArray(new X509Certificate[l.size()]);
}
catch (ClassCastException cce)
{
throw new CertPathValidatorException("invalid certificate path");
}
String sigProvider = ((PKIXParameters) params).getSigProvider();
PublicKey prevKey = null;
Date now = ((PKIXParameters) params).getDate();
if (now == null)
now = new Date();
LinkedList policyConstraints = new LinkedList();
for (int i = p.length - 1; i >= 0; i--)
{
try
{
p[i].checkValidity(now);
}
catch (CertificateException ce)
{
throw new CertPathValidatorException(ce.toString());
}
Set uce = getCritExts(p[i]);
for (Iterator check = checks.iterator(); check.hasNext(); )
{
try
{
((PKIXCertPathChecker) check.next()).check(p[i], uce);
}
catch (Exception x)
{
}
}
PolicyConstraint constr = null;
if (p[i] instanceof GnuPKIExtension)
{
Extension pcx =
((GnuPKIExtension) p[i]).getExtension (PolicyConstraint.ID);
if (pcx != null)
constr = (PolicyConstraint) pcx.getValue();
}
else
{
byte[] pcx = p[i].getExtensionValue (PolicyConstraint.ID.toString());
if (pcx != null)
{
try
{
constr = new PolicyConstraint (pcx);
}
catch (Exception x)
{
}
}
}
if (constr != null && constr.getRequireExplicitPolicy() >= 0)
{
policyConstraints.add (new int[]
{ p.length-i, constr.getRequireExplicitPolicy() });
}
updatePolicyTree(p[i], rootNode, p.length-i, (PKIXParameters) params,
checkExplicitPolicy (p.length-i, policyConstraints));
// The rest of the tests involve this cert's relationship with the
// next in the path. If this cert is the end entity, we can stop.
if (i == 0)
break;
basicSanity(p, i);
PublicKey pubKey = null;
try
{
pubKey = p[i].getPublicKey();
if (pubKey instanceof DSAPublicKey)
{
DSAParams dsa = ((DSAPublicKey) pubKey).getParams();
// If the DSA public key is missing its parameters, use those
// from the previous cert's key.
if (dsa == null || dsa.getP() == null || dsa.getG() == null
|| dsa.getQ() == null)
{
if (prevKey == null)
throw new InvalidKeyException("DSA keys not chainable");
if (!(prevKey instanceof DSAPublicKey))
throw new InvalidKeyException("DSA keys not chainable");
dsa = ((DSAPublicKey) prevKey).getParams();
pubKey = new GnuDSAPublicKey(((DSAPublicKey) pubKey).getY(),
dsa.getP(), dsa.getQ(), dsa.getG());
}
}
if (sigProvider == null)
p[i-1].verify(pubKey);
else
p[i-1].verify(pubKey, sigProvider);
prevKey = pubKey;
}
catch (Exception e)
{
throw new CertPathValidatorException(e.toString());
}
if (!p[i].getSubjectDN().equals(p[i-1].getIssuerDN()))
throw new CertPathValidatorException("issuer DN mismatch");
boolean[] issuerUid = p[i-1].getIssuerUniqueID();
boolean[] subjectUid = p[i].getSubjectUniqueID();
if (issuerUid != null && subjectUid != null)
if (!Arrays.equals(issuerUid, subjectUid))
throw new CertPathValidatorException("UID mismatch");
// Check the certificate against the revocation lists.
if (((PKIXParameters) params).isRevocationEnabled())
{
X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
try
{
selector.addIssuerName(p[i].getSubjectDN());
}
catch (IOException ioe)
{
throw new CertPathValidatorException("error selecting CRLs");
}
List certStores = ((PKIXParameters) params).getCertStores();
List crls = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext(); )
{
CertStore cs = (CertStore) it.next();
try
{
Collection c = cs.getCRLs(selector);
crls.addAll(c);
}
catch (CertStoreException cse)
{
}
}
if (crls.isEmpty())
throw new CertPathValidatorException("no CRLs for issuer");
boolean certOk = false;
for (Iterator it = crls.iterator(); it.hasNext(); )
{
CRL crl = (CRL) it.next();
if (!(crl instanceof X509CRL))
continue;
X509CRL xcrl = (X509CRL) crl;
if (!checkCRL(xcrl, p, now, p[i], pubKey, certStores))
continue;
if (xcrl.isRevoked(p[i-1]))
throw new CertPathValidatorException("certificate is revoked");
else
certOk = true;
}
if (!certOk)
throw new CertPathValidatorException("certificate's validity could not be determined");
}
}
rootNode.setReadOnly();
// Now ensure that the first certificate in the chain was issued
// by a trust anchor.
Exception cause = null;
Set anchors = ((PKIXParameters) params).getTrustAnchors();
for (Iterator i = anchors.iterator(); i.hasNext(); )
{
TrustAnchor anchor = (TrustAnchor) i.next();
X509Certificate anchorCert = null;
PublicKey anchorKey = null;
if (anchor.getTrustedCert() != null)
{
anchorCert = anchor.getTrustedCert();
anchorKey = anchorCert.getPublicKey();
}
else
anchorKey = anchor.getCAPublicKey();
if (anchorKey == null)
continue;
try
{
if (anchorCert == null)
anchorCert.checkValidity(now);
p[p.length-1].verify(anchorKey);
if (anchorCert != null && anchorCert.getBasicConstraints() >= 0
&& anchorCert.getBasicConstraints() < p.length)
continue;
if (((PKIXParameters) params).isRevocationEnabled())
{
X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
if (anchorCert != null)
try
{
selector.addIssuerName(anchorCert.getSubjectDN());
}
catch (IOException ioe)
{
}
else
selector.addIssuerName(anchor.getCAName());
List certStores = ((PKIXParameters) params).getCertStores();
List crls = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext(); )
{
CertStore cs = (CertStore) it.next();
try
{
Collection c = cs.getCRLs(selector);
crls.addAll(c);
}
catch (CertStoreException cse)
{
}
}
if (crls.isEmpty())
continue;
for (Iterator it = crls.iterator(); it.hasNext(); )
{
CRL crl = (CRL) it.next();
if (!(crl instanceof X509CRL))
continue;
X509CRL xcrl = (X509CRL) crl;
try
{
xcrl.verify(anchorKey);
}
catch (Exception x)
{
continue;
}
Date nextUpdate = xcrl.getNextUpdate();
if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
continue;
if (xcrl.isRevoked(p[p.length-1]))
throw new CertPathValidatorException("certificate is revoked");
}
}
// The chain is valid; return the result.
return new PKIXCertPathValidatorResult(anchor, rootNode,
p[0].getPublicKey());
}
catch (Exception ignored)
{
cause = ignored;
continue;
}
}
// The path is not valid.
CertPathValidatorException cpve =
new CertPathValidatorException("path validation failed");
if (cause != null)
cpve.initCause (cause);
throw cpve;
}
// Own methods.
// -------------------------------------------------------------------------
/**
* Check if a given CRL is acceptable for checking the revocation status
* of certificates in the path being checked.
*
* <p>The CRL is accepted iff:</p>
*
* <ol>
* <li>The <i>nextUpdate</i> field (if present) is in the future.</li>
* <li>The CRL does not contain any unsupported critical extensions.</li>
* <li>The CRL is signed by one of the certificates in the path, or,</li>
* <li>The CRL is signed by the given public key and was issued by the
* public key's subject, or,</li>
* <li>The CRL is signed by a certificate in the given cert stores, and
* that cert is signed by one of the certificates in the path.</li>
* </ol>
*
* @param crl The CRL being checked.
* @param path The path this CRL is being checked against.
* @param now The value to use as 'now'.
* @param pubKeySubject The subject of the public key.
* @param pubKey The public key to check.
* @return True if the CRL is acceptable.
*/
private static boolean checkCRL(X509CRL crl, X509Certificate[] path, Date now,
X509Certificate pubKeyCert, PublicKey pubKey,
List certStores)
{
Date nextUpdate = crl.getNextUpdate();
if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
return false;
if (crl.hasUnsupportedCriticalExtension())
return false;
for (int i = 0; i < path.length; i++)
{
if (!path[i].getSubjectDN().equals(crl.getIssuerDN()))
continue;
boolean[] keyUsage = path[i].getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.CRL_SIGN])
continue;
}
try
{
crl.verify(path[i].getPublicKey());
return true;
}
catch (Exception x)
{
}
}
if (crl.getIssuerDN().equals(pubKeyCert.getSubjectDN()))
{
try
{
boolean[] keyUsage = pubKeyCert.getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.CRL_SIGN])
throw new Exception();
}
crl.verify(pubKey);
return true;
}
catch (Exception x)
{
}
}
try
{
X509CertSelectorImpl select = new X509CertSelectorImpl();
select.addSubjectName(crl.getIssuerDN());
List certs = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext(); )
{
CertStore cs = (CertStore) it.next();
try
{
certs.addAll(cs.getCertificates(select));
}
catch (CertStoreException cse)
{
}
}
for (Iterator it = certs.iterator(); it.hasNext(); )
{
X509Certificate c = (X509Certificate) it.next();
for (int i = 0; i < path.length; i++)
{
if (!c.getIssuerDN().equals(path[i].getSubjectDN()))
continue;
boolean[] keyUsage = c.getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.CRL_SIGN])
continue;
}
try
{
c.verify(path[i].getPublicKey());
crl.verify(c.getPublicKey());
return true;
}
catch (Exception x)
{
}
}
if (c.getIssuerDN().equals(pubKeyCert.getSubjectDN()))
{
c.verify(pubKey);
crl.verify(c.getPublicKey());
}
}
}
catch (Exception x)
{
}
return false;
}
private static Set getCritExts(X509Certificate cert)
{
HashSet s = new HashSet();
if (cert instanceof GnuPKIExtension)
{
Collection exts = ((GnuPKIExtension) cert).getExtensions();
for (Iterator it = exts.iterator(); it.hasNext(); )
{
Extension ext = (Extension) it.next();
if (ext.isCritical() && !ext.isSupported())
s.add(ext.getOid().toString());
}
}
else
s.addAll(cert.getCriticalExtensionOIDs());
return s;
}
/**
* Perform a basic sanity check on the CA certificate at <code>index</code>.
*/
private static void basicSanity(X509Certificate[] path, int index)
throws CertPathValidatorException
{
X509Certificate cert = path[index];
int pathLen = 0;
for (int i = index - 1; i > 0; i--)
{
if (!path[i].getIssuerDN().equals(path[i].getSubjectDN()))
pathLen++;
}
Extension e = null;
if (cert instanceof GnuPKIExtension)
{
e = ((GnuPKIExtension) cert).getExtension(BasicConstraints.ID);
}
else
{
try
{
e = new Extension(cert.getExtensionValue(BasicConstraints.ID.toString()));
}
catch (Exception x)
{
}
}
if (e == null)
throw new CertPathValidatorException("no basicConstraints");
BasicConstraints bc = (BasicConstraints) e.getValue();
if (!bc.isCA())
throw new CertPathValidatorException("certificate cannot be used to verify signatures");
if (bc.getPathLengthConstraint() >= 0 && bc.getPathLengthConstraint() < pathLen)
throw new CertPathValidatorException("path is too long");
boolean[] keyUsage = cert.getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.KEY_CERT_SIGN])
throw new CertPathValidatorException("certificate cannot be used to sign certificates");
}
}
private static void updatePolicyTree(X509Certificate cert, PolicyNodeImpl root,
int depth, PKIXParameters params,
boolean explicitPolicy)
throws CertPathValidatorException
{
if (DEBUG) debug("updatePolicyTree depth == " + depth);
Set nodes = new HashSet();
LinkedList stack = new LinkedList();
Iterator current = null;
stack.addLast(Collections.singleton(root).iterator());
do
{
current = (Iterator) stack.removeLast();
while (current.hasNext())
{
PolicyNodeImpl p = (PolicyNodeImpl) current.next();
if (DEBUG) debug("visiting node == " + p);
if (p.getDepth() == depth - 1)
{
if (DEBUG) debug("added node");
nodes.add(p);
}
else
{
if (DEBUG) debug("skipped node");
stack.addLast(current);
current = p.getChildren();
}
}
}
while (!stack.isEmpty());
Extension e = null;
CertificatePolicies policies = null;
List qualifierInfos = null;
if (cert instanceof GnuPKIExtension)
{
e = ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID);
if (e != null)
policies = (CertificatePolicies) e.getValue();
}
List cp = null;
if (policies != null)
cp = policies.getPolicies();
else
cp = Collections.EMPTY_LIST;
boolean match = false;
if (DEBUG) debug("nodes are == " + nodes);
if (DEBUG) debug("cert policies are == " + cp);
for (Iterator it = nodes.iterator(); it.hasNext(); )
{
PolicyNodeImpl parent = (PolicyNodeImpl) it.next();
if (DEBUG) debug("adding policies to " + parent);
for (Iterator it2 = cp.iterator(); it2.hasNext(); )
{
OID policy = (OID) it2.next();
if (DEBUG) debug("trying to add policy == " + policy);
if (policy.toString().equals(ANY_POLICY) &&
params.isAnyPolicyInhibited())
continue;
PolicyNodeImpl child = new PolicyNodeImpl();
child.setValidPolicy(policy.toString());
child.addExpectedPolicy(policy.toString());
if (parent.getExpectedPolicies().contains(policy.toString()))
{
parent.addChild(child);
match = true;
}
else if (parent.getExpectedPolicies().contains(ANY_POLICY))
{
parent.addChild(child);
match = true;
}
else if (ANY_POLICY.equals (policy.toString()))
{
parent.addChild (child);
match = true;
}
if (match && policies != null)
{
List qualifiers = policies.getPolicyQualifierInfos (policy);
if (qualifiers != null)
child.addAllPolicyQualifiers (qualifiers);
}
}
}
if (!match && (params.isExplicitPolicyRequired() || explicitPolicy))
throw new CertPathValidatorException("policy tree building failed");
}
private boolean checkExplicitPolicy (int depth, List explicitPolicies)
{
if (DEBUG) debug ("checkExplicitPolicy depth=" + depth);
for (Iterator it = explicitPolicies.iterator(); it.hasNext(); )
{
int[] i = (int[]) it.next();
int caDepth = i[0];
int limit = i[1];
if (DEBUG) debug (" caDepth=" + caDepth + " limit=" + limit);
if (depth - caDepth >= limit)
return true;
}
return false;
}
}
+314
View File
@@ -0,0 +1,314 @@
/* RSA.java -- RSA PKCS#1 signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
public abstract class RSA extends SignatureSpi implements Cloneable
{
// Constants and fields.
// -------------------------------------------------------------------------
/**
* digestAlgorithm OBJECT IDENTIFIER ::=
* { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) }
*/
protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2");
protected final OID digestAlgorithm;
protected final MessageDigest md;
protected RSAPrivateKey signerKey;
protected RSAPublicKey verifierKey;
// Constructor.
// -------------------------------------------------------------------------
protected RSA(MessageDigest md, OID digestAlgorithm)
{
super();
this.md = md;
this.digestAlgorithm = digestAlgorithm;
}
// Instance methods.
// -------------------------------------------------------------------------
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
protected Object engineGetParameter(String param)
{
throw new UnsupportedOperationException("deprecated");
}
protected void engineSetParameter(String param, Object value)
{
throw new UnsupportedOperationException("deprecated");
}
protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException
{
if (!(privateKey instanceof RSAPrivateKey))
throw new InvalidKeyException();
verifierKey = null;
signerKey = (RSAPrivateKey) privateKey;
}
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException
{
// This class does not need random bytes.
engineInitSign(privateKey);
}
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException
{
if (!(publicKey instanceof RSAPublicKey))
throw new InvalidKeyException();
signerKey = null;
verifierKey = (RSAPublicKey) publicKey;
}
protected void engineUpdate(byte b) throws SignatureException
{
if (signerKey == null && verifierKey == null)
throw new SignatureException("not initialized");
md.update(b);
}
protected void engineUpdate(byte[] buf, int off, int len)
throws SignatureException
{
if (signerKey == null && verifierKey == null)
throw new SignatureException("not initialized");
md.update(buf, off, len);
}
protected byte[] engineSign() throws SignatureException
{
if (signerKey == null)
throw new SignatureException("not initialized for signing");
//
// The signature will be the RSA encrypted BER representation of
// the following:
//
// DigestInfo ::= SEQUENCE {
// digestAlgorithm DigestAlgorithmIdentifier,
// digest Digest }
//
// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
//
// Digest ::= OCTET STRING
//
ArrayList digestAlg = new ArrayList(2);
digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm));
digestAlg.add(new DERValue(DER.NULL, null));
ArrayList digestInfo = new ArrayList(2);
digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg));
digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest()));
ByteArrayOutputStream out = new ByteArrayOutputStream();
try
{
DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo));
}
catch (IOException ioe)
{
throw new SignatureException(ioe.toString());
}
byte[] buf = out.toByteArray();
md.reset();
// k = octect length of the modulus.
int k = signerKey.getModulus().bitLength();
k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
if (buf.length < k - 3)
{
throw new SignatureException("RSA modulus too small");
}
byte[] d = new byte[k];
// Padding type 1:
// 00 | 01 | FF | ... | FF | 00 | D
d[1] = 0x01;
for (int i = 2; i < k - buf.length - 1; i++)
d[i] = (byte) 0xFF;
System.arraycopy(buf, 0, d, k - buf.length, buf.length);
BigInteger eb = new BigInteger(d);
byte[] ed = eb.modPow(signerKey.getPrivateExponent(),
signerKey.getModulus()).toByteArray();
// Ensure output is k octets long.
if (ed.length < k)
{
byte[] b = new byte[k];
System.arraycopy(eb, 0, b, k - ed.length, ed.length);
ed = b;
}
else if (ed.length > k)
{
if (ed.length != k + 1)
{
throw new SignatureException("modPow result is larger than the modulus");
}
// Maybe an extra 00 octect.
byte[] b = new byte[k];
System.arraycopy(ed, 1, b, 0, k);
ed = b;
}
return ed;
}
protected int engineSign(byte[] out, int off, int len)
throws SignatureException
{
if (out == null || off < 0 || len < 0 || off+len > out.length)
throw new SignatureException("illegal output argument");
byte[] result = engineSign();
if (result.length > len)
throw new SignatureException("not enough space for signature");
System.arraycopy(result, 0, out, off, result.length);
return result.length;
}
protected boolean engineVerify(byte[] sig) throws SignatureException
{
if (verifierKey == null)
throw new SignatureException("not initialized for verifying");
if (sig == null)
throw new SignatureException("no signature specified");
int k = verifierKey.getModulus().bitLength();
k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1);
if (sig.length != k)
throw new SignatureException("signature is the wrong size (expecting "
+ k + " bytes, got " + sig.length + ")");
BigInteger ed = new BigInteger(1, sig);
byte[] eb = ed.modPow(verifierKey.getPublicExponent(),
verifierKey.getModulus()).toByteArray();
int i = 0;
if (eb[0] == 0x00)
{
for (i = 1; i < eb.length && eb[i] == 0x00; i++);
if (i == 1)
throw new SignatureException("wrong RSA padding");
i--;
}
else if (eb[0] == 0x01)
{
for (i = 1; i < eb.length && eb[i] != 0x00; i++)
if (eb[i] != (byte) 0xFF)
throw new IllegalArgumentException("wrong RSA padding");
}
else
throw new SignatureException("wrong RSA padding type");
byte[] d = new byte[eb.length-i-1];
System.arraycopy(eb, i+1, d, 0, eb.length-i-1);
DERReader der = new DERReader(d);
try
{
DERValue val = der.read();
if (val.getTag() != DER.SEQUENCE)
throw new SignatureException("failed to parse DigestInfo");
val = der.read();
if (val.getTag() != DER.SEQUENCE)
throw new SignatureException("failed to parse DigestAlgorithmIdentifier");
boolean sequenceIsBer = val.getLength() == 0;
val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new SignatureException("failed to parse object identifier");
if (!val.getValue().equals(digestAlgorithm))
throw new SignatureException("digest algorithms do not match");
val = der.read();
// We should never see parameters here, since they are never used.
if (val.getTag() != DER.NULL)
throw new SignatureException("cannot handle digest parameters");
if (sequenceIsBer)
der.skip(1); // end-of-sequence byte.
val = der.read();
if (val.getTag() != DER.OCTET_STRING)
throw new SignatureException("failed to parse Digest");
return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue());
}
catch (IOException ioe)
{
throw new SignatureException(ioe.toString());
}
}
protected boolean engineVerify(byte[] sig, int off, int len)
throws SignatureException
{
if (sig == null || off < 0 || len < 0 || off+len > sig.length)
throw new SignatureException("illegal parameter");
byte[] buf = new byte[len];
System.arraycopy(sig, off, buf, 0, len);
return engineVerify(buf);
}
}
@@ -0,0 +1,181 @@
/* RSAKeyFactory.java -- RSA key factory.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSAKeyFactory extends KeyFactorySpi
{
// Default constructor.
// -------------------------------------------------------------------------
// Instance methods.
// -------------------------------------------------------------------------
protected PrivateKey engineGeneratePrivate(KeySpec spec)
throws InvalidKeySpecException
{
if (spec instanceof RSAPrivateCrtKeySpec)
{
return new GnuRSAPrivateKey((RSAPrivateCrtKeySpec) spec);
}
if (spec instanceof RSAPrivateKeySpec)
{
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
((RSAPrivateKeySpec) spec).getModulus(), null,
((RSAPrivateKeySpec) spec).getPrivateExponent(), null,
null, null, null, null));
}
if (spec instanceof PKCS8EncodedKeySpec)
{
EncodedKeyFactory ekf = new EncodedKeyFactory();
PrivateKey pk = ekf.engineGeneratePrivate(spec);
if (pk instanceof RSAPrivateKey)
return pk;
}
throw new InvalidKeySpecException();
}
protected PublicKey engineGeneratePublic(KeySpec spec)
throws InvalidKeySpecException
{
if (spec instanceof RSAPublicKeySpec)
{
return new GnuRSAPublicKey((RSAPublicKeySpec) spec);
}
if (spec instanceof X509EncodedKeySpec)
{
EncodedKeyFactory ekf = new EncodedKeyFactory();
PublicKey pk = ekf.engineGeneratePublic(spec);
if (pk instanceof RSAPublicKey)
return pk;
}
throw new InvalidKeySpecException();
}
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException
{
if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class)
&& (key instanceof RSAPrivateCrtKey))
{
return new RSAPrivateCrtKeySpec(
((RSAPrivateCrtKey) key).getModulus(),
((RSAPrivateCrtKey) key).getPublicExponent(),
((RSAPrivateCrtKey) key).getPrivateExponent(),
((RSAPrivateCrtKey) key).getPrimeP(),
((RSAPrivateCrtKey) key).getPrimeQ(),
((RSAPrivateCrtKey) key).getPrimeExponentP(),
((RSAPrivateCrtKey) key).getPrimeExponentQ(),
((RSAPrivateCrtKey) key).getCrtCoefficient());
}
if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class)
&& (key instanceof RSAPrivateKey))
{
return new RSAPrivateKeySpec(
((RSAPrivateCrtKey) key).getModulus(),
((RSAPrivateCrtKey) key).getPrivateExponent());
}
if (keySpec.isAssignableFrom(RSAPublicKeySpec.class)
&& (key instanceof RSAPublicKey))
{
return new RSAPublicKeySpec(
((RSAPrivateCrtKey) key).getModulus(),
((RSAPrivateCrtKey) key).getPublicExponent());
}
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)
&& key.getFormat().equalsIgnoreCase("PKCS#8"))
{
return new PKCS8EncodedKeySpec(key.getEncoded());
}
if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)
&& key.getFormat().equalsIgnoreCase("X.509"))
{
return new X509EncodedKeySpec(key.getEncoded());
}
throw new InvalidKeySpecException();
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException
{
if (key instanceof RSAPrivateCrtKey)
{
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
((RSAPrivateCrtKey) key).getModulus(),
((RSAPrivateCrtKey) key).getPublicExponent(),
((RSAPrivateCrtKey) key).getPrivateExponent(),
((RSAPrivateCrtKey) key).getPrimeP(),
((RSAPrivateCrtKey) key).getPrimeQ(),
((RSAPrivateCrtKey) key).getPrimeExponentP(),
((RSAPrivateCrtKey) key).getPrimeExponentQ(),
((RSAPrivateCrtKey) key).getCrtCoefficient()));
}
if (key instanceof RSAPrivateKey)
{
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
((RSAPrivateKey) key).getModulus(), null,
((RSAPrivateKey) key).getPrivateExponent(), null,
null, null, null, null));
}
if (key instanceof RSAPublicKey)
{
return new GnuRSAPublicKey(new RSAPublicKeySpec(
((RSAPrivateCrtKey) key).getModulus(),
((RSAPrivateCrtKey) key).getPublicExponent()));
}
throw new InvalidKeyException();
}
}
@@ -0,0 +1,61 @@
/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import gnu.java.security.OID;
public class SHA1withRSA extends RSA
{
// Constant.
// -------------------------------------------------------------------------
private static final OID SHA1 = new OID("1.3.14.3.2.26");
// Constructor.
// -------------------------------------------------------------------------
public SHA1withRSA() throws NoSuchAlgorithmException
{
super(MessageDigest.getInstance("SHA-160"), SHA1);
}
}
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -44,16 +44,21 @@ import java.io.InputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactorySpi;
import java.security.cert.CertPath;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import gnu.java.io.Base64InputStream;
import gnu.java.security.x509.X509Certificate;
import gnu.java.security.x509.X509CertPath;
import gnu.java.security.x509.X509CRL;
public class X509CertificateFactory extends CertificateFactorySpi
@@ -87,7 +92,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
catch (IOException ioe)
{
throw new CertificateException(ioe.toString());
CertificateException ce = new CertificateException(ioe.getMessage());
ce.initCause (ioe);
throw ce;
}
}
@@ -107,7 +114,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
catch (IOException ioe)
{
throw new CertificateException(ioe.toString());
CertificateException ce = new CertificateException(ioe.getMessage());
ce.initCause (ioe);
throw ce;
}
}
return certs;
@@ -121,7 +130,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
catch (IOException ioe)
{
throw new CRLException(ioe.toString());
CRLException crle = new CRLException(ioe.getMessage());
crle.initCause (ioe);
throw crle;
}
}
@@ -141,18 +152,44 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
catch (IOException ioe)
{
throw new CRLException(ioe.toString());
CRLException crle = new CRLException(ioe.getMessage());
crle.initCause (ioe);
throw crle;
}
}
return crls;
}
public CertPath engineGenerateCertPath(List certs)
{
return new X509CertPath(certs);
}
public CertPath engineGenerateCertPath(InputStream in)
throws CertificateEncodingException
{
return new X509CertPath(in);
}
public CertPath engineGenerateCertPath(InputStream in, String encoding)
throws CertificateEncodingException
{
return new X509CertPath(in, encoding);
}
public Iterator engineGetCertPathEncodings()
{
return X509CertPath.ENCODINGS.iterator();
}
// Own methods.
// ------------------------------------------------------------------------
private X509Certificate generateCert(InputStream inStream)
throws IOException, CertificateException
{
if (inStream == null)
throw new CertificateException("missing input stream");
if (!inStream.markSupported())
inStream = new BufferedInputStream(inStream, 8192);
inStream.mark(20);
@@ -211,6 +248,8 @@ public class X509CertificateFactory extends CertificateFactorySpi
private X509CRL generateCRL(InputStream inStream)
throws IOException, CRLException
{
if (inStream == null)
throw new CRLException("missing input stream");
if (!inStream.markSupported())
inStream = new BufferedInputStream(inStream, 8192);
inStream.mark(20);
@@ -265,5 +304,4 @@ public class X509CertificateFactory extends CertificateFactorySpi
return new X509CRL(inStream);
}
}
}