Index: framework/security/entitydef/entitymodel.xml
===================================================================
--- framework/security/entitydef/entitymodel.xml	(revision 532685)
+++ framework/security/entitydef/entitymodel.xml	(working copy)
@@ -52,6 +52,7 @@
       <field name="cityLocality" type="value"></field>
       <field name="stateProvince" type="value"></field>
       <field name="country" type="value"></field>
+      <field name="serialNumber" type="value"></field>
       <prim-key field="certProvisionId"/>
     </entity>
 
Index: framework/base/src/base/org/ofbiz/base/component/ComponentConfig.java
===================================================================
--- framework/base/src/base/org/ofbiz/base/component/ComponentConfig.java	(revision 532685)
+++ framework/base/src/base/org/ofbiz/base/component/ComponentConfig.java	(working copy)
@@ -28,14 +28,12 @@
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
+import java.security.KeyStore;
 import javax.xml.parsers.ParserConfigurationException;
 
 import javolution.util.FastList;
 import javolution.util.FastMap;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilURL;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.*;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
@@ -644,8 +642,7 @@
         }
     }
 
-    public static class KeystoreInfo extends ResourceInfo {
-        public ComponentConfig componentConfig;
+    public static class KeystoreInfo extends ResourceInfo {        
         public String name;
         public String type;
         public String password;
@@ -661,6 +658,18 @@
             this.isTrustStore = "true".equalsIgnoreCase(element.getAttribute("is-truststore"));
         }
 
+        public KeyStore getKeyStore() {
+            ComponentResourceHandler rh = this.createResourceHandler();
+            if (rh != null) {
+                try {
+                    return KeyStoreUtil.getStore(rh.getURL(), this.getPassword(), this.getType());
+                } catch (Exception e) {
+                    Debug.logWarning(e, module);
+                }
+            }
+            return null;
+        }
+
         public String getName() {
             return name;
         }
Index: framework/base/src/base/org/ofbiz/base/util/SSLUtil.java
===================================================================
--- framework/base/src/base/org/ofbiz/base/util/SSLUtil.java	(revision 532685)
+++ framework/base/src/base/org/ofbiz/base/util/SSLUtil.java	(working copy)
@@ -81,11 +81,16 @@
     public static KeyManager[] getKeyManagers(String alias) throws IOException, GeneralSecurityException, GenericConfigException {
         Iterator i = ComponentConfig.getAllKeystoreInfos().iterator();
         List keyMgrs = FastList.newInstance();
+        
         while (i.hasNext()) {
             ComponentConfig.KeystoreInfo ksi = (ComponentConfig.KeystoreInfo) i.next();
             if (ksi.isCertStore()) {
-                KeyStore ks = KeyStoreUtil.getComponentKeyStore(ksi.componentConfig.getComponentName(), ksi.getName());
-                keyMgrs.addAll(Arrays.asList(getKeyManagers(ks, ksi.getPassword(), alias)));
+                KeyStore ks = ksi.getKeyStore();
+                if (ks != null) {
+                    keyMgrs.addAll(Arrays.asList(getKeyManagers(ks, ksi.getPassword(), alias)));
+                } else {
+                    throw new IOException("Unable to load keystore: " + ksi.createResourceHandler().getFullLocation());
+                }
             }
         }
 
@@ -104,9 +109,13 @@
         Iterator i = ComponentConfig.getAllKeystoreInfos().iterator();
         while (i.hasNext()) {
             ComponentConfig.KeystoreInfo ksi = (ComponentConfig.KeystoreInfo) i.next();
-            if (ksi.isCertStore()) {
-                KeyStore ks = KeyStoreUtil.getComponentKeyStore(ksi.componentConfig.getComponentName(), ksi.getName());
-                trustMgrs.addAll(Arrays.asList(getTrustManagers(ks)));
+            if (ksi.isTrustStore()) {
+                KeyStore ks = ksi.getKeyStore();
+                if (ks != null) {
+                    trustMgrs.addAll(Arrays.asList(getTrustManagers(ks)));
+                } else {
+                    throw new IOException("Unable to load keystore: " + ksi.createResourceHandler().getFullLocation());
+                }
             }
         }
 
Index: framework/base/src/base/org/ofbiz/base/util/KeyStoreUtil.java
===================================================================
--- framework/base/src/base/org/ofbiz/base/util/KeyStoreUtil.java	(revision 532685)
+++ framework/base/src/base/org/ofbiz/base/util/KeyStoreUtil.java	(working copy)
@@ -31,6 +31,8 @@
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.Collection;
 import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
 
 import javolution.util.FastMap;
 
@@ -53,7 +55,7 @@
 
     public static KeyStore getComponentKeyStore(String componentName, String keyStoreName) throws IOException, GeneralSecurityException, GenericConfigException {
         ComponentConfig.KeystoreInfo ks = ComponentConfig.getKeystoreInfo(componentName, keyStoreName);
-        return getStore(ks.createResourceHandler().getURL(), ks.getType(), ks.getPassword());
+        return getStore(ks.createResourceHandler().getURL(), ks.getPassword(), ks.getPassword());
     }
 
     public static KeyStore getStore(URL url, String password) throws IOException, GeneralSecurityException {
@@ -92,11 +94,14 @@
     public static Map getCertX500Map(X509Certificate cert) {
         X500Principal x500 = cert.getSubjectX500Principal();
         Map x500Map = FastMap.newInstance();
-
-        String[] x500Opts = x500.getName().split("\\,");
+        
+        String name = x500.getName().replaceAll("\\\\,", "&com;");
+        String[] x500Opts = name.split("\\,");
         for (int x = 0; x < x500Opts.length; x++) {
-            String[] nv = x500Opts[x].split("\\=");
-            x500Map.put(nv[0], nv[1]);
+            if (x500Opts[x].indexOf("=") > -1) {
+                String[] nv = x500Opts[x].split("\\=", 2);                
+                x500Map.put(nv[0].replaceAll("&com;", ","), nv[1].replaceAll("&com;", ","));
+            }
         }
 
         return x500Map;
Index: framework/base/dtd/ofbiz-component.xsd
===================================================================
--- framework/base/dtd/ofbiz-component.xsd	(revision 532685)
+++ framework/base/dtd/ofbiz-component.xsd	(working copy)
@@ -27,6 +27,7 @@
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="entity-resource"/>
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="service-resource"/>
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="test-suite"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="keystore"/>
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="webapp"/>
             </xs:sequence>
             <xs:attributeGroup ref="attlist.ofbiz-component"/>
Index: framework/catalina/src/org/ofbiz/catalina/container/SSLImpl.java
===================================================================
--- framework/catalina/src/org/ofbiz/catalina/container/SSLImpl.java	(revision 532685)
+++ framework/catalina/src/org/ofbiz/catalina/container/SSLImpl.java	(working copy)
@@ -67,6 +67,7 @@
             try {
                 tm = SSLUtil.getTrustManagers();
             } catch (Exception e) {
+                Debug.logError(e, module);
                 throw new ClassNotFoundException(e.getMessage());
             }
         }
Index: framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
===================================================================
--- framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java	(revision 532685)
+++ framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java	(working copy)
@@ -20,6 +20,7 @@
 
 import java.util.*;
 import java.security.cert.X509Certificate;
+import java.math.BigInteger;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletRequest;
@@ -541,17 +542,17 @@
 
                 for (int i = 0; i < clientCerts.length; i++) {
                     X500Principal x500 = clientCerts[i].getSubjectX500Principal();
-                    Debug.log("Checking client certification for authentication: " + x500.getName(), module);
+                    //Debug.log("Checking client certification for authentication: " + x500.getName(), module);
                     
-                    Map x500Map = KeyStoreUtil.getCertX500Map(clientCerts[i]);                    
+                    Map x500Map = KeyStoreUtil.getCertX500Map(clientCerts[i]);
                     if (i == 0) {
                         userLoginId = (String) x500Map.get("CN");
                     }
 
                     try {
                         // check for a valid issuer (or generated cert data)
-                        if (LoginWorker.checkValidIssuer(delegator, x500Map)) {
-                            Debug.log("Looking up userLogin from CN: " + userLoginId, module);
+                        if (LoginWorker.checkValidIssuer(delegator, x500Map, clientCerts[i].getSerialNumber())) {
+                            //Debug.log("Looking up userLogin from CN: " + userLoginId, module);
                             
                             // CN should match the userLoginId
                             GenericValue userLogin = delegator.findByPrimaryKey("UserLogin", UtilMisc.toMap("userLoginId", userLoginId));
@@ -577,7 +578,7 @@
         return "success";
     }
 
-    protected static boolean checkValidIssuer(GenericDelegator delegator, Map x500Map) throws GeneralException {
+    protected static boolean checkValidIssuer(GenericDelegator delegator, Map x500Map, BigInteger serialNumber) throws GeneralException {
         List conds = FastList.newInstance();
         conds.add(new EntityConditionList(UtilMisc.toList(new EntityExpr("commonName", EntityOperator.EQUALS, x500Map.get("CN")),
                 new EntityExpr("commonName", EntityOperator.EQUALS, null),
@@ -603,6 +604,10 @@
                 new EntityExpr("country", EntityOperator.EQUALS, null),
                 new EntityExpr("country", EntityOperator.EQUALS, "")), EntityOperator.OR));
 
+        conds.add(new EntityConditionList(UtilMisc.toList(new EntityExpr("serialNumber", EntityOperator.EQUALS, serialNumber.toString(16)),
+                new EntityExpr("serialNumber", EntityOperator.EQUALS, null),
+                new EntityExpr("serialNumber", EntityOperator.EQUALS, "")), EntityOperator.OR));
+
         EntityConditionList condition = new EntityConditionList(conds, EntityOperator.AND);
         Debug.log("Doing issuer lookup: " + condition.toString(), module);
         long count = delegator.findCountByCondition("X509IssuerProvision", condition, null, null);
