Commit 6471f15c authored by André Berenguel's avatar André Berenguel Committed by Guus der Kinderen

Reactivating the signing certificate feature

parent 71cb91c1
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
package org.jivesoftware.openfire.session; package org.jivesoftware.openfire.session;
import java.io.IOException; import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
...@@ -36,7 +35,6 @@ import org.jivesoftware.openfire.SessionManager; ...@@ -36,7 +35,6 @@ import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.StreamID; import org.jivesoftware.openfire.StreamID;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.keystore.CertificateStoreManager;
import org.jivesoftware.openfire.net.SASLAuthentication; import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.net.SocketConnection; import org.jivesoftware.openfire.net.SocketConnection;
import org.jivesoftware.openfire.server.ServerDialback; import org.jivesoftware.openfire.server.ServerDialback;
...@@ -371,8 +369,7 @@ public class LocalIncomingServerSession extends LocalServerSession implements In ...@@ -371,8 +369,7 @@ public class LocalIncomingServerSession extends LocalServerSession implements In
usingSelfSigned = true; usingSelfSigned = true;
} else { } else {
try { try {
final KeyStore keyStore = XMPPServer.getInstance().getCertificateStoreManager().getIdentityStore( ConnectionType.SOCKET_S2S ).getStore(); usingSelfSigned = CertificateManager.isSelfSignedCertificate((X509Certificate) chain[0]);
usingSelfSigned = CertificateManager.isSelfSignedCertificate(keyStore, (X509Certificate) chain[0]);
} catch (KeyStoreException ex) { } catch (KeyStoreException ex) {
Log.warn("Exception occurred while trying to determine whether local certificate is self-signed. Proceeding as if it is.", ex); Log.warn("Exception occurred while trying to determine whether local certificate is self-signed. Proceeding as if it is.", ex);
usingSelfSigned = true; usingSelfSigned = true;
......
...@@ -32,6 +32,7 @@ import java.security.GeneralSecurityException; ...@@ -32,6 +32,7 @@ import java.security.GeneralSecurityException;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchProviderException;
import java.security.Principal; import java.security.Principal;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
...@@ -43,6 +44,7 @@ import java.security.cert.CertPathValidator; ...@@ -43,6 +44,7 @@ import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStore; import java.security.cert.CertStore;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters; import java.security.cert.CollectionCertStoreParameters;
...@@ -70,6 +72,7 @@ import org.bouncycastle.asn1.DERSequence; ...@@ -70,6 +72,7 @@ import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extension;
...@@ -78,6 +81,7 @@ import org.bouncycastle.asn1.x509.GeneralNames; ...@@ -78,6 +81,7 @@ import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.CertException;
import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.openssl.MiscPEMGenerator; import org.bouncycastle.openssl.MiscPEMGenerator;
...@@ -420,28 +424,17 @@ public class CertificateManager { ...@@ -420,28 +424,17 @@ public class CertificateManager {
* @return true if the specified certificate is a self-signed certificate. * @return true if the specified certificate is a self-signed certificate.
* @throws KeyStoreException if an error happens while usign the keystore * @throws KeyStoreException if an error happens while usign the keystore
*/ */
public static boolean isSelfSignedCertificate(KeyStore keyStore, String alias) throws KeyStoreException { public static boolean isSelfSignedCertificate(X509Certificate certificate) throws KeyStoreException {
// Get certificate chain
java.security.cert.Certificate[] certificateChain = keyStore.getCertificateChain( alias );
// Verify that the chain is empty or was signed by himself
return certificateChain == null || certificateChain.length == 1;
}
/** try {
* Returns true if the specified certificate is a self-signed certificate. If the certificate JcaX509CertificateHolder certificateHolder = new JcaX509CertificateHolder(certificate);
* was not found in the store then a KeyStoreException is returned. ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider("BC").build(
* certificate.getPublicKey());
* @param keyStore key store that holds the certificate to verify.
* @param certificate the certificate in the key store. return certificateHolder.isSignatureValid(verifier);
* @return true if the specified certificate is a self-signed certificate. } catch (CertException | CertificateEncodingException | OperatorCreationException e) {
* @throws KeyStoreException if an error happens while usign the keystore return certificate.getSubjectDN().equals(certificate.getIssuerDN());
*/
public static boolean isSelfSignedCertificate(KeyStore keyStore, X509Certificate certificate) throws KeyStoreException {
String alias = keyStore.getCertificateAlias( certificate );
if (alias == null) {
throw new KeyStoreException("Certificate not found in store: " + certificate);
} }
return isSelfSignedCertificate(keyStore, alias);
} }
/** /**
...@@ -454,14 +447,13 @@ public class CertificateManager { ...@@ -454,14 +447,13 @@ public class CertificateManager {
* @return true if the specified certificate is ready to be signed by a Certificate Authority. * @return true if the specified certificate is ready to be signed by a Certificate Authority.
* @throws KeyStoreException if an error happens while usign the keystore * @throws KeyStoreException if an error happens while usign the keystore
*/ */
public static boolean isSigningRequestPending(KeyStore keyStore, String alias) throws KeyStoreException { public static boolean isSigningRequestPending(X509Certificate certificate) throws KeyStoreException {
// Verify that this is a self-signed certificate // Verify that this is a self-signed certificate
if (!isSelfSignedCertificate(keyStore, alias)) { if (!isSelfSignedCertificate(certificate)) {
return false; return false;
} }
// Verify that the issuer information has been entered // Verify that the issuer information has been entered
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); Matcher matcher = valuesPattern.matcher(certificate.getIssuerDN().toString());
Matcher matcher = valuesPattern.matcher( certificate.getIssuerDN().toString() );
return matcher.find() && matcher.find(); return matcher.find() && matcher.find();
} }
...@@ -517,7 +509,7 @@ public class CertificateManager { ...@@ -517,7 +509,7 @@ public class CertificateManager {
* @return true if the CA reply was successfully processed. * @return true if the CA reply was successfully processed.
* @throws Exception * @throws Exception
*/ */
public static boolean installReply(KeyStore keyStore, KeyStore trustStore, String keyPassword, String alias, InputStream inputStream) throws Exception { public static boolean installReply(KeyStore keyStore, KeyStore trustStore, char[] keyPassword, String alias, InputStream inputStream) throws Exception {
// Check that there is a certificate for the specified alias // Check that there is a certificate for the specified alias
X509Certificate certificate = (X509Certificate) keyStore.getCertificate( alias ); X509Certificate certificate = (X509Certificate) keyStore.getCertificate( alias );
...@@ -526,7 +518,7 @@ public class CertificateManager { ...@@ -526,7 +518,7 @@ public class CertificateManager {
return false; return false;
} }
// Retrieve the private key of the stored certificate // Retrieve the private key of the stored certificate
PrivateKey privKey = (PrivateKey) keyStore.getKey(alias, keyPassword.toCharArray()); PrivateKey privKey = (PrivateKey) keyStore.getKey(alias, keyPassword);
// Load certificates found in the PEM input stream // Load certificates found in the PEM input stream
Collection<X509Certificate> certs = parseCertificates( inputStream ); Collection<X509Certificate> certs = parseCertificates( inputStream );
if (certs.isEmpty()) { if (certs.isEmpty()) {
...@@ -544,7 +536,7 @@ public class CertificateManager { ...@@ -544,7 +536,7 @@ public class CertificateManager {
{ {
return false; return false;
} }
keyStore.setKeyEntry(alias, privKey, keyPassword.toCharArray(), newCerts.toArray(new X509Certificate[newCerts.size()])); keyStore.setKeyEntry(alias, privKey, keyPassword, newCerts.toArray(new X509Certificate[newCerts.size()]));
// Notify listeners that a new certificate has been created // Notify listeners that a new certificate has been created
for (CertificateEventListener listener : listeners) { for (CertificateEventListener listener : listeners) {
...@@ -711,7 +703,12 @@ public class CertificateManager { ...@@ -711,7 +703,12 @@ public class CertificateManager {
public static Collection<X509Certificate> parseCertificates(InputStream pemRepresentation) throws IOException, public static Collection<X509Certificate> parseCertificates(InputStream pemRepresentation) throws IOException,
CertificateException { CertificateException {
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); CertificateFactory certificateFactory;
try {
certificateFactory = CertificateFactory.getInstance("X509", "BC");
} catch (NoSuchProviderException e) {
certificateFactory = CertificateFactory.getInstance("X509");
}
return (Collection<X509Certificate>) certificateFactory.generateCertificates(pemRepresentation); return (Collection<X509Certificate>) certificateFactory.generateCertificates(pemRepresentation);
} }
...@@ -750,7 +747,7 @@ public class CertificateManager { ...@@ -750,7 +747,7 @@ public class CertificateManager {
throw new Exception("Certificate reply and certificate in keystore are identical"); throw new Exception("Certificate reply and certificate in keystore are identical");
} }
} }
Map<Principal, List<X509Certificate>> knownCerts = new Hashtable<>(); Map<String, List<X509Certificate>> knownCerts = new Hashtable<>();
// TODO Figure out why we add keystore issuers. This implies that we always trust the issuer of our identitity (which probably is right, but shouldn't be required) // TODO Figure out why we add keystore issuers. This implies that we always trust the issuer of our identitity (which probably is right, but shouldn't be required)
if (keyStore.size() > 0) { if (keyStore.size() > 0) {
...@@ -779,7 +776,7 @@ public class CertificateManager { ...@@ -779,7 +776,7 @@ public class CertificateManager {
* @return true if the entire chain of all certificates was successfully built. * @return true if the entire chain of all certificates was successfully built.
*/ */
private static boolean buildChain(X509Certificate certificate, LinkedList<X509Certificate> answer, private static boolean buildChain(X509Certificate certificate, LinkedList<X509Certificate> answer,
Map<Principal, List<X509Certificate>> knownCerts) { Map<String, List<X509Certificate>> knownCerts) {
Principal subject = certificate.getSubjectDN(); Principal subject = certificate.getSubjectDN();
Principal issuer = certificate.getIssuerDN(); Principal issuer = certificate.getIssuerDN();
// Check if the certificate is a root certificate (i.e. was issued by the same Principal that // Check if the certificate is a root certificate (i.e. was issued by the same Principal that
...@@ -789,7 +786,7 @@ public class CertificateManager { ...@@ -789,7 +786,7 @@ public class CertificateManager {
return true; return true;
} }
// Get the list of known certificates of the certificate's issuer // Get the list of known certificates of the certificate's issuer
List<X509Certificate> issuerCerts = knownCerts.get(issuer); List<X509Certificate> issuerCerts = knownCerts.get(issuer.getName());
if (issuerCerts == null || issuerCerts.isEmpty()) { if (issuerCerts == null || issuerCerts.isEmpty()) {
// No certificates were found so building of chain failed // No certificates were found so building of chain failed
return false; return false;
...@@ -820,9 +817,9 @@ public class CertificateManager { ...@@ -820,9 +817,9 @@ public class CertificateManager {
* @return a map with the certificates per issuer. * @return a map with the certificates per issuer.
* @throws Exception * @throws Exception
*/ */
private static Map<Principal, List<X509Certificate>> getCertsByIssuer(KeyStore ks) private static Map<String, List<X509Certificate>> getCertsByIssuer(KeyStore ks)
throws Exception { throws Exception {
Map<Principal, List<X509Certificate>> answer = new HashMap<>(); Map<String, List<X509Certificate>> answer = new HashMap<>();
Enumeration<String> aliases = ks.aliases(); Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) { while (aliases.hasMoreElements()) {
String alias = aliases.nextElement(); String alias = aliases.nextElement();
...@@ -839,7 +836,7 @@ public class CertificateManager { ...@@ -839,7 +836,7 @@ public class CertificateManager {
vec.add(cert); vec.add(cert);
} }
} }
answer.put(subjectDN, vec); answer.put(subjectDN.getName(), vec);
} }
} }
return answer; return answer;
...@@ -982,6 +979,33 @@ public class CertificateManager { ...@@ -982,6 +979,33 @@ public class CertificateManager {
String subjectCommonName, String domain, String subjectCommonName, String domain,
String signAlgoritm) String signAlgoritm)
throws GeneralSecurityException, IOException { throws GeneralSecurityException, IOException {
// subjectDN
X500NameBuilder subjectBuilder = new X500NameBuilder();
subjectBuilder.addRDN(BCStyle.CN, subjectCommonName);
// issuerDN
X500NameBuilder issuerBuilder = new X500NameBuilder();
issuerBuilder.addRDN(BCStyle.CN, issuerCommonName);
return createX509V3Certificate(kp, days, issuerBuilder, subjectBuilder, domain, signAlgoritm);
}
/**
* Creates an X509 version3 certificate.
*
* @param kp KeyPair that keeps the public and private keys for the new certificate.
* @param days time to live
* @param issuerBuilder Issuer CN builder
* @param subjectBuilder Subject CN builder
* @param domain Domain of the server.
* @param signAlgoritm Signature algorithm. This can be either a name or an OID.
* @return X509 V3 Certificate
* @throws GeneralSecurityException
* @throws IOException
*/
public static synchronized X509Certificate createX509V3Certificate(KeyPair kp, int days, X500NameBuilder issuerBuilder,
X500NameBuilder subjectBuilder, String domain, String signAlgoritm) throws GeneralSecurityException, IOException {
PublicKey pubKey = kp.getPublic(); PublicKey pubKey = kp.getPublic();
PrivateKey privKey = kp.getPrivate(); PrivateKey privKey = kp.getPrivate();
...@@ -991,26 +1015,21 @@ public class CertificateManager { ...@@ -991,26 +1015,21 @@ public class CertificateManager {
random.nextBytes(serno); random.nextBytes(serno);
BigInteger serial = (new java.math.BigInteger(serno)).abs(); BigInteger serial = (new java.math.BigInteger(serno)).abs();
// subjectDN X500Name issuerDN = issuerBuilder.build();
X500NameBuilder subjectBuilder = new X500NameBuilder(); X500Name subjectDN = issuerBuilder.build();
subjectBuilder.addRDN(BCStyle.CN, subjectCommonName);
// issuerDN
X500NameBuilder issuerBuilder = new X500NameBuilder();
issuerBuilder.addRDN(BCStyle.CN, issuerCommonName);
// builder // builder
JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( // JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( //
issuerBuilder.build(), // issuerDN, //
serial, // serial, //
new Date(), // new Date(), //
new Date(System.currentTimeMillis() + days * (1000L * 60 * 60 * 24)), // new Date(System.currentTimeMillis() + days * (1000L * 60 * 60 * 24)), //
subjectBuilder.build(), subjectDN, //
pubKey // pubKey //
); );
// add subjectAlternativeName extension // add subjectAlternativeName extension
boolean critical = subjectCommonName == null || "".equals(subjectCommonName.trim()); boolean critical = subjectDN.getRDNs().length == 0;
ASN1Sequence othernameSequence = new DERSequence(new ASN1Encodable[]{ ASN1Sequence othernameSequence = new DERSequence(new ASN1Encodable[]{
new ASN1ObjectIdentifier("1.3.6.1.5.5.7.8.5"), new DERTaggedObject(true, 0, new DERUTF8String(domain))}); new ASN1ObjectIdentifier("1.3.6.1.5.5.7.8.5"), new DERTaggedObject(true, 0, new DERUTF8String(domain))});
GeneralName othernameGN = new GeneralName(GeneralName.otherName, othernameSequence); GeneralName othernameGN = new GeneralName(GeneralName.otherName, othernameSequence);
......
<%@page import="java.util.Enumeration"%>
<%@page import="org.jivesoftware.openfire.XMPPServer"%>
<%@page import="java.security.PublicKey"%>
<%@page import="java.security.KeyPair"%>
<%@page import="java.security.cert.X509Certificate"%>
<%@page import="java.security.PrivateKey"%>
<%@page import="org.jivesoftware.openfire.keystore.IdentityStore"%>
<%@page import="java.security.KeyStore"%>
<%@page import="org.bouncycastle.asn1.x500.X500Name"%>
<%@page import="org.bouncycastle.asn1.x500.style.BCStyle"%>
<%@page import="org.bouncycastle.asn1.x509.Extension"%>
<%@page import="org.bouncycastle.asn1.x500.X500NameBuilder"%>
<%@page import="org.jivesoftware.util.CertificateManager"%>
<%@ page import="org.jivesoftware.util.ParamUtils" %> <%@ page import="org.jivesoftware.util.ParamUtils" %>
<%@ page import="org.jivesoftware.util.StringUtils" %> <%@ page import="org.jivesoftware.util.StringUtils" %>
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.HashMap" %>
...@@ -10,99 +23,101 @@ ...@@ -10,99 +23,101 @@
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" /> <jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
<% webManager.init(request, response, session, application, out ); %> <% webManager.init(request, response, session, application, out ); %>
<% // Get parameters: <%
String domain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
// Get parameters:
final boolean save = ParamUtils.getParameter(request, "save") != null; final boolean save = ParamUtils.getParameter(request, "save") != null;
final String name = ParamUtils.getParameter(request, "name"); final String name = domain;
final String organizationalUnit = ParamUtils.getParameter(request, "ou"); final String organizationalUnit = ParamUtils.getParameter(request, "ou");
final String organization = ParamUtils.getParameter(request, "o"); final String organization = ParamUtils.getParameter(request, "o");
final String city = ParamUtils.getParameter(request, "city"); final String city = ParamUtils.getParameter(request, "city");
final String state = ParamUtils.getParameter(request, "state"); final String state = ParamUtils.getParameter(request, "state");
final String countryCode = ParamUtils.getParameter(request, "country"); final String countryCode = ParamUtils.getParameter(request, "country");
final String storePurposeText = ParamUtils.getParameter(request, "connectionType"); final String connectionTypeText = ParamUtils.getParameter( request, "connectionType" );
final Map<String, String> errors = new HashMap<String, String>(); final Map<String, String> errors = new HashMap<String, String>();
ConnectionType connectionType; ConnectionType connectionType = null;
IdentityStore identityStore = null;
try try
{ {
connectionType = ConnectionType.valueOf( storePurposeText ); connectionType = ConnectionType.valueOf( connectionTypeText );
} catch (RuntimeException ex) { identityStore = XMPPServer.getInstance().getCertificateStoreManager().getIdentityStore( connectionType );
if ( identityStore == null )
{
errors.put( "identityStore", "Unable to get an instance." );
}
}
catch (RuntimeException ex)
{
errors.put( "connectionType", ex.getMessage() ); errors.put( "connectionType", ex.getMessage() );
connectionType = null;
} }
pageContext.setAttribute( "connectionType", connectionType ); pageContext.setAttribute( "connectionType", connectionType );
// if (save) { if (save) {
//
// // Verify that fields were completed // Verify that fields were completed
// if (name == null) { if (organizationalUnit == null) {
// errors.put("name", ""); errors.put("organizationalUnit", "");
// } }
// if (organizationalUnit == null) { if (organization == null) {
// errors.put("organizationalUnit", ""); errors.put("organization", "");
// } }
// if (organization == null) { if (city == null) {
// errors.put("organization", ""); errors.put("city", "");
// } }
// if (city == null) { if (state == null) {
// errors.put("city", ""); errors.put("state", "");
// } }
// if (state == null) { if (countryCode == null) {
// errors.put("state", ""); errors.put("countryCode", "");
// } }
// if (countryCode == null) { if (errors.size() == 0) {
// errors.put("countryCode", ""); try {
// } X500NameBuilder builder = new X500NameBuilder();
// if (errors.size() == 0) { builder.addRDN(BCStyle.CN, name);
// try { builder.addRDN(BCStyle.OU, organizationalUnit);
// final IdentityStore identityStoreConfig = (IdentityStore) SSLConfig.getInstance().getStoreConfig( connectionType ); builder.addRDN(BCStyle.O, organization);
// builder.addRDN(BCStyle.L, city);
// identityStoreConfig.ensureSelfSignedDomainCertificates( name, organizationalUnit, organization, city, state, countryCode, "rsa", "dsa" ); builder.addRDN(BCStyle.ST, state);
// // Regenerate self-sign certs whose subjectDN matches the issuerDN and set the new issuerDN builder.addRDN(BCStyle.C, countryCode);
// String domain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
// StringBuilder issuerDN = new StringBuilder(); // Update certs with new issuerDN information
// issuerDN.append("CN=").append(name); KeyStore keyStore = identityStore.getStore();
// issuerDN.append(", OU=").append(organizationalUnit); for (Enumeration<String> certAliases = keyStore.aliases(); certAliases.hasMoreElements();) {
// issuerDN.append(", O=").append(organization);
// issuerDN.append(", L=").append(city); String alias = certAliases.nextElement();
// issuerDN.append(", ST=").append(state); X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);
// issuerDN.append(", C=").append(countryCode);
// StringBuilder subjectDN = new StringBuilder(); // Update only Self-signed certs
// subjectDN.append("CN=").append(domain); if (CertificateManager.isSelfSignedCertificate(certificate)) {
// subjectDN.append(", OU=").append(organizationalUnit);
// subjectDN.append(", O=").append(organization); PrivateKey privKey = (PrivateKey) keyStore.getKey(alias, identityStore.getConfiguration().getPassword());
// subjectDN.append(", L=").append(city); PublicKey pubKey = certificate.getPublicKey();
// subjectDN.append(", ST=").append(state);
// subjectDN.append(", C=").append(countryCode); String signAlgoritm = "SHA256WITH" + pubKey.getAlgorithm();
// // Update certs with new issuerDN information int days = 60;
// for (Enumeration<String> certAliases = keyStore.aliases(); certAliases.hasMoreElements();) {
// String alias = certAliases.nextElement(); // Regenerate self-sign certs whose subjectDN matches the issuerDN and set the new issuerDN
// X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); X509Certificate newCertificate = CertificateManager.createX509V3Certificate(new KeyPair(pubKey, privKey), days, builder, builder, domain, signAlgoritm);
// // Update only Self-signed certs keyStore.setKeyEntry(alias, privKey, identityStore.getConfiguration().getPassword(), new X509Certificate[] { newCertificate });
// if (CertificateManager.isSelfSignedCertificate(keyStore, alias)) { }
// if (CertificateManager.isDSACertificate(certificate)) { }
// CertificateManager.createDSACert(keyStore, sslConfig.getKeyStorePassword(), alias, // Save keystore
// issuerDN.toString(), subjectDN.toString(), "*." + domain); identityStore.persist();
// } else { // Log the event
// CertificateManager.createRSACert(keyStore, sslConfig.getKeyStorePassword(), alias, webManager.logEvent("generated SSL signing request", null);
// issuerDN.toString(), subjectDN.toString(), "*." + domain); response.sendRedirect("security-keystore.jsp?connectionType="+connectionType);
// } return;
// } }
// } catch (Exception e) {
// // Save keystore e.printStackTrace();
// sslConfig.saveStores(); errors.put("general", "");
// // Log the event }
// webManager.logEvent("generated SSL signing request", null); }
// response.sendRedirect("security-keystore.jsp?connectivityType="+connectivityType); }
// return;
// }
// catch (Exception e) {
// e.printStackTrace();
// errors.put("general", "");
// }
// }
// }
%> %>
<html> <html>
...@@ -110,7 +125,7 @@ ...@@ -110,7 +125,7 @@
<title> <title>
<fmt:message key="ssl.signing-request.title"/> <fmt:message key="ssl.signing-request.title"/>
</title> </title>
<meta name="pageID" content="security-keystore-${connectivityType}"/> <meta name="pageID" content="security-keystore-${connectionType}"/>
</head> </head>
<body> <body>
...@@ -118,9 +133,6 @@ ...@@ -118,9 +133,6 @@
<c:forEach var="err" items="${errors}"> <c:forEach var="err" items="${errors}">
<admin:infobox type="error"> <admin:infobox type="error">
<c:choose> <c:choose>
<c:when test="${err.key eq 'name'}">
<fmt:message key="ssl.signing-request.enter_name" />
</c:when>
<c:when test="${err.key eq 'organizationalUnit'}"> <c:when test="${err.key eq 'organizationalUnit'}">
<fmt:message key="ssl.signing-request.enter_ou" /> <fmt:message key="ssl.signing-request.enter_ou" />
</c:when> </c:when>
...@@ -147,9 +159,9 @@ ...@@ -147,9 +159,9 @@
</c:forEach> </c:forEach>
<!-- BEGIN 'Issuer information form' --> <!-- BEGIN 'Issuer information form' -->
<form action="ssl-signing-request.jsp" method="post"> <form action="security-keystore-signing-request.jsp" method="post">
<input type="hidden" name="save" value="true"> <input type="hidden" name="save" value="true">
<input type="hidden" name="connectivityType" value="${connectivityType}"> <input type="hidden" name="connectionType" value="${connectionType}">
<div class="jive-contentBoxHeader"> <div class="jive-contentBoxHeader">
<fmt:message key="ssl.signing-request.issuer_information"/> <fmt:message key="ssl.signing-request.issuer_information"/>
</div> </div>
...@@ -167,7 +179,7 @@ ...@@ -167,7 +179,7 @@
</td> </td>
<td width="99%"> <td width="99%">
<input type="text" name="name" size="50" maxlength="75" <input type="text" name="name" size="50" maxlength="75"
value="<%= ((name!=null) ? StringUtils.escapeForXML(name) : "") %>" id="namef"> value="<%= ((name!=null) ? StringUtils.escapeForXML(name) : "") %>" id="namef" disabled="disabled">
</td> </td>
</tr> </tr>
<tr> <tr>
......
<%@page import="org.jivesoftware.util.StringUtils"%>
<%@page import="java.util.LinkedHashMap"%>
<%@page import="java.security.PrivateKey"%>
<%@page import="org.jivesoftware.util.CertificateManager"%>
<%@ page errorPage="error.jsp" %> <%@ page errorPage="error.jsp" %>
<%@ page import="org.jivesoftware.openfire.XMPPServer" %> <%@ page import="org.jivesoftware.openfire.XMPPServer" %>
...@@ -107,14 +111,13 @@ ...@@ -107,14 +111,13 @@
errors.put("generate", e.getMessage()); errors.put("generate", e.getMessage());
} }
} }
/*
if (importReply) { if (importReply) {
String reply = ParamUtils.getParameter(request, "reply"); String reply = ParamUtils.getParameter(request, "reply");
if (alias != null && reply != null && reply.trim().length() > 0) { if (alias != null && reply != null && reply.trim().length() > 0) {
try { try {
CertificateManager.installReply( keyStore, s2sTrustStore, identityStore.installCSRReply(alias, reply);
sslConfig.getKeyStorePassword(), alias, new ByteArrayInputStream( reply.getBytes() ) ); identityStore.persist();
sslConfig.saveStores();
// Log the event // Log the event
webManager.logEvent( "imported SSL certificate with alias " + alias, null ); webManager.logEvent( "imported SSL certificate with alias " + alias, null );
response.sendRedirect("security-keystore.jsp?connectionType="+connectionType); response.sendRedirect("security-keystore.jsp?connectionType="+connectionType);
...@@ -125,10 +128,12 @@ ...@@ -125,10 +128,12 @@
} }
} }
} }
*/
final boolean restartNeeded = ( (AdminConsolePlugin) XMPPServer.getInstance().getPluginManager().getPlugin( "admin" ) ).isRestartNeeded(); final boolean restartNeeded = ( (AdminConsolePlugin) XMPPServer.getInstance().getPluginManager().getPlugin( "admin" ) ).isRestartNeeded();
pageContext.setAttribute( "restartNeeded", restartNeeded ); pageContext.setAttribute( "restartNeeded", restartNeeded );
boolean offerUpdateIssuer = false;
Map<String, String> signingRequests = new LinkedHashMap<String, String>();
%> %>
<html> <html>
...@@ -233,38 +238,19 @@ ...@@ -233,38 +238,19 @@
<c:set var="alias" value="${certificateEntry.key}"/> <c:set var="alias" value="${certificateEntry.key}"/>
<c:set var="identities" value="${admin:serverIdentities(certificateEntry.value)}"/> <c:set var="identities" value="${admin:serverIdentities(certificateEntry.value)}"/>
<% <%
// TODO restore this functionality String rowAlias = (String) pageContext.getAttribute("alias");
// int i = 0; X509Certificate certificate = (X509Certificate) pageContext.getAttribute("certificate");
// boolean offerUpdateIssuer = false;
// Map<String, String> signingRequests = new LinkedHashMap<String, String>(); boolean isSelfSigned = CertificateManager.isSelfSignedCertificate(certificate);
// if (keyStore != null && keyStore.aliases().hasMoreElements()) { boolean isSigningPending = CertificateManager.isSigningRequestPending(certificate);
// for (Enumeration aliases = keyStore.aliases(); aliases.hasMoreElements(); ) {
// i++; offerUpdateIssuer = offerUpdateIssuer || isSelfSigned || isSigningPending;
// String a = (String) aliases.nextElement();
// X509Certificate c = (X509Certificate) keyStore.getCertificate(a); if (isSigningPending) {
// StringBuffer identities = new StringBuffer(); // Generate new signing request for certificate
// for (String identity : CertificateManager.getServerIdentities(c)) { signingRequests.put(rowAlias, identityStore.generateCSR(rowAlias));
// identities.append(identity).append(", "); }
// }
// if (identities.length() > 0) {
// identities.setLength(identities.length() - 2);
// }
// // Self-signed certs are certs generated by Openfire whose IssueDN equals SubjectDN
// boolean isSelfSigned = CertificateManager.isSelfSignedCertificate(keyStore, a);
// // Signing Request pending = not self signed certs whose chain has only 1 cert (the same cert)
// boolean isSigningPending = CertificateManager.isSigningRequestPending(keyStore, a);
//
// offerUpdateIssuer = offerUpdateIssuer || isSelfSigned || isSigningPending;
// if (isSigningPending) {
// // Generate new signing request for certificate
// PrivateKey privKey = (PrivateKey) keyStore.getKey(a, sslConfig.getKeyStorePassword().toCharArray());
// if (privKey != null) {
// signingRequests.put(a, CertificateManager.createSigningRequest(c, privKey));
// }
// }
// pageContext.setAttribute("identities", identities);
// pageContext.setAttribute("alias", a);
// pageContext.setAttribute("certificate", c);
%> %>
<tr valign="top"> <tr valign="top">
<td> <td>
...@@ -293,30 +279,28 @@ ...@@ -293,30 +279,28 @@
</c:otherwise> </c:otherwise>
</c:choose> </c:choose>
</td> </td>
<%--<% if (isSelfSigned && !isSigningPending) { %>--%> <% if (isSelfSigned && !isSigningPending) { %>
<%--<td width="1%"><img src="images/certificate_warning-16x16.png" width="16" height="16" border="0"--%> <td width="1%"><img src="images/certificate_warning-16x16.png" width="16" height="16" border="0"
<%--alt="<fmt:message key="ssl.certificates.keystore.self-signed.info"/>"--%> alt="<fmt:message key="ssl.certificates.keystore.self-signed.info"/>"
<%--title="<fmt:message key="ssl.certificates.keystore.self-signed.info"/>"></td>--%> title="<fmt:message key="ssl.certificates.keystore.self-signed.info"/>"></td>
<%--<td width="1%" nowrap>--%> <td width="1%" nowrap>
<%--<fmt:message key="ssl.certificates.self-signed"/>--%> <fmt:message key="ssl.certificates.self-signed"/>
<%--</td>--%> </td>
<%--<% } else if (isSigningPending) { %>--%> <% } else if (isSigningPending) { %>
<%--<td width="1%"><img src="images/certificate_warning-16x16.png" width="16" height="16" border="0"--%> <td width="1%"><img src="images/certificate_warning-16x16.png" width="16" height="16" border="0"
<%--alt="<fmt:message key="ssl.certificates.keystore.signing-pending.info"/>"--%> alt="<fmt:message key="ssl.certificates.keystore.signing-pending.info"/>"
<%--title="<fmt:message key="ssl.certificates.keystore.signing-pending.info"/>"></td>--%> title="<fmt:message key="ssl.certificates.keystore.signing-pending.info"/>"></td>
<%--<td width="1%" nowrap>--%> <td width="1%" nowrap>
<%--<fmt:message key="ssl.certificates.signing-pending"/>--%> <fmt:message key="ssl.certificates.signing-pending"/>
<%--</td>--%> </td>
<%--<% } else { %>--%> <% } else { %>
<%--<td width="1%"><img src="images/certificate_ok-16x16.png" width="16" height="16" border="0"--%> <td width="1%"><img src="images/certificate_ok-16x16.png" width="16" height="16" border="0"
<%--alt="<fmt:message key="ssl.certificates.keystore.ca-signed.info"/>"--%> alt="<fmt:message key="ssl.certificates.keystore.ca-signed.info"/>"
<%--title="<fmt:message key="ssl.certificates.keystore.ca-signed.info"/>"></td>--%> title="<fmt:message key="ssl.certificates.keystore.ca-signed.info"/>"></td>
<%--<td width="1%" nowrap>--%> <td width="1%" nowrap>
<%--<fmt:message key="ssl.certificates.ca-signed"/>--%> <fmt:message key="ssl.certificates.ca-signed"/>
<%--</td>--%> </td>
<%--<% } %>--%> <% } %>
<td width="1%" nowrap><%-- Restore functionality above --%></td>
<td width="1%" nowrap><%-- Restore functionality above --%></td>
<td width="2%"> <td width="2%">
<c:out value="${certificate.publicKey.algorithm}"/> <c:out value="${certificate.publicKey.algorithm}"/>
</td> </td>
...@@ -327,85 +311,82 @@ ...@@ -327,85 +311,82 @@
><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a> ><img src="images/delete-16x16.gif" width="16" height="16" border="0" alt=""></a>
</td> </td>
</tr> </tr>
<% if (isSigningPending) { %>
<form action="security-keystore.jsp?connectionType=${connectionType}" method="post">
<input type="hidden" name="importReply" value="true">
<input type="hidden" name="alias" value="${alias}">
<tr>
<td colspan="5">
<span class="jive-description">
<fmt:message key="ssl.certificates.truststore.ca-reply"/>
</span>
<textarea name="reply" rows="8" style="width:100%;font-size:8pt;" wrap="virtual"></textarea>
</td>
<td valign="bottom">
<input type="submit" name="install" value="<fmt:message key="global.save"/>">
</td>
</tr>
</form>
<% } %>
</c:forEach> </c:forEach>
</c:otherwise> </c:otherwise>
</c:choose> </c:choose>
<%-- FIXME restore functionality below. --%>
<%--<% if (isSigningPending) { %>--%>
<%--<form action="security-keystore.jsp" method="post">--%>
<%--<input type="hidden" name="importReply" value="true">--%>
<%--<input type="hidden" name="alias" value="${alias}">--%>
<%--<input type="hidden" name="connectivityType" value="${connecticvityType}">--%>
<%--<tr id="pk<%=i%>">--%>
<%--<td colspan="5">--%>
<%--<span class="jive-description">--%>
<%--<fmt:message key="ssl.certificates.truststore.ca-reply"/>--%>
<%--</span>--%>
<%--<textarea name="reply" cols="40" rows="3" style="width:100%;font-size:8pt;" wrap="virtual"></textarea>--%>
<%--</td>--%>
<%--<td valign="bottom">--%>
<%--<input type="submit" name="install" value="<fmt:message key="global.save"/>">--%>
<%--</td>--%>
<%--</tr>--%>
<%--</form>--%>
</tbody> </tbody>
</table> </table>
<!-- END 'Installed Certificates' --> <!-- END 'Installed Certificates' -->
<!-- BEGIN 'Signing request' --> <!-- BEGIN 'Signing request' -->
<%-- FIXME restore functionality below. --%>
<% if (offerUpdateIssuer || !signingRequests.isEmpty()) { %>
<%--<% if (offerUpdateIssuer || !signingRequests.isEmpty()) { %>--%> <br>
<%--<br>--%>
<div class="jive-contentBoxHeader">
<%--<div class="jive-contentBoxHeader">--%> <fmt:message key="ssl.signing-request.title"/>
<%--<fmt:message key="ssl.signing-request.title"/>--%> </div>
<%--</div>--%> <div class="jive-contentBox">
<%--<div class="jive-contentBox">--%> <% if (offerUpdateIssuer) { %>
<%--<% if (offerUpdateIssuer) { %>--%> <p>
<%--<p>--%> <fmt:message key="ssl.signing-request.offer-issuer-information">
<%--<fmt:message key="ssl.signing-request.offer-issuer-information">--%> <fmt:param value="<a href='security-keystore-signing-request.jsp?connectionType=${connectionType}'>"/>
<%--<fmt:param value="<a href='ssl-signing-request.jsp?connectivityType=${connectivityType}'>"/>--%> <fmt:param value="</a>"/>
<%--<fmt:param value="</a>"/>--%> </fmt:message>
<%--</fmt:message>--%> </p>
<%--</p>--%> <% } %>
<%--<% } %>--%> <% if (!signingRequests.isEmpty()) { %>
<%--<% if (!signingRequests.isEmpty()) { %>--%> <p>
<%--<p>--%> <fmt:message key="ssl.signing-request.requests_info"/>
<%--<fmt:message key="ssl.signing-request.requests_info"/>--%> </p>
<%--</p>--%> <table cellpadding="3" cellspacing="2" border="0">
<%--<table cellpadding="3" cellspacing="2" border="0">--%> <thead>
<%--<thead>--%> <tr>
<%--<tr>--%> <th>
<%--<th>--%> <fmt:message key="ssl.signing-request.alias"/>
<%--<fmt:message key="ssl.signing-request.alias"/>--%> </th>
<%--</th>--%> <th>
<%--<th>--%> <fmt:message key="ssl.signing-request.signing-request"/>
<%--<fmt:message key="ssl.signing-request.signing-request"/>--%> </th>
<%--</th>--%> </tr>
<%--</tr>--%> </thead>
<%--</thead>--%> <tbody>
<%--<tbody>--%> <% for (Map.Entry<String, String> entry : signingRequests.entrySet()) { %>
<%--<% for (Map.Entry<String, String> entry : signingRequests.entrySet()) { %>--%> <tr>
<%--<tr>--%> <td valign="top">
<%--<td valign="top">--%> <%= entry.getKey() %>
<%--<%= entry.getKey() %>--%> </td>
<%--</td>--%> <td style="font-family: monospace;">
<%--<td style="font-family: monospace;">--%> <%= StringUtils.escapeHTMLTags(entry.getValue()) %>
<%--<%= StringUtils.escapeHTMLTags(entry.getValue()) %>--%> </td>
<%--</td>--%> </tr>
<%--</tr>--%> <% } %>
<%--<% } %>--%> </tbody>
<%--</tbody>--%> </table>
<%--</table>--%> <% } %>
<%--<% } %>--%> </div>
<%--</div>--%> <% } %>
<%--<% } %>--%> <!-- END 'Signing request' -->
<%--<!-- END 'Signing request' -->--%> <form action="/security-certificate-store-management.jsp">
<%--<form action="/security-certificate-store-management.jsp">--%> <input type="submit" name="done" value="<fmt:message key="global.done" />">
<%--<input type="submit" name="done" value="<fmt:message key="global.done" />">--%> </form>
<%--</form>--%>
</body> </body>
</html> </html>
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