Commit b7e5e637 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added support for importing private keys and signed certificates.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@7130 b35dd754-fafc-0310-a699-88a17e54d16e
parent 526a7e85
......@@ -218,6 +218,7 @@
##
## 3.2.1
## Added key: 'index.certificate-warning'
## Added section 'ssl.import.certificate.*'
# Wildfire
......@@ -2338,4 +2339,18 @@ stun.settings.secondaryaddress = Secondary Address
stun.settings.primaryport = Primary Port Value
stun.settings.secondaryport = Secondary Port Value
stun.settings.enabled = Enabled
stun.settings.change = Change
\ No newline at end of file
stun.settings.change = Change
# Import signed certificate page
ssl.import.certificate.title=Import Signed Certificate
ssl.import.certificate.info=Use the form below to import a private key and certificate that was provided by a \
Certificate Authority. At this moment private keys encrypted with an AES algorithm cannot be imported. You will \
need to decrypt them before importing them. However, DES encrypted keys can be safely imported. To decrypt \
a private key file execute the following command: "openssl rsa -in ssl.key -out decryptedssl.key".
ssl.import.certificate.boxtitle=Import Private Key and Certificate
ssl.import.certificate.private-key=Content of Private Key file:
ssl.import.certificate.certificate=Content of Certificate file:
ssl.import.certificate.error.private-key=Please specify the content of the private key.
ssl.import.certificate.error.certificate=Please specify the content of the certificate to import.
ssl.import.certificate.error.import=There was an error one importing private key and signed certificate.
\ No newline at end of file
......@@ -18,12 +18,10 @@ import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
......@@ -212,8 +210,10 @@ public class CertificateManager {
encoded = ((DERTaggedObject) encoded).getObject();
encoded = ((DERTaggedObject) encoded).getObject();
String identity = ((DERUTF8String) encoded).getString();
// Add the decoded server name to the list of identities
identities.add(identity);
if (!"".equals(identity)) {
// Add the decoded server name to the list of identities
identities.add(identity);
}
}
catch (UnsupportedEncodingException e) {
// Ignore
......@@ -226,7 +226,7 @@ public class CertificateManager {
}
}
// Other types are not good for XMPP so ignore them
if (Log.isDebugEnabled()) {
else if (Log.isDebugEnabled()) {
Log.debug("SubjectAltName of invalid type found: " + certificate);
}
}
......@@ -425,6 +425,76 @@ public class CertificateManager {
}
}
/**
* Imports a new signed certificate and its private key into the keystore. The certificate input
* stream may contain the signed certificate as well as its CA chain.
*
* @param keyStore key store where the certificate will be stored.
* @param trustStore key store where ca certificates are stored.
* @param keyPassword password of the keystore.
* @param alias the alias of the the new signed certificate.
* @param pkInputStream the stream containing the private key.
* @param inputStream the stream containing the signed certificate.
* @param trustCACerts true if certificates present in the truststore file will be used to verify the
* identity of the entity signing the certificate.
* @param validateRoot true if you want to verify that the root certificate in the chain can be trusted
* based on the truststore.
* @return true if the certificate was successfully imported.
* @throws Exception if no certificates were found in the inputStream.
*/
public static boolean installCert(KeyStore keyStore, KeyStore trustStore, String keyPassword, String alias,
InputStream pkInputStream, InputStream inputStream, boolean trustCACerts,
boolean validateRoot) throws Exception {
// Check that there is a certificate for the specified alias
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);
if (certificate != null) {
Log.warn("Certificate already exists for alias: " + alias);
return false;
}
// Retrieve the private key of the stored certificate
PEMReader pemReader = new PEMReader(new InputStreamReader(pkInputStream));
KeyPair kp = (KeyPair) pemReader.readObject();
PrivateKey privKey = kp.getPrivate();
// Load certificates found in the PEM input stream
List<X509Certificate> certs = new ArrayList<X509Certificate>();
for (Certificate cert : CertificateFactory.getInstance("X509").generateCertificates(inputStream)) {
certs.add((X509Certificate) cert);
}
if (certs.isEmpty()) {
throw new Exception("No certificates were found");
}
List<X509Certificate> newCerts;
if (certs.size() == 1) {
// Reply has only one certificate
newCerts = establishCertChain(keyStore, trustStore, certificate, certs.get(0), trustCACerts);
} else {
// Reply has a chain of certificates
newCerts = validateReply(keyStore, trustStore, alias, certificate, certs, trustCACerts, validateRoot);
}
if (newCerts != null) {
keyStore.setKeyEntry(alias, privKey, keyPassword.toCharArray(),
newCerts.toArray(new X509Certificate[newCerts.size()]));
// Notify listeners that a new certificate has been created (and signed)
for (CertificateEventListener listener : listeners) {
try {
listener.certificateCreated(keyStore, alias, certs.get(0));
if (newCerts.size() > 1) {
listener.certificateSigned(keyStore, alias, newCerts);
}
}
catch (Exception e) {
Log.error(e);
}
}
return true;
} else {
return false;
}
}
/**
* Registers a listener to receive events.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment