You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2003/10/14 14:04:45 UTC
cvs commit: ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto BouncyCastle.java CredentialException.java Crypto.java CryptoFactory.java Merlin.java errors.properties
dims 2003/10/14 05:04:45
Added: contrib/wss4j/src/org/apache/ws/security/components/crypto
BouncyCastle.java CredentialException.java
Crypto.java CryptoFactory.java Merlin.java
errors.properties
Log:
******* WORK IN PROGRESS *******
Initial check-in of my sandbox for ws-security related code.
Revision Changes Path
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto/BouncyCastle.java
Index: BouncyCastle.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security.components.crypto;
import org.apache.axis.encoding.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Properties;
import java.util.Vector;
/**
* Bouncy Castle crypto provider (for use with JDK1.3).
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class BouncyCastle implements Crypto {
private static Log log = LogFactory.getLog(BouncyCastle.class);
private static CertificateFactory certFact = null;
private PrivateKey key = null;
private X509Certificate[] certs = null;
private Properties properties = null;
static {
Security.addProvider(new BouncyCastleProvider());
installSecureRandomProvider();
}
/**
* Constructor.
* <p>
* @param properties
* @throws CredentialException
*/
public BouncyCastle(Properties properties) throws CredentialException {
this.properties = properties;
try {
InputStream in = new FileInputStream(getProxyFile(this.properties));
load(in);
} catch (Exception e) {
throw new CredentialException(3, "proxyNotFound", new Object[]{getProxyFile(this.properties)});
}
}
/**
* get the singleton certificate factory.
* <p>
* @return
* @throws GeneralSecurityException
*/
private static synchronized CertificateFactory getCertificateFactory() throws GeneralSecurityException {
if (certFact == null) {
certFact = CertificateFactory.getInstance("X.509");
}
return certFact;
}
/**
* loads certificate from an input stream.
* <p>
* @param in
* @return
* @throws GeneralSecurityException
*/
public X509Certificate loadCertificate(InputStream in) throws GeneralSecurityException {
return (X509Certificate) getCertificateFactory().generateCertificate(in);
}
/** installs the secure random provider. */
private static void installSecureRandomProvider() {
String providerName = "cryptix.jce.provider.CryptixRandom";
try {
log.debug("Loading SecureRandom provider: " + providerName);
Class providerClass = Class.forName(providerName);
Security.insertProviderAt((Provider) providerClass.newInstance(), 1);
} catch (Exception e) {
log.debug("Unable to install PRNG. Using default PRNG.", e);
}
}
/**
* convert bytes into corresponding DER object.
* <p>
* @param data
* @return
* @throws IOException
*/
private static DERObject toDERObject(byte[] data) throws IOException {
ByteArrayInputStream inStream = new ByteArrayInputStream(data);
DERInputStream derInputStream = new DERInputStream(inStream);
return derInputStream.readObject();
}
/**
* get an array of certificates from a byte array.
* <p>
* @param data
* @param reverse
* @return
* @throws IOException
* @throws GeneralSecurityException
*/
public X509Certificate[] getX509Certificates(byte[] data, boolean reverse) throws IOException, GeneralSecurityException {
X509Certificate[] certs;
DERObject obj = BouncyCastle.toDERObject(data);
ASN1Sequence seq = ASN1Sequence.getInstance(obj);
int size = seq.size();
ByteArrayInputStream in;
certs = new X509Certificate[size];
for (int i = 0; i < size; i++) {
obj = seq.getObjectAt(i).getDERObject();
data = BouncyCastle.toByteArray(obj);
in = new ByteArrayInputStream(data);
certs[(reverse) ? (size - 1 - i) : i] = loadCertificate(in);
}
return certs;
}
/**
* get a byte array given an array of certificates.
* <p>
* @param reverse
* @param certs
* @return
* @throws IOException
* @throws CertificateEncodingException
*/
public byte[] getCertificateData(boolean reverse, X509Certificate[] certs) throws IOException, CertificateEncodingException {
DEREncodableVector vec = new DEREncodableVector();
if (reverse) {
for (int i = certs.length - 1; i >= 0; i--) {
vec.add(BouncyCastle.toDERObject(certs[i].getEncoded()));
}
} else {
for (int i = 0; i < certs.length; i++) {
vec.add(BouncyCastle.toDERObject(certs[i].getEncoded()));
}
}
DERSequence seq = new DERSequence(vec);
byte[] data = BouncyCastle.toByteArray(seq);
return data;
}
/**
* load the private key and certificates from the input stream.
* <p>
* @param input
* @throws Exception
*/
private void load(InputStream input) throws Exception {
if (input == null) {
throw new IllegalArgumentException("input stream cannot be null");
}
PrivateKey key = null;
X509Certificate cert = null;
Vector chain = new Vector(3);
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(input));
String s;
while ((s = reader.readLine()) != null) {
if (s.indexOf("BEGIN CERTIFICATE") != -1) {
byte[] data = getDecodedPEMObject(reader);
cert = loadCertificate(new ByteArrayInputStream(data));
chain.addElement(cert);
} else if (s.indexOf("BEGIN RSA PRIVATE KEY") != -1) {
byte[] data = getDecodedPEMObject(reader);
key = getKey("RSA", data);
}
}
} catch (IOException e) {
throw new CredentialException(3, "ioError00", e);
} catch (GeneralSecurityException e) {
throw new CredentialException(3, "secError00", e);
} catch (Exception e) {
throw new CredentialException(-1, "error00", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
}
int size = chain.size();
if (size == 0) {
throw new CredentialException(3, "noCerts00", (Exception) null);
}
if (key == null) {
throw new CredentialException(3, "noKey00", (Exception) null);
} else {
certs = new X509Certificate[size];
chain.copyInto(certs);
this.key = key;
return;
}
}
/**
* convert a DER object into its byte representation.
* <p>
* @param obj
* @return
* @throws IOException
*/
private static byte[] toByteArray(DERObject obj) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DEROutputStream der = new DEROutputStream(bout);
der.writeObject(obj);
return bout.toByteArray();
}
/**
* get the decoded information.
* <p>
* @param reader
* @return
* @throws IOException
*/
private static final byte[] getDecodedPEMObject(BufferedReader reader) throws IOException {
StringBuffer buf = new StringBuffer();
String s;
while ((s = reader.readLine()) != null) {
if (s.indexOf("--END") != -1) {
return Base64.decode(buf.toString());
}
buf.append(s);
}
throw new EOFException("PEM footer missing");
}
/**
* get the private key from the byte array.
* <p>
* @param alg
* @param data
* @return
* @throws GeneralSecurityException
*/
private PrivateKey getKey(String alg, byte[] data) throws GeneralSecurityException {
if (alg.equals("RSA")) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
byte[] keyData = getKeyData(bis);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyData);
KeyFactory kfac = KeyFactory.getInstance("RSA");
return kfac.generatePrivate(spec);
} catch (IOException e) {
return null;
}
} else {
return null;
}
}
/**
* construct the private key byte representation from the info in the input stream.
* <p>
* @param bis
* @return
* @throws IOException
*/
private byte[] getKeyData(InputStream bis) throws IOException {
DERInputStream derin = new DERInputStream(bis);
DERObject keyInfo = derin.readObject();
DERObjectIdentifier rsa_oid = PKCSObjectIdentifiers.rsaEncryption;
AlgorithmIdentifier rsa = new AlgorithmIdentifier(rsa_oid);
PrivateKeyInfo pkeyinfo = new PrivateKeyInfo(rsa, keyInfo);
DERObject derkey = pkeyinfo.getDERObject();
byte[] keyData = toByteArray(derkey);
return keyData;
}
/**
* get the list of certificates.
* <p>
* @return
*/
public X509Certificate[] getCertificates() {
return certs;
}
/**
* get the private key.
* <p>
* @return
*/
public PrivateKey getPrivateKey() {
return key;
}
/**
* get the name of the file where the key/certificate information is stored.
* <p>
* @param properties
* @return
*/
private static String getProxyFile(Properties properties) {
String location = properties.getProperty("org.apache.ws.security.crypto.bouncycastle.file");
if (location != null) {
return location;
} else {
return getProxyDefaultLocation();
}
}
/**
* get the default location.
* <p>
* @return
*/
private static String getProxyDefaultLocation() {
String dir = System.getProperty("user.home");
File f = new File(dir, "x509.txt");
return f.getAbsolutePath();
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto/CredentialException.java
Index: CredentialException.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security.components.crypto;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* CredentialException.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class CredentialException extends Exception {
public static final int FAILURE = -1;
public static final int EXPIRED = 1;
public static final int DEFECTIVE = 2;
public static final int IO_ERROR = 3;
public static final int SEC_ERROR = 3;
private static ResourceBundle resources;
private int errorCode;
static {
try {
resources = ResourceBundle.getBundle("org.apache.ws.security.components.crypto.errors");
} catch (MissingResourceException e) {
throw new RuntimeException(e.getMessage());
}
}
/**
* Constructor.
* <p>
* @param errorCode
* @param msgId
* @param root
*/
public CredentialException(int errorCode, String msgId, Throwable root) {
this(errorCode, msgId, null, root);
}
/**
* Constructor.
* <p>
* @param errorCode
* @param msgId
* @param args
*/
public CredentialException(int errorCode, String msgId, Object[] args) {
this(errorCode, msgId, args, null);
}
/**
* Constructor.
* <p>
* @param errorCode
* @param msgId
* @param args
* @param root
*/
public CredentialException(int errorCode, String msgId, Object[] args, Throwable root) {
super(getMessage(msgId, args) + " Inner Exception: [" + root.getMessage() + "]");
this.errorCode = -1;
this.errorCode = errorCode;
}
/**
* get the error code.
* <p>
* @return TODO: Put description of return value here.
*/
public int getErrorCode() {
return errorCode;
}
/**
* get the actual message.
* <p>
* @param msgId
* @param args
* @return TODO: Put description of return value here.
*/
private static String getMessage(String msgId, Object[] args) {
try {
return MessageFormat.format(resources.getString(msgId), args);
} catch (MissingResourceException e) {
throw new RuntimeException("bad" + msgId);
}
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto/Crypto.java
Index: Crypto.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security.components.crypto;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
/**
* Crypto.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public interface Crypto {
/**
* returns a X509Certificate from the given input stream.
* <p>
* @param in
* @return
* @throws GeneralSecurityException
*/
X509Certificate loadCertificate(InputStream in) throws GeneralSecurityException;
/**
* returns a X509Certificate array from the given byte array.
* <p>
* @param data
* @param reverse
* @return
* @throws IOException
* @throws GeneralSecurityException
*/
X509Certificate[] getX509Certificates(byte[] data, boolean reverse) throws IOException, GeneralSecurityException;
/**
* get a byte array representation of the certificate information.
* <p>
* @param reverse
* @param certs
* @return
* @throws IOException
* @throws CertificateEncodingException
*/
byte[] getCertificateData(boolean reverse, X509Certificate[] certs) throws IOException, CertificateEncodingException;
/**
* Returns the private key.
* <p>
* @return the private key.
*/
public PrivateKey getPrivateKey();
/**
* returns the list of certificates.
* <p>
* @return the array of X509 certificates.
*/
public X509Certificate[] getCertificates();
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto/CryptoFactory.java
Index: CryptoFactory.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security.components.crypto;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.util.Loader;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.util.Properties;
/**
* CryptoFactory.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public abstract class CryptoFactory {
private static Log log = LogFactory.getLog(CryptoFactory.class);
private static final String defaultCryptoClassName = "org.apache.ws.security.components.crypto.BouncyCastle";
private static Crypto crypto = null;
/**
* getInstance
* <p>
* Returns the singleton instance of Crypto.
* <p>
* @return TODO: Put description of return value here.
*/
public static synchronized Crypto getInstance() {
if (crypto == null) {
crypto = getInstance(null);
}
return crypto;
}
/**
* getInstance
* <p>
* Returns an instance of Crypto.
* <p>
* @param cryptoClassName
* @return TODO: Put description of return value here.
*/
private static Crypto getInstance(String cryptoClassName) {
Crypto crypto = null;
Properties properties = getProperties();
if ((cryptoClassName == null) || (cryptoClassName.length() == 0)) {
cryptoClassName = System.getProperty("org.apache.ws.security.crypto.provider");
if ((cryptoClassName == null) || (cryptoClassName.length() == 0)) {
// use the default Crypto implementation
cryptoClassName = properties.getProperty("org.apache.ws.security.crypto.provider", defaultCryptoClassName);
}
}
Class cryptogenClass = null;
try {
// instruct the class loader to load the crypto implementation
cryptogenClass = java.lang.Class.forName(cryptoClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(cryptoClassName + " Not Found");
}
log.info("Using Crypto Engine [" + cryptoClassName + "]");
try {
Class[] classes = new Class[]{Properties.class};
Constructor c = cryptogenClass.getConstructor(classes);
crypto = (Crypto) c.newInstance(new Object[]{properties});
return crypto;
} catch (java.lang.Exception e) {
log.debug(cryptoClassName + " cannot create instance with properties constructor");
}
try {
// try to instantiate the Crypto subclass
crypto = (Crypto) cryptogenClass.newInstance();
return crypto;
} catch (java.lang.Exception e) {
throw new RuntimeException(cryptoClassName + " cannot create instance");
}
}
/**
* get the properties for crypto.
* <p>
* @return TODO: Put description of return value here.
*/
private static Properties getProperties() {
Properties properties = new Properties();
try {
URL url = Loader.getResource("crypto.properties");
properties.load(url.openStream());
} catch (Exception e) {
log.debug("Cannot find crypto.properties");
}
return properties;
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto/Merlin.java
Index: Merlin.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security.components.crypto;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.*;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
/**
* JDK1.4 based implementation of Crypto (uses keystore).
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class Merlin implements Crypto {
private static Log log = LogFactory.getLog(Merlin.class);
private static CertificateFactory certFact;
protected PrivateKey key = null;
protected Certificate[] certs = null;
private Properties properties = null;
/**
* Constructor.
* <p>
* @param properties
* @throws Exception
*/
public Merlin(Properties properties) throws Exception {
this.properties = properties;
try {
FileInputStream is = new FileInputStream(getProxyKeyStore(this.properties));
load(is);
} catch (Exception e) {
throw new CredentialException(3, "proxyNotFound", new Object[]{getProxyKeyStore(this.properties)});
}
}
/**
* Singleton certificate factory.
* <p>
* @return
* @throws GeneralSecurityException
*/
private static synchronized CertificateFactory getCertificateFactory() throws GeneralSecurityException {
if (certFact == null) {
certFact = CertificateFactory.getInstance("X.509");
}
return certFact;
}
/**
* load a X509Certificate from the input stream.
* <p>
* @param in
* @return
* @throws GeneralSecurityException
*/
public X509Certificate loadCertificate(InputStream in) throws GeneralSecurityException {
return (X509Certificate) getCertificateFactory().generateCertificate(in);
}
/**
* get an array of X509Certificate's from the byte array.
* <p>
* @param data
* @param reverse
* @return
* @throws IOException
* @throws GeneralSecurityException
*/
public X509Certificate[] getX509Certificates(byte[] data, boolean reverse) throws IOException, GeneralSecurityException {
InputStream in = new ByteArrayInputStream(data);
CertPath path = getCertificateFactory().generateCertPath(in);
List l = path.getCertificates();
X509Certificate[] certs = new X509Certificate[l.size()];
Iterator iterator = l.iterator();
for (int i = 0; i < l.size(); i++) {
certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate) iterator.next();
}
return certs;
}
/**
* get a byte array given an array of certificates.
* <p>
* @param reverse
* @param certs
* @return
* @throws IOException
* @throws CertificateEncodingException
*/
public byte[] getCertificateData(boolean reverse, X509Certificate[] certs) throws IOException, CertificateEncodingException {
Vector list = new Vector();
for (int i = 0; i < certs.length; i++) {
if (reverse) {
list.insertElementAt(certs[i], 0);
} else {
list.add(certs[i]);
}
}
try {
CertPath path = getCertificateFactory().generateCertPath(list);
return path.getEncoded();
} catch (GeneralSecurityException gse) {
gse.printStackTrace();
}
return null;
}
/**
* get the private key.
* <p>
* @return
*/
public PrivateKey getPrivateKey() {
return key;
}
/**
* get the list of certificates.
* <p>
* @return
*/
public X509Certificate[] getCertificates() {
X509Certificate[] certs = new X509Certificate[this.certs.length];
for (int i = 0; i < this.certs.length; i++) {
certs[i] = (X509Certificate) this.certs[i];
}
return certs;
}
/**
* load the private key and certificates from the input stream (of the keystore).
* <p>
* @param input
* @throws Exception
*/
public void load(InputStream input) throws Exception {
if (input == null) {
throw new IllegalArgumentException("input stream cannot be null");
}
try {
KeyStore keystore = KeyStore.getInstance(properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type", KeyStore.getDefaultType()));
String alias = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias", "security");
String password = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.password", "security");
keystore.load(input, password.toCharArray());
boolean b = keystore.isKeyEntry(alias);
log.info("Private Key:" + b);
if (!b) {
log.error("Cannot find key");
throw new Exception("Cannot find key");
}
String password2 = properties.getProperty("org.apache.ws.security.crypto.merlin.alias.password", "security");
key = (PrivateKey) keystore.getKey(alias, password2.toCharArray());
if (!(key instanceof PrivateKey)) {
throw new Exception("Key is not a private key");
}
certs = keystore.getCertificateChain(alias);
} catch (IOException e) {
throw new CredentialException(3, "ioError00", e);
} catch (GeneralSecurityException e) {
throw new CredentialException(3, "secError00", e);
} catch (Exception e) {
throw new CredentialException(-1, "error00", e);
}
if ((certs == null) || (certs.length == 0)) {
throw new CredentialException(3, "noCerts00", (Exception) null);
}
if (key == null) {
throw new CredentialException(3, "noKey00", (Exception) null);
}
}
/**
* location of the key store.
* <p>
* @param properties
* @return
*/
private static String getProxyKeyStore(Properties properties) {
String location = properties.getProperty("org.apache.ws.security.crypto.merlin.file");
if (location != null) {
return location;
} else {
return getProxyDefaultKeyStore();
}
}
/**
* get the default location.
* <p>
* @return
*/
private static String getProxyDefaultKeyStore() {
String dir = System.getProperty("user.home");
File f = new File(dir, "x509.keystore");
return f.getAbsolutePath();
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/components/crypto/errors.properties
Index: errors.properties
===================================================================
## defines error code - str message mapping
0 = General security error
1 = An unsupported token was provided
2 = An unsupported signature or encryption algorithm was used
3 = An error was discovered processing the <wsse:Security> header.
4 = An invalid security token was provided
5 = The security token could not be authenticated or authorized
6 = The signature or decryption was invalid
7 = Referenced security token could not be retrieved.
proxyNotFound = Proxy file ({0}) not found.
ioError00 = Failed to load credentials.
secError00 = Failed to load credentials.
error00 = Failed to load credentials.
noCerts00 = No certificates loaded
noKey00 = No private key loaded