Commit 73086ef3 authored by Victor Hong's avatar Victor Hong

Added explicit methods to return identities for client and server certificates

parent 57b37b11
......@@ -77,7 +77,7 @@ public class ClearspaceX509TrustManager implements X509TrustManager {
if (verify) {
int nSize = x509Certificates.length;
List<String> peerIdentities = CertificateManager.getPeerIdentities(x509Certificates[0]);
List<String> peerIdentities = CertificateManager.getServerPeerIdentities(x509Certificates[0]);
if (getBooleanProperty("clearspace.certificate.verify.chain", true)) {
// Working down the chain, for every certificate in the chain,
......
......@@ -189,7 +189,7 @@ public class ClientTrustManager implements X509TrustManager {
if (verify) {
int nSize = x509Certificates.length;
List<String> peerIdentities = CertificateManager.getPeerIdentities(x509Certificates[0]);
List<String> peerIdentities = CertificateManager.getClientPeerIdentities(x509Certificates[0]);
if (JiveGlobals.getBooleanProperty("xmpp.client.certificate.verify.chain", true)) {
// Working down the chain, for every certificate in the chain,
......
......@@ -590,7 +590,7 @@ public class SASLAuthentication {
authenticationFailed(session, Failure.NOT_AUTHORIZED);
return Status.failed;
}
principals.addAll(CertificateManager.getPeerIdentities((X509Certificate)trusted));
principals.addAll(CertificateManager.getClientPeerIdentities((X509Certificate)trusted));
if(principals.size() == 1) {
principal = principals.get(0);
......@@ -640,7 +640,7 @@ public class SASLAuthentication {
}
public static boolean verifyCertificate(X509Certificate trustedCert, String hostname) {
for (String identity : CertificateManager.getPeerIdentities(trustedCert)) {
for (String identity : CertificateManager.getServerPeerIdentities(trustedCert)) {
// Verify that either the identity is the same as the hostname, or for wildcarded
// identities that the hostname ends with .domainspecified or -is- domainspecified.
if ((identity.startsWith("*.")
......
......@@ -116,23 +116,49 @@ public class CertificateManager {
private static List<CertificateEventListener> listeners = new CopyOnWriteArrayList<CertificateEventListener>();
private static List<CertificateIdentityMapping> certIdentityMapping = new ArrayList<CertificateIdentityMapping>();
private static List<CertificateIdentityMapping> serverCertIdentityMapping = new ArrayList<CertificateIdentityMapping>();
private static List<CertificateIdentityMapping> clientCertIdentityMapping = new ArrayList<CertificateIdentityMapping>();
static {
// Add the BC provider to the list of security providers
Security.addProvider(provider);
String classList = JiveGlobals.getProperty("provider.certIdentityMapping.classList");
if (classList != null) {
StringTokenizer st = new StringTokenizer(classList, " ,\t\n\r\f");
String serverCertIdentityMapList = JiveGlobals.getProperty("provider.serverCertIdentityMap.classList");
if (serverCertIdentityMapList != null) {
StringTokenizer st = new StringTokenizer(serverCertIdentityMapList, " ,\t\n\r\f");
while (st.hasMoreTokens()) {
String s_provider = st.nextToken();
try {
Class c_provider = ClassUtils.forName(s_provider);
CertificateIdentityMapping provider =
(CertificateIdentityMapping)(c_provider.newInstance());
Log.debug("CertificateManager: Loaded server identity mapping " + s_provider);
serverCertIdentityMapping.add(provider);
}
catch (Exception e) {
Log.error("CertificateManager: Error loading CertificateIdentityMapping: " + s_provider + "\n" + e);
}
}
}
if (serverCertIdentityMapping.isEmpty()) {
Log.debug("CertificateManager: No server CertificateIdentityMapping's found. Loading default mappings");
serverCertIdentityMapping.add(new SANCertificateIdentityMapping());
serverCertIdentityMapping.add(new CNCertificateIdentityMapping());
}
String clientCertMapList = JiveGlobals.getProperty("provider.clientCertIdentityMap.classList");
if (clientCertMapList != null) {
StringTokenizer st = new StringTokenizer(clientCertMapList, " ,\t\n\r\f");
while (st.hasMoreTokens()) {
String s_provider = st.nextToken();
try {
Class c_provider = ClassUtils.forName(s_provider);
CertificateIdentityMapping provider =
(CertificateIdentityMapping)(c_provider.newInstance());
Log.debug("CertificateManager: Loaded " + s_provider);
certIdentityMapping.add(provider);
Log.debug("CertificateManager: Loaded client identity mapping " + s_provider);
clientCertIdentityMapping.add(provider);
}
catch (Exception e) {
Log.error("CertificateManager: Error loading CertificateIdentityMapping: " + s_provider + "\n" + e);
......@@ -140,10 +166,9 @@ public class CertificateManager {
}
}
if (certIdentityMapping.isEmpty()) {
Log.debug("CertificateManager: No CertificateIdentityMapping's found. Loading default mappings");
certIdentityMapping.add(new SANCertificateIdentityMapping());
certIdentityMapping.add(new CNCertificateIdentityMapping());
if (clientCertIdentityMapping.isEmpty()) {
Log.debug("CertificateManager: No client CertificateIdentityMapping's found. Loading default mappings");
clientCertIdentityMapping.add(new CNCertificateIdentityMapping());
}
}
......@@ -358,20 +383,41 @@ public class CertificateManager {
return null;
}
/**
* Returns the identities of the remote client as defined in the specified certificate. The
* identities are mapped by the classes in the "provider.clientCertIdentityMap.classList" property.
* By default, the subjectDN of the certificate is used.
*
* @param x509Certificate the certificate the holds the identities of the remote server.
* @return the identities of the remote client as defined in the specified certificate.
*/
public static List<String> getClientPeerIdentities(X509Certificate x509Certificate) {
List<String> names = new ArrayList<String>();
for (CertificateIdentityMapping mapping : clientCertIdentityMapping) {
List<String> identities = mapping.mapIdentity(x509Certificate);
Log.debug("CertificateManager: " + mapping.name() + " returned " + identities.toString());
names.addAll(identities);
}
return names;
}
/**
* Returns the identities of the remote server as defined in the specified certificate. The
* identities are defined in the subjectDN of the certificate and it can also be defined in
* the subjectAltName extensions of type "xmpp". When the extension is being used then the
* identities are mapped by the classes in the "provider.serverCertIdentityMap.classList" property.
* By default, the identities are defined in the subjectDN of the certificate and it can also be
* defined in the subjectAltName extensions of type "xmpp". When the extension is being used then the
* identities defined in the extension are going to be returned. Otherwise, the value stored in
* the subjectDN is returned.
*
* @param x509Certificate the certificate the holds the identities of the remote server.
* @return the identities of the remote server as defined in the specified certificate.
*/
public static List<String> getPeerIdentities(X509Certificate x509Certificate) {
public static List<String> getServerPeerIdentities(X509Certificate x509Certificate) {
List<String> names = new ArrayList<String>();
for (CertificateIdentityMapping mapping : certIdentityMapping) {
for (CertificateIdentityMapping mapping : serverCertIdentityMapping) {
List<String> identities = mapping.mapIdentity(x509Certificate);
Log.debug("CertificateManager: " + mapping.name() + " returned " + identities.toString());
names.addAll(identities);
......@@ -438,7 +484,7 @@ public class CertificateManager {
}
else {
// Only accept certified domains that match the specified domain
for (String identity : getPeerIdentities(certificate)) {
for (String identity : getServerPeerIdentities(certificate)) {
if (identity.endsWith(domain) && certificate.getPublicKey().getAlgorithm().equals(algorithm)) {
result = true;
}
......
......@@ -210,7 +210,7 @@
String a = (String) aliases.nextElement();
X509Certificate c = (X509Certificate) keyStore.getCertificate(a);
StringBuffer identities = new StringBuffer();
for (String identity : CertificateManager.getPeerIdentities(c)) {
for (String identity : CertificateManager.getServerPeerIdentities(c)) {
identities.append(identity).append(", ");
}
if (identities.length() > 0) {
......
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