changeset 1934:dd483ae1e6ca

2009-06-24 Omair Majid <omajid@redhat.com> * netx/net/sourceforge/jnlp/security/CertWarningPane.java (installComponents): Call SecurityUtil.getCN instead of getCN. (getCN): Removed. * netx/net/sourceforge/jnlp/security/CertsInfoPane.java (buildTree): Call SecurityUtil.getCN instead of getCN. (populateTable): Likewise. (getCN): Removed. * netx/net/sourceforge/jnlp/security/SecurityUtil.java (getCN): Follow RFC 2253 partially and understand escaping. (isHexDigit): New function. * netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java (buildTree): Call SecurityUtil.getCN instead of getCN. (populateTable): Likewise. * netx/net/sourceforge/jnlp/tools/KeyTool.java: (doPrintEntry): Call SecurityUtil.getCN instead of getCN. (getCN): Removed.
author Omair Majid <omajid@redhat.com>
date Wed, 24 Jun 2009 16:26:08 -0400
parents 9528fc8f3555
children 0a41b2f5f086
files ChangeLog netx/net/sourceforge/jnlp/security/CertWarningPane.java netx/net/sourceforge/jnlp/security/CertsInfoPane.java netx/net/sourceforge/jnlp/security/SecurityUtil.java netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java netx/net/sourceforge/jnlp/tools/KeyTool.java
diffstat 6 files changed, 128 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Jun 24 15:10:22 2009 -0400
+++ b/ChangeLog	Wed Jun 24 16:26:08 2009 -0400
@@ -1,3 +1,22 @@
+2009-06-24  Omair Majid  <omajid@redhat.com>
+
+	* netx/net/sourceforge/jnlp/security/CertWarningPane.java
+	(installComponents): Call SecurityUtil.getCN instead of getCN.
+	(getCN): Removed.
+	* netx/net/sourceforge/jnlp/security/CertsInfoPane.java
+	(buildTree): Call SecurityUtil.getCN instead of getCN.
+	(populateTable): Likewise.
+	(getCN): Removed.
+	* netx/net/sourceforge/jnlp/security/SecurityUtil.java
+	(getCN): Follow RFC 2253 partially and understand escaping.
+	(isHexDigit): New function.
+	* netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java
+	(buildTree): Call SecurityUtil.getCN instead of getCN.
+	(populateTable): Likewise.
+	* netx/net/sourceforge/jnlp/tools/KeyTool.java:
+	(doPrintEntry): Call SecurityUtil.getCN instead of getCN.
+	(getCN): Removed. 
+
 2009-06-24  Omair Majid  <omajid@redhat.com>
 
 	* netx/net/sourceforge/jnlp/Launcher.java
--- a/netx/net/sourceforge/jnlp/security/CertWarningPane.java	Wed Jun 24 15:10:22 2009 -0400
+++ b/netx/net/sourceforge/jnlp/security/CertWarningPane.java	Wed Jun 24 16:26:08 2009 -0400
@@ -101,7 +101,7 @@
 		try {
 			if ((certVerifier instanceof HttpsCertVerifier) && 
 			     (c instanceof X509Certificate))
-			   name = getCN(((X509Certificate)c)
+			   name = SecurityUtil.getCN(((X509Certificate)c)
                                         .getSubjectX500Principal().getName());
 			else if (file instanceof PluginBridge)
 				name = file.getTitle();
@@ -112,7 +112,7 @@
 
 		try {
 			if (c instanceof X509Certificate) {
-				publisher = getCN(((X509Certificate)c)
+				publisher = SecurityUtil.getCN(((X509Certificate)c)
 					.getSubjectX500Principal().getName());
 			}
 		} catch (Exception e) {
@@ -236,24 +236,6 @@
         return "<html>"+s+"</html>";
     }
 
-
-    /**
-     * Extracts the CN field from a Certificate principal string.
-     */
-    private String getCN(String principal) {
-        int start = principal.indexOf("CN=");
-        int end = principal.indexOf(",", start);
-
-        if (end == -1) {
-            end = principal.length();
-        }
-
-        if (start >= 0)
-            return principal.substring(start+3, end);
-        else
-            return principal;
-    }
-
 	private class MoreInfoButtonListener implements ActionListener {
 		public void actionPerformed(ActionEvent e) {
 			
--- a/netx/net/sourceforge/jnlp/security/CertsInfoPane.java	Wed Jun 24 15:10:22 2009 -0400
+++ b/netx/net/sourceforge/jnlp/security/CertsInfoPane.java	Wed Jun 24 16:26:08 2009 -0400
@@ -91,9 +91,9 @@
 		X509Certificate firstCert = 
 			((X509Certificate)firstPath.getCertificates().get(0));
 		String subjectString = 
-			getCN(firstCert.getSubjectX500Principal().getName());
+			SecurityUtil.getCN(firstCert.getSubjectX500Principal().getName());
 		String issuerString = 
-			getCN(firstCert.getIssuerX500Principal().getName());
+			SecurityUtil.getCN(firstCert.getIssuerX500Principal().getName());
 
 		DefaultMutableTreeNode top =
 			new DefaultMutableTreeNode(subjectString 
@@ -105,9 +105,9 @@
 			X509Certificate secondCert = 
 				((X509Certificate)firstPath.getCertificates().get(1));
 			subjectString = 
-				getCN(secondCert.getSubjectX500Principal().getName());
+				SecurityUtil.getCN(secondCert.getSubjectX500Principal().getName());
 			issuerString = 
-				getCN(secondCert.getIssuerX500Principal().getName());
+				SecurityUtil.getCN(secondCert.getIssuerX500Principal().getName());
 			top.add(new DefaultMutableTreeNode(subjectString 
 				+ " (" + issuerString + ")"));
 		}
@@ -129,8 +129,8 @@
 
             X509Certificate c = (X509Certificate) certs.get(0).getCertificates().get(i);
             certsData.add(parseCert(c));
-            certNames[i] = getCN(c.getSubjectX500Principal().getName())
-				+ " (" + getCN(c.getIssuerX500Principal().getName()) + ")";
+            certNames[i] = SecurityUtil.getCN(c.getSubjectX500Principal().getName())
+				+ " (" + SecurityUtil.getCN(c.getIssuerX500Principal().getName()) + ")";
         }
 	}
 	
@@ -235,23 +235,6 @@
 	}
 
 	/**
-	 * Extracts the CN field from a Certificate principal string.
-	 */
-	protected String getCN(String principal) {
-        int start = principal.indexOf("CN=");
-        int end = principal.indexOf(",", start);
-
-		if (end == -1) {
-			end = principal.length();
-		}
-
-        if (start >= 0)
-            return principal.substring(start+3, end);
-        else
-            return principal;
-    }
-
-	/**
 	 * Copies the currently selected certificate to the system Clipboard.
 	 */
 	private class CopyToClipboardHandler implements ActionListener {
--- a/netx/net/sourceforge/jnlp/security/SecurityUtil.java	Wed Jun 24 15:10:22 2009 -0400
+++ b/netx/net/sourceforge/jnlp/security/SecurityUtil.java	Wed Jun 24 16:26:08 2009 -0400
@@ -63,20 +63,106 @@
 		return password;
 	}
 	
-	public static String getCN(String principal) {
+    /**
+     * Extracts the CN field from a Certificate principal string. Or, if it
+     * can't find that, return the principal unmodified.
+     * 
+     * This is a simple (and hence 'wrong') version. See
+     * http://www.ietf.org/rfc/rfc2253.txt for all the gory details.
+     */
+    public static String getCN(String principal) {
+
+        /*
+         * FIXME Incomplete
+         * 
+         * This does not implement RFC 2253 completely
+         * 
+         * Issues:
+         * - rfc2253 talks about utf8, java uses utf16.
+         * - theoretically, java should have dealt with all byte encodings
+         *   so we shouldnt even see cases like \FF
+         * - if the above is wrong, then we need to deal with cases like 
+         *   \FF\FF
+         */
+
         int start = principal.indexOf("CN=");
-        int end = principal.indexOf(",", start);
+        if (start == -1) {
+            return principal;
+        }
+
+        StringBuilder commonName = new StringBuilder();
+
+        boolean inQuotes = false;
+        boolean escaped = false;
+
+        /*
+         * bit 0 = high order bit. bit 1 = low order bit
+         */
+        char[] hexBits = null;
+
+        for (int i = start + 3; i < principal.length(); i++) {
+            char ch = principal.charAt(i);
+            switch (ch) {
+            case '"':
+                if (escaped) {
+                    commonName.append(ch);
+                    escaped = false;
+                } else {
+                    inQuotes = !inQuotes;
+                }
+                break;
 
-		if (end == -1) {
-			end = principal.length();
-		}
+            case '\\':
+                if (escaped) {
+                    commonName.append(ch);
+                    escaped = false;
+                } else {
+                    escaped = true;
+                }
+                break;
+
+            case ',':
+                /* fall through */
+            case ';':
+                /* fall through */
+            case '+':
+                if (escaped || inQuotes) {
+                    commonName.append(ch);
+                    if (escaped) {
+                        escaped = false;
+                    }
+                } else {
+                    return commonName.toString();
+                }
+                break;
 
-        if (start >= 0)
-            return principal.substring(start+3, end);
-        else
-            return principal;
+            default:
+                if (escaped && isHexDigit(ch)) {
+                    hexBits = new char[2];
+                    hexBits[0] = ch;
+                } else if (hexBits != null) {
+                    if (!isHexDigit(ch)) {
+                        /* error parsing */
+                        return "";
+                    }
+                    hexBits[1] = ch;
+                    commonName.append((char) Integer.parseInt(new String(hexBits), 16));
+                    hexBits = null;
+                } else {
+                    commonName.append(ch);
+                }
+                escaped = false;
+            }
+        }
+
+        return commonName.toString();
+
     }
-	
+
+    private static boolean isHexDigit(char ch) {
+        return ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'));
+    }
+
 	/**
 	 * Checks the user's home directory to see if the trusted.certs file exists.
 	 * If it does not exist, it tries to create an empty keystore.
--- a/netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java	Wed Jun 24 15:10:22 2009 -0400
+++ b/netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java	Wed Jun 24 16:26:08 2009 -0400
@@ -55,9 +55,9 @@
 	protected void buildTree() {
 		X509Certificate cert = ((SecurityWarningDialog)optionPane).getCert();
 		String subjectString = 
-			getCN(cert.getSubjectX500Principal().getName());
+			SecurityUtil.getCN(cert.getSubjectX500Principal().getName());
 		String issuerString = 
-			getCN(cert.getIssuerX500Principal().getName());
+			SecurityUtil.getCN(cert.getIssuerX500Principal().getName());
 
 		DefaultMutableTreeNode top = new DefaultMutableTreeNode(subjectString 
 				+ " (" + issuerString + ")");
@@ -72,7 +72,7 @@
 		certNames = new String[1];
 		certsData = new ArrayList<String[][]>();
 		certsData.add(parseCert(c));
-		certNames[0] = getCN(c.getSubjectX500Principal().getName())
-		+ " (" + getCN(c.getIssuerX500Principal().getName()) + ")";
+		certNames[0] = SecurityUtil.getCN(c.getSubjectX500Principal().getName())
+		+ " (" + SecurityUtil.getCN(c.getIssuerX500Principal().getName()) + ")";
 	}
 }
--- a/netx/net/sourceforge/jnlp/tools/KeyTool.java	Wed Jun 24 15:10:22 2009 -0400
+++ b/netx/net/sourceforge/jnlp/tools/KeyTool.java	Wed Jun 24 16:26:08 2009 -0400
@@ -176,7 +176,7 @@
 
 			out.println("Alias: " + alias);
 			out.println("Date Created: " + usercerts.getCreationDate(alias));
-			out.println("Subject: " + getCN(((X509Certificate)usercerts
+			out.println("Subject: " + SecurityUtil.getCN(((X509Certificate)usercerts
 				.getCertificate(alias)).getSubjectX500Principal().getName()));
 			out.println("Certificate fingerprint (MD5): "
 					+ getCertFingerPrint("MD5", cert));
@@ -184,23 +184,6 @@
 		}
 	}
 
-	/**
-	 * Extracts the CN field from a Certificate principal string.
-	 */
-	private String getCN(String principal) {
-		int start = principal.indexOf("CN=");
-		int end = principal.indexOf(",", start);
-
-		if (end == -1) {
-			end = principal.length();
-		}
-
-		if (start >= 0)
-			return principal.substring(start+3, end);
-		else
-			return principal;
-    }
-
     /**
      * Gets the requested finger print of the certificate.
      */