]> WPIA git - gigi.git/blobdiff - src/org/cacert/gigi/pages/account/certs/CertificateRequest.java
UPD: minor consistency cleanups
[gigi.git] / src / org / cacert / gigi / pages / account / certs / CertificateRequest.java
index 187c7cb8eea7a7effa18498b2c299548930afc0b..eb547cd3a22c915e94bbfeb86bd2a52eb344cde3 100644 (file)
@@ -23,6 +23,7 @@ import org.cacert.gigi.dbObjects.Certificate;
 import org.cacert.gigi.dbObjects.Certificate.CSRType;
 import org.cacert.gigi.dbObjects.Certificate.SANType;
 import org.cacert.gigi.dbObjects.Certificate.SubjectAlternateName;
+import org.cacert.gigi.dbObjects.CertificateOwner;
 import org.cacert.gigi.dbObjects.CertificateProfile;
 import org.cacert.gigi.dbObjects.CertificateProfile.PropertyTemplate;
 import org.cacert.gigi.dbObjects.Digest;
@@ -105,7 +106,16 @@ public class CertificateRequest {
     private String pDNS, pMail;
 
     public CertificateRequest(User issuer, String csr) throws IOException, GeneralSecurityException, GigiApiException {
+        this(issuer, csr, (CertificateProfile) null);
+    }
+
+    public CertificateRequest(User issuer, String csr, CertificateProfile cp) throws GeneralSecurityException, IOException, IOException {
         u = issuer;
+        if (cp != null) {
+            profile = cp;
+        } else if (u.getAssurancePoints() > 50) {
+            profile = CertificateProfile.getByName("client-a");
+        }
         byte[] data = PEM.decode("(NEW )?CERTIFICATE REQUEST", csr);
         PKCS10 parsed = new PKCS10(data);
         PKCS10Attributes atts = parsed.getAttributes();
@@ -151,18 +161,22 @@ public class CertificateRequest {
                     }
                 } else if (c instanceof ExtendedKeyUsageExtension) {
                     ExtendedKeyUsageExtension ekue = (ExtendedKeyUsageExtension) c;
+                    String appendix = "";
+                    if (u.getAssurancePoints() >= 50) {
+                        appendix = "-a";
+                    }
                     for (String s : ekue.getExtendedKeyUsage()) {
                         if (s.equals(OID_KEY_USAGE_SSL_SERVER.toString())) {
                             // server
-                            profile = CertificateProfile.getByName("server");
+                            profile = CertificateProfile.getByName("server" + appendix);
                         } else if (s.equals(OID_KEY_USAGE_SSL_CLIENT.toString())) {
                             // client
-                            profile = CertificateProfile.getByName("client");
+                            profile = CertificateProfile.getByName("client" + appendix);
                         } else if (s.equals(OID_KEY_USAGE_CODESIGN.toString())) {
                             // code sign
                         } else if (s.equals(OID_KEY_USAGE_EMAIL_PROTECTION.toString())) {
                             // emailProtection
-                            profile = CertificateProfile.getByName("mail");
+                            profile = CertificateProfile.getByName("mail" + appendix);
                         } else if (s.equals(OID_KEY_USAGE_TIMESTAMP.toString())) {
                             // timestamp
                         } else if (s.equals(OID_KEY_USAGE_OCSP.toString())) {
@@ -249,11 +263,11 @@ public class CertificateRequest {
                 continue;
             }
             try {
-                SANType t = Certificate.SANType.valueOf(parts[0].toUpperCase());
+                SANType t = Certificate.SANType.valueOf(parts[0].toUpperCase().trim());
                 if (t == null) {
                     continue;
                 }
-                parsedNames.add(new SubjectAlternateName(t, parts[1]));
+                parsedNames.add(new SubjectAlternateName(t, parts[1].trim()));
             } catch (IllegalArgumentException e) {
                 // invalid enum type
                 continue;
@@ -296,14 +310,29 @@ public class CertificateRequest {
         if (newOrgStr != null) {
             Organisation neworg = Organisation.getById(Integer.parseInt(newOrgStr));
             if (neworg == null || u.getOrganisations().contains(neworg)) {
-                org = neworg;
+                PropertyTemplate orga = profile.getTemplates().get("orga");
+                if (orga != null) {
+                    org = neworg;
+                } else {
+                    org = null;
+                    error.mergeInto(new GigiApiException("No organisations for this certificate profile."));
+                }
             } else {
-                error.mergeInto(new GigiApiException("Selected Organisation is not part of your account."));
+                error.mergeInto(new GigiApiException("Selected organisation is not part of your account."));
             }
         }
+
         this.ou = ou;
 
-        verifySANs(error, profile, parseSANBox(SANsStr));
+        if ( !this.profile.canBeIssuedBy(u)) {
+            this.profile = CertificateProfile.getById(1);
+            error.mergeInto(new GigiApiException("Certificate Profile is invalid."));
+            throw error;
+        }
+
+        CertificateOwner owner = org != null ? org : u;
+
+        verifySANs(error, profile, parseSANBox(SANsStr), owner);
 
         if ( !error.isEmpty()) {
             throw error;
@@ -311,7 +340,7 @@ public class CertificateRequest {
         return true;
     }
 
-    private void verifySANs(GigiApiException error, CertificateProfile p, Set<SubjectAlternateName> sANs2) {
+    private void verifySANs(GigiApiException error, CertificateProfile p, Set<SubjectAlternateName> sANs2, CertificateOwner owner) {
         Set<SubjectAlternateName> filteredSANs = new LinkedHashSet<>();
         PropertyTemplate domainTemp = p.getTemplates().get("domain");
         PropertyTemplate emailTemp = p.getTemplates().get("email");
@@ -319,7 +348,7 @@ public class CertificateRequest {
         pMail = null;
         for (SubjectAlternateName san : sANs2) {
             if (san.getType() == SANType.DNS) {
-                if (domainTemp != null && u.isValidDomain(san.getName())) {
+                if (domainTemp != null && owner.isValidDomain(san.getName())) {
                     if (pDNS != null && !domainTemp.isMultiple()) {
                         // remove
                     } else {
@@ -331,7 +360,7 @@ public class CertificateRequest {
                     }
                 }
             } else if (san.getType() == SANType.EMAIL) {
-                if (emailTemp != null && u.isValidEmail(san.getName())) {
+                if (emailTemp != null && owner.isValidEmail(san.getName())) {
                     if (pMail != null && !emailTemp.isMultiple()) {
                         // remove
                     } else {
@@ -355,19 +384,13 @@ public class CertificateRequest {
     public synchronized Certificate draft() throws GigiApiException {
 
         GigiApiException error = new GigiApiException();
-        if ( !this.profile.canBeIssuedBy(u)) {
-            this.profile = CertificateProfile.getById(1);
-            error.mergeInto(new GigiApiException("Certificate Profile is invalid."));
-            throw error;
-        }
-
-        verifySANs(error, profile, SANs);
 
         HashMap<String, String> subject = new HashMap<>();
         PropertyTemplate domainTemp = profile.getTemplates().get("domain");
         PropertyTemplate emailTemp = profile.getTemplates().get("email");
         PropertyTemplate nameTemp = profile.getTemplates().get("name");
         PropertyTemplate wotUserTemp = profile.getTemplates().get("name=WoTUser");
+        verifySANs(error, profile, SANs, org != null ? org : u);
 
         // Ok, let's determine the CN
         // the CN is
@@ -378,8 +401,13 @@ public class CertificateRequest {
         // primary domain. (domainTemp != null)
 
         String verifiedCN = null;
-
-        verifiedCN = verifyName(error, nameTemp, wotUserTemp, verifiedCN);
+        if (org == null) {
+            verifiedCN = verifyName(error, nameTemp, wotUserTemp, verifiedCN);
+        } else {
+            if ( !name.equals("")) {
+                verifiedCN = name;
+            }
+        }
         if (pDNS == null && domainTemp != null && domainTemp.isRequired()) {
             error.mergeInto(new GigiApiException("Server Certificates require a DNS name."));
         } else if (domainTemp != null && verifiedCN == null) {
@@ -404,33 +432,26 @@ public class CertificateRequest {
             }
         }
 
-        PropertyTemplate orga = profile.getTemplates().get("orga");
-        if (orga != null) {
-            if (orga.isMultiple() || !orga.isRequired()) {
-                error.mergeInto(new GigiApiException("This is an internal error."));
-            } else if (org == null) {
-                error.mergeInto(new GigiApiException("You need to select an organisation for this profile type."));
-            } else {
-                subject.put("O", org.getName());
-                subject.put("C", org.getState());
-                subject.put("ST", org.getProvince());
-                subject.put("L", org.getCity());
-                if (ou != null) {
-                    subject.put("OU", ou);
-                }
-            }
-        } else {
-            if (org != null) {
-                org = null;
-                error.mergeInto(new GigiApiException("You may only include organisations in orga-certs."));
+        if (org != null) {
+            subject.put("O", org.getName());
+            subject.put("C", org.getState());
+            subject.put("ST", org.getProvince());
+            subject.put("L", org.getCity());
+            if (ou != null) {
+                subject.put("OU", ou);
             }
         }
         System.out.println(subject);
         if ( !error.isEmpty()) {
             throw error;
         }
-        return new Certificate(u, subject, selectedDigest.toString(), //
-                this.csr, this.csrType, profile, SANs.toArray(new SubjectAlternateName[SANs.size()]));
+        try {
+            return new Certificate(u, subject, selectedDigest.toString(), //
+                    this.csr, this.csrType, profile, SANs.toArray(new SubjectAlternateName[SANs.size()]));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
     }
 
     private String verifyName(GigiApiException error, PropertyTemplate nameTemp, PropertyTemplate wotUserTemp, String verifiedCN) {
@@ -441,7 +462,7 @@ public class CertificateRequest {
         // null y -> default
         // null null -> null
         // ? y -> real, default
-        // ? null -> real, null
+        // ? null -> real, default, null
         boolean realIsOK = false;
         boolean nullIsOK = false;
         boolean defaultIsOK = false;
@@ -455,12 +476,12 @@ public class CertificateRequest {
             nullIsOK = !defaultIsOK;
         } else if (nameTemp != null && !nameTemp.isRequired() && !nameTemp.isMultiple()) {
             realIsOK = true;
-            defaultIsOK = wotUserTemp != null;
-            nullIsOK = !defaultIsOK;
+            defaultIsOK = true;
+            nullIsOK = wotUserTemp == null;
         } else {
             error.mergeInto(new GigiApiException("Internal configuration error detected."));
         }
-        if (u.isValidName(name)) {
+        if (name != null && u.isValidName(name)) {
             if (realIsOK) {
                 verifiedCN = name;
             } else {
@@ -471,7 +492,7 @@ public class CertificateRequest {
                     name = "";
                 }
             }
-        } else if (name.equals(DEFAULT_CN)) {
+        } else if (name != null && name.equals(DEFAULT_CN)) {
             if (defaultIsOK) {
                 verifiedCN = name;
             } else {
@@ -482,9 +503,9 @@ public class CertificateRequest {
                     name = u.getName().toString();
                 }
             }
-        } else if (name.equals("")) {
+        } else if (name == null || name.equals("")) {
             if (nullIsOK) {
-                verifiedCN = name;
+                verifiedCN = "";
             } else {
                 error.mergeInto(new GigiApiException("A name is required in this certificate."));
                 if (defaultIsOK) {