X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=src%2Forg%2Fcacert%2Fgigi%2Fpages%2Faccount%2Fcerts%2FCertificateRequest.java;h=5edf362e4877ef2c505ca5c6636e60b91b9b0b42;hp=e8a53df03449e6e07fcb6d5e1b51820927220872;hb=5207476641f1bf10637937555a70e5c8bd5979b6;hpb=41a647e1c20b5182928e9d2178693aa943e56146 diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java b/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java index e8a53df0..5edf362e 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java @@ -7,7 +7,6 @@ import java.security.PublicKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPublicKey; -import java.util.Arrays; import java.util.Base64; import java.util.HashMap; import java.util.HashSet; @@ -15,8 +14,6 @@ import java.util.LinkedHashSet; import java.util.Set; import java.util.TreeSet; -import javax.servlet.http.HttpServletRequest; - import org.cacert.gigi.GigiApiException; import org.cacert.gigi.crypto.SPKAC; import org.cacert.gigi.dbObjects.Certificate; @@ -27,12 +24,15 @@ 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; +import org.cacert.gigi.dbObjects.Group; import org.cacert.gigi.dbObjects.Organisation; import org.cacert.gigi.dbObjects.User; -import org.cacert.gigi.output.template.Scope; import org.cacert.gigi.output.template.SprintfCommand; import org.cacert.gigi.util.AuthorizationContext; +import org.cacert.gigi.util.CAA; +import org.cacert.gigi.util.DomainAssessment; import org.cacert.gigi.util.PEM; +import org.cacert.gigi.util.RateLimit; import sun.security.pkcs.PKCS9Attribute; import sun.security.pkcs10.PKCS10; @@ -58,7 +58,7 @@ import sun.security.x509.X500Name; public class CertificateRequest { - public static final String DEFAULT_CN = "CAcert WoT User"; + public static final String DEFAULT_CN = "SomeCA User"; public static final ObjectIdentifier OID_KEY_USAGE_SSL_SERVER = ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 3, 1 @@ -225,6 +225,8 @@ public class CertificateRequest { selectedDigest = Digest.SHA512; } else if (sign.toLowerCase().startsWith("sha384")) { selectedDigest = Digest.SHA384; + } else if (sign.toLowerCase().startsWith("sha256")) { + selectedDigest = Digest.SHA256; } } @@ -298,7 +300,7 @@ public class CertificateRequest { return profile; } - public synchronized boolean update(String nameIn, String hashAlg, String profileStr, String newOrgStr, String ou, String SANsStr, PrintWriter out, HttpServletRequest req) throws GigiApiException { + public synchronized boolean update(String nameIn, String hashAlg, String profileStr, String newOrgStr, String ou, String SANsStr) throws GigiApiException { GigiApiException error = new GigiApiException(); this.name = nameIn; if (hashAlg != null) { @@ -315,7 +317,7 @@ public class CertificateRequest { throw error; } - verifySANs(error, profile, parseSANBox(SANsStr), ctx.getTarget()); + verifySANs(error, profile, parseSANBox(SANsStr), ctx.getTarget(), ctx.getActor()); if ( !error.isEmpty()) { throw error; @@ -323,7 +325,7 @@ public class CertificateRequest { return true; } - private void verifySANs(GigiApiException error, CertificateProfile p, Set sANs2, CertificateOwner owner) { + private void verifySANs(GigiApiException error, CertificateProfile p, Set sANs2, CertificateOwner owner, User user) { Set filteredSANs = new LinkedHashSet<>(); PropertyTemplate domainTemp = p.getTemplates().get("domain"); PropertyTemplate emailTemp = p.getTemplates().get("email"); @@ -332,14 +334,22 @@ public class CertificateRequest { for (SubjectAlternateName san : sANs2) { if (san.getType() == SANType.DNS) { if (domainTemp != null && owner.isValidDomain(san.getName())) { - if (pDNS != null && !domainTemp.isMultiple()) { - // remove - } else { - if (pDNS == null) { - pDNS = san.getName(); + boolean valid; + try { + DomainAssessment.checkCertifiableDomain(san.getName(), user.isInGroup(Group.CODESIGNING), false); + valid = true; + if ( !valid || !CAA.verifyDomainAccess(owner, p, san.getName()) || (pDNS != null && !domainTemp.isMultiple())) { + // remove + } else { + if (pDNS == null) { + pDNS = san.getName(); + } + filteredSANs.add(san); + continue; } - filteredSANs.add(san); - continue; + } catch (GigiApiException e) { + error.mergeInto(e); + valid = false; } } } else if (san.getType() == SANType.EMAIL) { @@ -355,10 +365,8 @@ public class CertificateRequest { } } } - HashMap vars = new HashMap<>(); - vars.put("SAN", san.getType().toString().toLowerCase() + ":" + san.getName()); - error.mergeInto(new GigiApiException(new Scope(new SprintfCommand(// - "The requested Subject alternate name \"{0}\" has been removed.", Arrays.asList("${SAN}")), vars))); + error.mergeInto(new GigiApiException(SprintfCommand.createSimple(// + "The requested subject alternate name (SAN) \"{0}\" has been removed.", san.getType().toString().toLowerCase() + ":" + san.getName()))); } SANs = filteredSANs; } @@ -373,7 +381,7 @@ public class CertificateRequest { PropertyTemplate emailTemp = profile.getTemplates().get("email"); PropertyTemplate nameTemp = profile.getTemplates().get("name"); PropertyTemplate wotUserTemp = profile.getTemplates().get("name=WoTUser"); - verifySANs(error, profile, SANs, ctx.getTarget()); + verifySANs(error, profile, SANs, ctx.getTarget(), ctx.getActor()); // Ok, let's determine the CN // the CN is @@ -418,7 +426,7 @@ public class CertificateRequest { if (ctx.getTarget() instanceof Organisation) { Organisation org = (Organisation) ctx.getTarget(); subject.put("O", org.getName()); - subject.put("C", org.getState()); + subject.put("C", org.getCountry().getCode()); subject.put("ST", org.getProvince()); subject.put("L", org.getCity()); if (ou != null) { @@ -430,7 +438,10 @@ public class CertificateRequest { throw error; } try { - return new Certificate(ctx.getTarget(), ctx.getActor(), subject, selectedDigest.toString(), // + if (RATE_LIMIT.isLimitExceeded(Integer.toString(ctx.getActor().getId()))) { + throw new GigiApiException("Rate Limit Exceeded"); + } + return new Certificate(ctx.getTarget(), ctx.getActor(), subject, selectedDigest, // this.csr, this.csrType, profile, SANs.toArray(new SubjectAlternateName[SANs.size()])); } catch (IOException e) { e.printStackTrace(); @@ -438,6 +449,9 @@ public class CertificateRequest { return null; } + // 100 per 10 minutes + public static final RateLimit RATE_LIMIT = new RateLimit(100, 10 * 60 * 1000); + private String verifyName(GigiApiException error, PropertyTemplate nameTemp, PropertyTemplate wotUserTemp, String verifiedCN) { // real names, // possible configurations: name {y,null,?}, name=WoTUser {y,null} @@ -486,7 +500,7 @@ public class CertificateRequest { if (nullIsOK) { name = ""; } else if (realIsOK) { - name = u.getName().toString(); + name = u.getPreferredName().toString(); } } } else if (name == null || name.equals("")) { @@ -497,7 +511,7 @@ public class CertificateRequest { if (defaultIsOK) { name = DEFAULT_CN; } else if (realIsOK) { - name = u.getName().toString(); + name = u.getPreferredName().toString(); } } } else { @@ -530,12 +544,12 @@ public class CertificateRequest { verifiedCN = name; } else { if (nameTemp.isRequired()) { - error.mergeInto(new GigiApiException("The name entered, does not match the details in your account. You cannot issue certificates with this name. Enter a name that matches the one that has been assured in your account, because a name is required for this certificate type.")); + error.mergeInto(new GigiApiException("The name entered, does not match the details in your account. You cannot issue certificates with this name. Enter a name that matches the one that has been verified in your account, because a name is required for this certificate type.")); } else if (name.equals(DEFAULT_CN)) { verifiedCN = DEFAULT_CN; } else { name = DEFAULT_CN; - error.mergeInto(new GigiApiException("The name entered, does not match the details in your account. You cannot issue certificates with this name. Enter a name that matches the one that has been assured in your account or keep the default name.")); + error.mergeInto(new GigiApiException("The name entered, does not match the details in your account. You cannot issue certificates with this name. Enter a name that matches the one that has been verified in your account or keep the default name.")); } } } else {