From dc10b875c132eb7840a6b9827ec93916076d34f7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Mon, 2 Nov 2015 02:40:08 +0100 Subject: [PATCH] upd: split certificate issuance as organisation into seperate ... authorization context --- src/org/cacert/gigi/Gigi.java | 15 +- src/org/cacert/gigi/api/GigiAPI.java | 7 +- .../cacert/gigi/dbObjects/Certificate.java | 24 ++- .../gigi/dbObjects/CertificateProfile.java | 17 +- src/org/cacert/gigi/pages/LoginPage.java | 13 +- .../cacert/gigi/pages/account/MyDetails.java | 16 +- .../cacert/gigi/pages/account/MyDetails.templ | 5 +- .../pages/account/MyOrganisationsForm.java | 91 ++++++++ .../pages/account/MyOrganisationsForm.templ | 10 + .../account/certs/CertificateIssueForm.java | 43 ++-- .../account/certs/CertificateIssueForm.templ | 13 -- .../certs/CertificateModificationForm.java | 6 +- .../account/certs/CertificateRequest.java | 198 +++++++++--------- .../pages/account/certs/Certificates.java | 4 +- .../account/domain/DomainManagementForm.java | 6 +- .../pages/account/domain/DomainOverview.java | 10 +- .../pages/account/domain/DomainOverview.templ | 4 + .../gigi/pages/account/mail/MailOverview.java | 1 - .../gigi/pages/orga/AffiliationForm.java | 2 + .../gigi/util/AuthorizationContext.java | 29 +++ tests/org/cacert/gigi/TestCertificate.java | 14 +- .../cacert/gigi/TestCrossDomainAccess.java | 4 +- .../cacert/gigi/TestSeparateSessionScope.java | 14 +- tests/org/cacert/gigi/api/IssueCert.java | 4 +- .../pages/account/TestCertificateRequest.java | 14 +- tests/org/cacert/gigi/ping/TestSSL.java | 5 +- .../org/cacert/gigi/DevelLauncher.java | 3 +- .../org/cacert/gigi/pages/Manager.java | 5 +- .../org/cacert/gigi/util/SimpleSigner.java | 15 ++ 29 files changed, 381 insertions(+), 211 deletions(-) create mode 100644 src/org/cacert/gigi/pages/account/MyOrganisationsForm.java create mode 100644 src/org/cacert/gigi/pages/account/MyOrganisationsForm.templ create mode 100644 src/org/cacert/gigi/util/AuthorizationContext.java diff --git a/src/org/cacert/gigi/Gigi.java b/src/org/cacert/gigi/Gigi.java index 99b136b8..63ce7fe8 100644 --- a/src/org/cacert/gigi/Gigi.java +++ b/src/org/cacert/gigi/Gigi.java @@ -22,8 +22,10 @@ import javax.servlet.http.HttpSession; import org.cacert.gigi.database.DatabaseConnection; import org.cacert.gigi.dbObjects.CACertificate; +import org.cacert.gigi.dbObjects.CertificateOwner; import org.cacert.gigi.dbObjects.CertificateProfile; import org.cacert.gigi.dbObjects.DomainPingConfiguration; +import org.cacert.gigi.dbObjects.Organisation; import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.Menu; @@ -61,6 +63,7 @@ import org.cacert.gigi.pages.wot.AssurePage; import org.cacert.gigi.pages.wot.MyPoints; import org.cacert.gigi.pages.wot.RequestTTPPage; import org.cacert.gigi.ping.PingerDaemon; +import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.ServerConstants; public class Gigi extends HttpServlet { @@ -129,8 +132,8 @@ public class Gigi extends HttpServlet { putPage(TTPAdminPage.PATH + "/*", new TTPAdminPage(), "Admin"); putPage(CreateOrgPage.DEFAULT_PATH, new CreateOrgPage(), "Organisation Admin"); putPage(ViewOrgPage.DEFAULT_PATH + "/*", new ViewOrgPage(), "Organisation Admin"); - putPage(FindDomainPage.PATH, new FindDomainPage("Find Domain"), "System Admin"); putPage(FindUserPage.PATH, new FindUserPage("Find User"), "System Admin"); + putPage(FindDomainPage.PATH, new FindDomainPage("Find Domain"), "System Admin"); putPage(SupportUserDetailsPage.PATH + "*", new SupportUserDetailsPage("Support: User Details"), null); if (testing) { try { @@ -187,7 +190,7 @@ public class Gigi extends HttpServlet { public static final String CERT_ISSUER = "org.cacert.gigi.issuer"; - public static final String USER = "user"; + public static final String AUTH_CONTEXT = "auth"; public static final String LOGIN_METHOD = "org.cacert.gigi.loginMethod"; @@ -322,6 +325,7 @@ public class Gigi extends HttpServlet { resp.sendRedirect("https://" + ServerConstants.getWwwHostNamePortSecure() + req.getPathInfo()); return; } + AuthorizationContext currentAuthContext = LoginPage.getAuthorizationContext(req); User currentPageUser = LoginPage.getUser(req); if ( !p.isPermitted(currentPageUser)) { if (hs.getAttribute("loggedin") == null) { @@ -372,7 +376,12 @@ public class Gigi extends HttpServlet { vars.put("year", Calendar.getInstance().get(Calendar.YEAR)); vars.put("content", content); if (currentPageUser != null) { - vars.put("loggedInAs", currentPageUser.getName().toString()); + CertificateOwner target = currentAuthContext.getTarget(); + if (target != currentPageUser) { + vars.put("loggedInAs", ((Organisation) target).getName() + " (" + currentPageUser.getName().toString() + ")"); + } else { + vars.put("loggedInAs", currentPageUser.getName().toString()); + } vars.put("loginMethod", lang.getTranslation((String) req.getSession().getAttribute(LOGIN_METHOD))); } resp.setContentType("text/html; charset=utf-8"); diff --git a/src/org/cacert/gigi/api/GigiAPI.java b/src/org/cacert/gigi/api/GigiAPI.java index 3af4714c..a5acbe56 100644 --- a/src/org/cacert/gigi/api/GigiAPI.java +++ b/src/org/cacert/gigi/api/GigiAPI.java @@ -13,11 +13,12 @@ import javax.servlet.http.HttpServletResponse; import org.cacert.gigi.GigiApiException; import org.cacert.gigi.dbObjects.Certificate; -import org.cacert.gigi.dbObjects.Job; import org.cacert.gigi.dbObjects.Certificate.CertificateStatus; +import org.cacert.gigi.dbObjects.Job; import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.account.certs.CertificateRequest; +import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.PEM; public class GigiAPI extends HttpServlet { @@ -66,9 +67,9 @@ public class GigiAPI extends HttpServlet { return; } try { - CertificateRequest cr = new CertificateRequest(u, csr); + CertificateRequest cr = new CertificateRequest(new AuthorizationContext(u, u), csr); Certificate result = cr.draft(); - Job job = result.issue(null, "2y"); + Job job = result.issue(null, "2y", u); job.waitFor(60000); if (result.getStatus() != CertificateStatus.ISSUED) { resp.sendError(510, "Error, issuing timed out"); diff --git a/src/org/cacert/gigi/dbObjects/Certificate.java b/src/org/cacert/gigi/dbObjects/Certificate.java index 4300ac9a..7318ad80 100644 --- a/src/org/cacert/gigi/dbObjects/Certificate.java +++ b/src/org/cacert/gigi/dbObjects/Certificate.java @@ -109,7 +109,7 @@ public class Certificate implements IdCachable { private int id; - private User owner; + private CertificateOwner owner; private String serial; @@ -133,8 +133,8 @@ public class Certificate implements IdCachable { private CACertificate ca; - public Certificate(User owner, HashMap dn, String md, String csr, CSRType csrType, CertificateProfile profile, SubjectAlternateName... sans) throws GigiApiException, IOException { - if ( !profile.canBeIssuedBy(owner)) { + public Certificate(CertificateOwner owner, User actor, HashMap dn, String md, String csr, CSRType csrType, CertificateProfile profile, SubjectAlternateName... sans) throws GigiApiException, IOException { + if ( !profile.canBeIssuedBy(owner, actor)) { throw new GigiApiException("You are not allowed to issue these certificates."); } this.owner = owner; @@ -189,16 +189,12 @@ public class Certificate implements IdCachable { } private Certificate(GigiResultSet rs) { - // - if ( !rs.next()) { - throw new IllegalArgumentException("Invalid mid " + serial); - } this.id = rs.getInt("id"); dnString = rs.getString("subject"); md = rs.getString("md"); csrName = rs.getString("csr_name"); crtName = rs.getString("crt_name"); - owner = User.getById(rs.getInt("memid")); + owner = CertificateOwner.getById(rs.getInt("memid")); profile = CertificateProfile.getById(rs.getInt("profile")); this.serial = rs.getString("serial"); @@ -278,11 +274,11 @@ public class Certificate implements IdCachable { * @throws GigiApiException * if the period is bogus */ - public Job issue(Date start, String period) throws IOException, GigiApiException { + public Job issue(Date start, String period, User actor) throws IOException, GigiApiException { if (getStatus() != CertificateStatus.DRAFT) { throw new IllegalStateException(); } - Notary.writeUserAgreement(owner, "CCA", "issue certificate", "", true, 0); + Notary.writeUserAgreement(actor, "CCA", "issue certificate", "", true, 0); return Job.sign(this, start, period); @@ -345,7 +341,7 @@ public class Certificate implements IdCachable { return md; } - public User getOwner() { + public CertificateOwner getOwner() { return owner; } @@ -366,6 +362,9 @@ public class Certificate implements IdCachable { GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT certs.id, " + concat + " as `subject`, `md`, `csr_name`, `crt_name`,`memid`, `profile`, `certs`.`serial` FROM `certs` LEFT JOIN `certAvas` ON `certAvas`.`certId`=`certs`.`id` WHERE `serial`=? GROUP BY `certs`.`id`"); ps.setString(1, serial); GigiResultSet rs = ps.executeQuery(); + if ( !rs.next()) { + return null; + } int id = rs.getInt(1); Certificate c1 = cache.get(id); if (c1 != null) { @@ -393,6 +392,9 @@ public class Certificate implements IdCachable { GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT certs.id, " + concat + " as subject, md, csr_name, crt_name,memid, profile, certs.serial FROM `certs` LEFT JOIN `certAvas` ON `certAvas`.`certId`=certs.id WHERE certs.id=? GROUP BY certs.id"); ps.setInt(1, id); GigiResultSet rs = ps.executeQuery(); + if ( !rs.next()) { + return null; + } Certificate c = new Certificate(rs); cache.put(c); diff --git a/src/org/cacert/gigi/dbObjects/CertificateProfile.java b/src/org/cacert/gigi/dbObjects/CertificateProfile.java index 3a040903..0e6f29ba 100644 --- a/src/org/cacert/gigi/dbObjects/CertificateProfile.java +++ b/src/org/cacert/gigi/dbObjects/CertificateProfile.java @@ -237,18 +237,27 @@ public class CertificateProfile implements IdCachable { return byId.values().toArray(new CertificateProfile[byId.size()]); } - public boolean canBeIssuedBy(User u) { + public boolean canBeIssuedBy(CertificateOwner owner, User actor) { + if (pt.containsKey("orga")) { + if ( !(owner instanceof Organisation)) { + return false; + } + } else { + if (owner instanceof Organisation) { + return false; + } + } for (String s : req) { if (s.equals("points>=50")) { - if (u.getAssurancePoints() < 50) { + if (actor.getAssurancePoints() < 50) { return false; } } else if (s.equals("points>=100")) { - if (u.getAssurancePoints() < 100) { + if (actor.getAssurancePoints() < 100) { return false; } } else if (s.equals("codesign")) { - if (u.isInGroup(Group.CODESIGNING)) { + if (actor.isInGroup(Group.CODESIGNING)) { return false; } } else { diff --git a/src/org/cacert/gigi/pages/LoginPage.java b/src/org/cacert/gigi/pages/LoginPage.java index 06006cf2..d25eacfb 100644 --- a/src/org/cacert/gigi/pages/LoginPage.java +++ b/src/org/cacert/gigi/pages/LoginPage.java @@ -20,6 +20,7 @@ import org.cacert.gigi.dbObjects.Group; import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.template.Form; +import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.PasswordHash; public class LoginPage extends Page { @@ -114,7 +115,15 @@ public class LoginPage extends Page { } public static User getUser(HttpServletRequest req) { - return (User) req.getSession().getAttribute(USER); + AuthorizationContext ac = getAuthorizationContext(req); + if (ac == null) { + return null; + } + return ac.getActor(); + } + + public static AuthorizationContext getAuthorizationContext(HttpServletRequest req) { + return ((AuthorizationContext) req.getSession().getAttribute(AUTH_CONTEXT)); } private void tryAuthWithCertificate(HttpServletRequest req, X509Certificate x509Certificate) { @@ -169,7 +178,7 @@ public class LoginPage extends Page { HttpSession hs = req.getSession(); hs.setAttribute(LOGGEDIN, true); hs.setAttribute(Language.SESSION_ATTRIB_NAME, user.getPreferredLocale()); - hs.setAttribute(USER, user); + hs.setAttribute(AUTH_CONTEXT, new AuthorizationContext(user, user)); } @Override diff --git a/src/org/cacert/gigi/pages/account/MyDetails.java b/src/org/cacert/gigi/pages/account/MyDetails.java index 9de78a2e..a6118c67 100644 --- a/src/org/cacert/gigi/pages/account/MyDetails.java +++ b/src/org/cacert/gigi/pages/account/MyDetails.java @@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.cacert.gigi.output.template.Form; +import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.Page; public class MyDetails extends Page { @@ -26,18 +27,27 @@ public class MyDetails extends Page { MyListingForm listingForm = new MyListingForm(req, getUser(req)); map.put("detailsForm", form); map.put("contactMeForm", listingForm); + if (LoginPage.getUser(req).getOrganisations().size() != 0) { + map.put("orgaForm", new MyOrganisationsForm(req)); + } getDefaultTemplate().output(out, getLanguage(req), map); } @Override - public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { - if(req.getParameter("processDetails") != null) { + public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException { + if (req.getParameter("orgaForm") != null) { + Form.getForm(req, MyOrganisationsForm.class).submit(resp.getWriter(), req); + } else if (req.getParameter("processDetails") != null) { MyDetailsForm form = Form.getForm(req, MyDetailsForm.class); form.submit(resp.getWriter(), req); } else if (req.getParameter("processContact") != null) { MyListingForm form = Form.getForm(req, MyListingForm.class); form.submit(resp.getWriter(), req); + } else { + return false; } - super.doPost(req, resp); + resp.sendRedirect(PATH); + return true; } + } diff --git a/src/org/cacert/gigi/pages/account/MyDetails.templ b/src/org/cacert/gigi/pages/account/MyDetails.templ index eb86e511..a4940ceb 100644 --- a/src/org/cacert/gigi/pages/account/MyDetails.templ +++ b/src/org/cacert/gigi/pages/account/MyDetails.templ @@ -1,3 +1,6 @@

- \ No newline at end of file + + + + diff --git a/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java b/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java new file mode 100644 index 00000000..ead00a46 --- /dev/null +++ b/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java @@ -0,0 +1,91 @@ +package org.cacert.gigi.pages.account; + +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.cacert.gigi.Gigi; +import org.cacert.gigi.dbObjects.Organisation; +import org.cacert.gigi.localisation.Language; +import org.cacert.gigi.output.template.Form; +import org.cacert.gigi.output.template.IterableDataset; +import org.cacert.gigi.output.template.Template; +import org.cacert.gigi.pages.LoginPage; +import org.cacert.gigi.util.AuthorizationContext; + +public class MyOrganisationsForm extends Form { + + private AuthorizationContext target; + + public MyOrganisationsForm(HttpServletRequest hsr) { + super(hsr); + target = LoginPage.getAuthorizationContext(hsr); + } + + private static Template template; + + static { + template = new Template(MyListingForm.class.getResource("MyOrganisationsForm.templ")); + } + + @Override + public boolean submit(PrintWriter out, HttpServletRequest req) { + if (req.getParameter("org-leave") != null) { + req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(target.getActor(), target.getActor())); + return true; + } + Enumeration i = req.getParameterNames(); + int orgId = -1; + while (i.hasMoreElements()) { + String s = i.nextElement(); + if (s.startsWith("org:")) { + int id = Integer.parseInt(s.substring(4)); + if (orgId == -1) { + orgId = id; + } else { + out.println(LoginPage.getLanguage(req).getTranslation("Error: invalid parameter.")); + return false; + } + } + } + for (Organisation org : target.getActor().getOrganisations()) { + if (org.getId() == orgId) { + + req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(org, target.getActor())); + return true; + } + } + System.out.println("Switch fialed"); + return false; + } + + @Override + protected void outputContent(PrintWriter out, Language l, Map vars) { + final List o = target.getActor().getOrganisations(); + if (target.getTarget() != target.getActor()) { + vars.put("personal", target.getTarget() != target.getActor()); + } + vars.put("orgas", new IterableDataset() { + + Iterator it = o.iterator(); + + @Override + public boolean next(Language l, Map vars) { + if ( !it.hasNext()) { + return false; + } + Organisation o = it.next(); + vars.put("orgName", o.getName()); + vars.put("orgID", o.getId()); + return true; + } + }); + template.output(out, l, vars); + + } + +} diff --git a/src/org/cacert/gigi/pages/account/MyOrganisationsForm.templ b/src/org/cacert/gigi/pages/account/MyOrganisationsForm.templ new file mode 100644 index 00000000..babc09db --- /dev/null +++ b/src/org/cacert/gigi/pages/account/MyOrganisationsForm.templ @@ -0,0 +1,10 @@ + +

+ + + + +
+ + + diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java index 5ac13fda..5712190b 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java @@ -4,8 +4,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.security.GeneralSecurityException; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -15,14 +13,15 @@ import org.cacert.gigi.dbObjects.Certificate; import org.cacert.gigi.dbObjects.Certificate.SubjectAlternateName; import org.cacert.gigi.dbObjects.CertificateProfile; import org.cacert.gigi.dbObjects.Organisation; -import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.CertificateValiditySelector; import org.cacert.gigi.output.HashAlgorithms; import org.cacert.gigi.output.template.Form; import org.cacert.gigi.output.template.IterableDataset; import org.cacert.gigi.output.template.Template; +import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.Page; +import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.RandomToken; /** @@ -35,7 +34,7 @@ public class CertificateIssueForm extends Form { private final static Template tIni = new Template(CertificateAdd.class.getResource("RequestCertificate.templ")); - private User u; + private AuthorizationContext c; private String spkacChallenge; @@ -43,7 +42,7 @@ public class CertificateIssueForm extends Form { public CertificateIssueForm(HttpServletRequest hsr) { super(hsr); - u = Page.getUser(hsr); + c = LoginPage.getAuthorizationContext(hsr); spkacChallenge = RandomToken.generateToken(16); } @@ -64,10 +63,10 @@ public class CertificateIssueForm extends Form { try { try { if (csr != null) { - cr = new CertificateRequest(u, csr); + cr = new CertificateRequest(c, csr); cr.checkKeyStrength(out); } else if (spkac != null) { - cr = new CertificateRequest(u, spkac, spkacChallenge); + cr = new CertificateRequest(c, spkac, spkacChallenge); cr.checkKeyStrength(out); } else if (cr != null) { login = "1".equals(req.getParameter("login")); @@ -93,7 +92,7 @@ public class CertificateIssueForm extends Form { error.format(out, Page.getLanguage(req)); return false; } - result.issue(issueDate.getFrom(), issueDate.getTo()).waitFor(60000); + result.issue(issueDate.getFrom(), issueDate.getTo(), c.getActor()).waitFor(60000); this.result = result; return true; } else { @@ -144,7 +143,10 @@ public class CertificateIssueForm extends Form { } vars2.put("CN", cr.getName()); - vars2.put("department", cr.getOu()); + if (c.getTarget() instanceof Organisation) { + vars2.put("orga", "true"); + vars2.put("department", cr.getOu()); + } vars2.put("validity", issueDate); vars2.put("emails", content.toString()); vars2.put("hashs", new HashAlgorithms(cr.getSelectedDigest())); @@ -160,7 +162,7 @@ public class CertificateIssueForm extends Form { if (cp == null) { return false; } - } while ( !cp.canBeIssuedBy(u)); + } while ( !cp.canBeIssuedBy(c.getTarget(), c.getActor())); if (cp.getId() == cr.getProfile().getId()) { vars.put("selected", " selected"); @@ -172,27 +174,6 @@ public class CertificateIssueForm extends Form { return true; } }); - final List orgs = u.getOrganisations(); - vars2.put("orga", orgs.size() == 0 ? null : new IterableDataset() { - - Iterator iter = orgs.iterator(); - - @Override - public boolean next(Language l, Map vars) { - if ( !iter.hasNext()) { - return false; - } - Organisation orga = iter.next(); - vars.put("key", orga.getId()); - vars.put("name", orga.getName()); - if (orga == cr.getOrg()) { - vars.put("selected", " selected"); - } else { - vars.put("selected", ""); - } - return true; - } - }); t.output(out, l, vars2); } diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ index dda8ce4f..7b00f194 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ +++ b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ @@ -24,19 +24,6 @@ - - - - - - - - diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java index 8449c20f..6553a773 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java @@ -7,8 +7,8 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.cacert.gigi.dbObjects.Certificate; +import org.cacert.gigi.dbObjects.CertificateOwner; import org.cacert.gigi.dbObjects.Job; -import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.CertificateIterable; import org.cacert.gigi.output.template.Form; @@ -17,14 +17,14 @@ import org.cacert.gigi.pages.LoginPage; public class CertificateModificationForm extends Form { - User target; + CertificateOwner target; final boolean withRevoked; public CertificateModificationForm(HttpServletRequest hsr, boolean withRevoked) { super(hsr); this.withRevoked = withRevoked; - target = LoginPage.getUser(hsr); + target = LoginPage.getAuthorizationContext(hsr).getTarget(); } private static final Template certTable = new Template(CertificateIterable.class.getResource("CertificateTable.templ")); diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java b/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java index eb547cd3..dae44fa0 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateRequest.java @@ -31,6 +31,7 @@ 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.PEM; import sun.security.pkcs.PKCS9Attribute; @@ -99,21 +100,19 @@ public class CertificateRequest { private String ou = ""; - private Organisation org = null; - - private User u; + private AuthorizationContext ctx; private String pDNS, pMail; - public CertificateRequest(User issuer, String csr) throws IOException, GeneralSecurityException, GigiApiException { - this(issuer, csr, (CertificateProfile) null); + public CertificateRequest(AuthorizationContext c, String csr) throws IOException, GeneralSecurityException, GigiApiException { + this(c, csr, (CertificateProfile) null); } - public CertificateRequest(User issuer, String csr, CertificateProfile cp) throws GeneralSecurityException, IOException, IOException { - u = issuer; + public CertificateRequest(AuthorizationContext ctx, String csr, CertificateProfile cp) throws GeneralSecurityException, IOException, IOException { + this.ctx = ctx; if (cp != null) { profile = cp; - } else if (u.getAssurancePoints() > 50) { + } else if (ctx.getActor().getAssurancePoints() > 50) { profile = CertificateProfile.getByName("client-a"); } byte[] data = PEM.decode("(NEW )?CERTIFICATE REQUEST", csr); @@ -162,7 +161,7 @@ public class CertificateRequest { } else if (c instanceof ExtendedKeyUsageExtension) { ExtendedKeyUsageExtension ekue = (ExtendedKeyUsageExtension) c; String appendix = ""; - if (u.getAssurancePoints() >= 50) { + if (ctx.getActor().getAssurancePoints() >= 50) { appendix = "-a"; } for (String s : ekue.getExtendedKeyUsage()) { @@ -198,8 +197,8 @@ public class CertificateRequest { this.csrType = CSRType.CSR; } - public CertificateRequest(User issuer, String spkac, String spkacChallenge) throws IOException, GigiApiException, GeneralSecurityException { - u = issuer; + public CertificateRequest(AuthorizationContext ctx, String spkac, String spkacChallenge) throws IOException, GigiApiException, GeneralSecurityException { + this.ctx = ctx; String cleanedSPKAC = spkac.replaceAll("[\r\n]", ""); byte[] data = Base64.getDecoder().decode(cleanedSPKAC); SPKAC parsed = new SPKAC(data); @@ -284,12 +283,11 @@ public class CertificateRequest { return name; } - public Organisation getOrg() { - return org; - } - public String getOu() { - return ou; + if (ctx.getTarget() instanceof Organisation) { + return ou; + } + throw new IllegalStateException(); } public Digest getSelectedDigest() { @@ -307,32 +305,17 @@ public class CertificateRequest { selectedDigest = Digest.valueOf(hashAlg); } this.profile = CertificateProfile.getByName(profileStr); - if (newOrgStr != null) { - Organisation neworg = Organisation.getById(Integer.parseInt(newOrgStr)); - if (neworg == null || u.getOrganisations().contains(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.")); - } + if (ctx.getTarget() instanceof Organisation) { + this.ou = ou; } - this.ou = ou; - - if ( !this.profile.canBeIssuedBy(u)) { + if ( !this.profile.canBeIssuedBy(ctx.getTarget(), ctx.getActor())) { 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); + verifySANs(error, profile, parseSANBox(SANsStr), ctx.getTarget()); if ( !error.isEmpty()) { throw error; @@ -390,7 +373,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, org != null ? org : u); + verifySANs(error, profile, SANs, ctx.getTarget()); // Ok, let's determine the CN // the CN is @@ -401,12 +384,12 @@ public class CertificateRequest { // primary domain. (domainTemp != null) String verifiedCN = null; - if (org == null) { - verifiedCN = verifyName(error, nameTemp, wotUserTemp, verifiedCN); - } else { + if (ctx.getTarget() instanceof Organisation) { if ( !name.equals("")) { verifiedCN = name; } + } else { + verifiedCN = verifyName(error, nameTemp, wotUserTemp, verifiedCN); } if (pDNS == null && domainTemp != null && domainTemp.isRequired()) { error.mergeInto(new GigiApiException("Server Certificates require a DNS name.")); @@ -432,7 +415,8 @@ public class CertificateRequest { } } - if (org != null) { + if (ctx.getTarget() instanceof Organisation) { + Organisation org = (Organisation) ctx.getTarget(); subject.put("O", org.getName()); subject.put("C", org.getState()); subject.put("ST", org.getProvince()); @@ -446,7 +430,7 @@ public class CertificateRequest { throw error; } try { - return new Certificate(u, subject, selectedDigest.toString(), // + return new Certificate(ctx.getTarget(), ctx.getActor(), subject, selectedDigest.toString(), // this.csr, this.csrType, profile, SANs.toArray(new SubjectAlternateName[SANs.size()])); } catch (IOException e) { e.printStackTrace(); @@ -481,84 +465,96 @@ public class CertificateRequest { } else { error.mergeInto(new GigiApiException("Internal configuration error detected.")); } - if (name != null && u.isValidName(name)) { - if (realIsOK) { - verifiedCN = name; - } else { - error.mergeInto(new GigiApiException("Your real name is not allowed in this certificate.")); + if (ctx.getTarget() instanceof User) { + User u = (User) ctx.getTarget(); + if (name != null && u.isValidName(name)) { + if (realIsOK) { + verifiedCN = name; + } else { + error.mergeInto(new GigiApiException("Your real name is not allowed in this certificate.")); + if (defaultIsOK) { + name = DEFAULT_CN; + } else if (nullIsOK) { + name = ""; + } + } + } else if (name != null && name.equals(DEFAULT_CN)) { if (defaultIsOK) { - name = DEFAULT_CN; - } else if (nullIsOK) { - name = ""; + verifiedCN = name; + } else { + error.mergeInto(new GigiApiException("The default name is not allowed in this certificate.")); + if (nullIsOK) { + name = ""; + } else if (realIsOK) { + name = u.getName().toString(); + } } - } - } else if (name != null && name.equals(DEFAULT_CN)) { - if (defaultIsOK) { - verifiedCN = name; - } else { - error.mergeInto(new GigiApiException("The default name is not allowed in this certificate.")); + } else if (name == null || name.equals("")) { if (nullIsOK) { - name = ""; - } else if (realIsOK) { - name = u.getName().toString(); + verifiedCN = ""; + } else { + error.mergeInto(new GigiApiException("A name is required in this certificate.")); + if (defaultIsOK) { + name = DEFAULT_CN; + } else if (realIsOK) { + name = u.getName().toString(); + } } - } - } else if (name == null || name.equals("")) { - if (nullIsOK) { - verifiedCN = ""; } else { - error.mergeInto(new GigiApiException("A name is required in this certificate.")); - if (defaultIsOK) { + error.mergeInto(new GigiApiException("The name you entered was invalid.")); + + } + if (wotUserTemp != null) { + if ( !wotUserTemp.isRequired() || wotUserTemp.isMultiple()) { + error.mergeInto(new GigiApiException("Internal configuration error detected.")); + } + if ( !name.equals(DEFAULT_CN)) { name = DEFAULT_CN; - } else if (realIsOK) { - name = u.getName().toString(); + error.mergeInto(new GigiApiException("You may not change the name for this certificate type.")); + } else { + verifiedCN = DEFAULT_CN; } - } - } else { - error.mergeInto(new GigiApiException("The name you entered was invalid.")); - } - if (wotUserTemp != null) { - if ( !wotUserTemp.isRequired() || wotUserTemp.isMultiple()) { - error.mergeInto(new GigiApiException("Internal configuration error detected.")); - } - if ( !name.equals(DEFAULT_CN)) { - name = DEFAULT_CN; - error.mergeInto(new GigiApiException("You may not change the name for this certificate type.")); } else { - verifiedCN = DEFAULT_CN; - } + if (nameTemp != null) { + if (name.equals("")) { + if (nameTemp.isRequired()) { + // nothing, but required + name = DEFAULT_CN; + error.mergeInto(new GigiApiException("No name entered, but one was required.")); + } else { + // nothing and not required - } else { - if (nameTemp != null) { - if (name.equals("")) { - if (nameTemp.isRequired()) { - // nothing, but required - name = DEFAULT_CN; - error.mergeInto(new GigiApiException("No name entered, but one was required.")); + } + } else if (u.isValidName(name)) { + verifiedCN = name; } else { - // nothing and not required - + 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.")); + } 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.")); + } } - } else if (u.isValidName(name)) { - 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.")); - } 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.")); + if ( !name.equals("")) { + name = ""; + error.mergeInto(new GigiApiException("No real name is included in this certificate. The real name, you entered will be ignored.")); } } + } + } else { + if (realIsOK) { + verifiedCN = name; } else { - if ( !name.equals("")) { - name = ""; - error.mergeInto(new GigiApiException("No real name is included in this certificate. The real name, you entered will be ignored.")); - } + verifiedCN = ""; + name = ""; + error.mergeInto(new GigiApiException("No real name is included in this certificate. The real name, you entered will be ignored.")); } } + return verifiedCN; } } diff --git a/src/org/cacert/gigi/pages/account/certs/Certificates.java b/src/org/cacert/gigi/pages/account/certs/Certificates.java index 799927fd..766d21ea 100644 --- a/src/org/cacert/gigi/pages/account/certs/Certificates.java +++ b/src/org/cacert/gigi/pages/account/certs/Certificates.java @@ -85,7 +85,7 @@ public class Certificates extends Page implements HandlesMixedRequest { String serial = pi; try { Certificate c = Certificate.getBySerial(serial); - if (c == null || getUser(req).getId() != c.getOwner().getId()) { + if (c == null || LoginPage.getAuthorizationContext(req).getTarget().getId() != c.getOwner().getId()) { resp.sendError(404); return true; } @@ -142,7 +142,7 @@ public class Certificates extends Page implements HandlesMixedRequest { String serial = pi; Certificate c = Certificate.getBySerial(serial); - if (c == null || LoginPage.getUser(req).getId() != c.getOwner().getId()) { + if (c == null || LoginPage.getAuthorizationContext(req).getTarget().getId() != c.getOwner().getId()) { resp.sendError(404); return; } diff --git a/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java b/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java index 617d3d65..98e3cab3 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java +++ b/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java @@ -6,8 +6,8 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.cacert.gigi.GigiApiException; +import org.cacert.gigi.dbObjects.CertificateOwner; import org.cacert.gigi.dbObjects.Domain; -import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.template.Form; import org.cacert.gigi.output.template.IterableDataset; @@ -19,9 +19,9 @@ public class DomainManagementForm extends Form { private static final Template t = new Template(DomainManagementForm.class.getResource("DomainManagementForm.templ")); - private User target; + private CertificateOwner target; - public DomainManagementForm(HttpServletRequest hsr, User target) { + public DomainManagementForm(HttpServletRequest hsr, CertificateOwner target) { super(hsr); this.target = target; } diff --git a/src/org/cacert/gigi/pages/account/domain/DomainOverview.java b/src/org/cacert/gigi/pages/account/domain/DomainOverview.java index 7a851c36..ed707612 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainOverview.java +++ b/src/org/cacert/gigi/pages/account/domain/DomainOverview.java @@ -7,9 +7,11 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.cacert.gigi.GigiApiException; +import org.cacert.gigi.dbObjects.CertificateOwner; import org.cacert.gigi.dbObjects.Domain; import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.output.template.Form; +import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.Page; public class DomainOverview extends Page { @@ -22,7 +24,7 @@ public class DomainOverview extends Page { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - User u = getUser(req); + CertificateOwner u = LoginPage.getAuthorizationContext(req).getTarget(); String pi = req.getPathInfo(); if (pi.length() - PATH.length() > 0) { int i = Integer.parseInt(pi.substring(PATH.length())); @@ -48,11 +50,13 @@ public class DomainOverview extends Page { } try { DomainManagementForm domMan = new DomainManagementForm(req, u); - DomainAddForm domAdd = new DomainAddForm(req, u); HashMap vars = new HashMap<>(); vars.put("doms", u.getDomains()); vars.put("domainman", domMan); - vars.put("domainadd", domAdd); + if (u instanceof User) { + DomainAddForm domAdd = new DomainAddForm(req, (User) u); + vars.put("domainadd", domAdd); + } getDefaultTemplate().output(resp.getWriter(), getLanguage(req), vars); } catch (GigiApiException e) { e.format(resp.getWriter(), getLanguage(req)); diff --git a/src/org/cacert/gigi/pages/account/domain/DomainOverview.templ b/src/org/cacert/gigi/pages/account/domain/DomainOverview.templ index 11364a53..bcbe4267 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainOverview.templ +++ b/src/org/cacert/gigi/pages/account/domain/DomainOverview.templ @@ -1,5 +1,6 @@

+

@@ -7,3 +8,6 @@

+ +Please contact your Organisation Assurer to add a domain. + diff --git a/src/org/cacert/gigi/pages/account/mail/MailOverview.java b/src/org/cacert/gigi/pages/account/mail/MailOverview.java index 593307da..092b6a57 100644 --- a/src/org/cacert/gigi/pages/account/mail/MailOverview.java +++ b/src/org/cacert/gigi/pages/account/mail/MailOverview.java @@ -46,5 +46,4 @@ public class MailOverview extends Page { } super.doPost(req, resp); } - } diff --git a/src/org/cacert/gigi/pages/orga/AffiliationForm.java b/src/org/cacert/gigi/pages/orga/AffiliationForm.java index ad988895..c8dd3e52 100644 --- a/src/org/cacert/gigi/pages/orga/AffiliationForm.java +++ b/src/org/cacert/gigi/pages/orga/AffiliationForm.java @@ -42,6 +42,8 @@ public class AffiliationForm extends Form { if (byEmail != null && byEmail.canAssure()) { o.addAdmin(byEmail, LoginPage.getUser(req), req.getParameter("master") != null); return true; + } else { + out.println(Page.getLanguage(req).getTranslation("Requested user is not an assurer. We need an assurer here.")); } } out.println(Page.getLanguage(req).getTranslation("No action could have been carried out.")); diff --git a/src/org/cacert/gigi/util/AuthorizationContext.java b/src/org/cacert/gigi/util/AuthorizationContext.java new file mode 100644 index 00000000..4a329a9f --- /dev/null +++ b/src/org/cacert/gigi/util/AuthorizationContext.java @@ -0,0 +1,29 @@ +package org.cacert.gigi.util; + +import org.cacert.gigi.dbObjects.CertificateOwner; +import org.cacert.gigi.dbObjects.Group; +import org.cacert.gigi.dbObjects.User; + +public class AuthorizationContext { + + CertificateOwner target; + + User actor; + + public AuthorizationContext(CertificateOwner target, User actor) { + this.target = target; + this.actor = actor; + } + + public CertificateOwner getTarget() { + return target; + } + + public User getActor() { + return actor; + } + + public boolean hasRight(Group g) { + return actor.isInGroup(g); + } +} diff --git a/tests/org/cacert/gigi/TestCertificate.java b/tests/org/cacert/gigi/TestCertificate.java index d8553e1f..9a8955e0 100644 --- a/tests/org/cacert/gigi/TestCertificate.java +++ b/tests/org/cacert/gigi/TestCertificate.java @@ -31,9 +31,9 @@ public class TestCertificate extends ManagedTest { public void testClientCertLoginStates() throws IOException, GeneralSecurityException, SQLException, InterruptedException, GigiApiException { KeyPair kp = generateKeypair(); String key1 = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key1, CSRType.CSR, CertificateProfile.getById(1)); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key1, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); - c.issue(null, "2y").waitFor(60000); + c.issue(null, "2y", u).waitFor(60000); final X509Certificate ce = c.cert(); assertNotNull(login(pk, ce)); } @@ -42,11 +42,11 @@ public class TestCertificate extends ManagedTest { public void testSANs() throws IOException, GeneralSecurityException, SQLException, InterruptedException, GigiApiException { KeyPair kp = generateKeypair(); String key = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key, CSRType.CSR, CertificateProfile.getById(1),// + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key, CSRType.CSR, CertificateProfile.getById(1),// new SubjectAlternateName(SANType.EMAIL, "testmail@example.com"), new SubjectAlternateName(SANType.DNS, "testmail.example.com")); testFails(CertificateStatus.DRAFT, c); - c.issue(null, "2y").waitFor(60000); + c.issue(null, "2y", u).waitFor(60000); X509Certificate cert = c.cert(); Collection> sans = cert.getSubjectAlternativeNames(); assertEquals(2, sans.size()); @@ -93,11 +93,11 @@ public class TestCertificate extends ManagedTest { public void testCertLifeCycle() throws IOException, GeneralSecurityException, SQLException, InterruptedException, GigiApiException { KeyPair kp = generateKeypair(); String key = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key, CSRType.CSR, CertificateProfile.getById(1)); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); testFails(CertificateStatus.DRAFT, c); - c.issue(null, "2y").waitFor(60000); + c.issue(null, "2y", u).waitFor(60000); testFails(CertificateStatus.ISSUED, c); X509Certificate cert = c.cert(); @@ -121,7 +121,7 @@ public class TestCertificate extends ManagedTest { } if (status != CertificateStatus.DRAFT) { try { - c.issue(null, "2y"); + c.issue(null, "2y", u); fail(status + " is in invalid state"); } catch (IllegalStateException ise) { diff --git a/tests/org/cacert/gigi/TestCrossDomainAccess.java b/tests/org/cacert/gigi/TestCrossDomainAccess.java index 7e0a4f4e..7bc9c317 100644 --- a/tests/org/cacert/gigi/TestCrossDomainAccess.java +++ b/tests/org/cacert/gigi/TestCrossDomainAccess.java @@ -48,9 +48,9 @@ public class TestCrossDomainAccess extends ManagedTest { User u = User.getById(createVerifiedUser("fn", "ln", "testmail@example.com", TEST_PASSWORD)); KeyPair kp = generateKeypair(); String key = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key, CSRType.CSR, CertificateProfile.getById(1)); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", "testmail@example.com"), "sha256", key, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); - c.issue(null, "2y").waitFor(60000); + c.issue(null, "2y", u).waitFor(60000); URLConnection con = new URL("https://" + ServerConstants.getSecureHostNamePort()).openConnection(); authenticateClientCert(pk, c.cert(), (HttpURLConnection) con); diff --git a/tests/org/cacert/gigi/TestSeparateSessionScope.java b/tests/org/cacert/gigi/TestSeparateSessionScope.java index c82f8e07..f80c216c 100644 --- a/tests/org/cacert/gigi/TestSeparateSessionScope.java +++ b/tests/org/cacert/gigi/TestSeparateSessionScope.java @@ -30,9 +30,10 @@ public class TestSeparateSessionScope extends ManagedTest { String cookie = login(mail, TEST_PASSWORD); KeyPair kp = generateKeypair(); String csr = generatePEMCSR(kp, "CN=hans"); - Certificate c = new Certificate(User.getById(user), Certificate.buildDN("CN", "hans"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); + User u = User.getById(user); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", "hans"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); - c.issue(null, "2y").waitFor(60000); + c.issue(null, "2y", u).waitFor(60000); final X509Certificate ce = c.cert(); String scookie = login(pk, ce); @@ -49,11 +50,12 @@ public class TestSeparateSessionScope extends ManagedTest { int user = createAssuranceUser("test", "tugo", mail, TEST_PASSWORD); KeyPair kp = generateKeypair(); String csr = generatePEMCSR(kp, "CN=hans"); - Certificate c = new Certificate(User.getById(user), Certificate.buildDN("CN", "hans"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); - Certificate c2 = new Certificate(User.getById(user), Certificate.buildDN("CN", "hans"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); + User u = User.getById(user); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", "hans"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); + Certificate c2 = new Certificate(u, u, Certificate.buildDN("CN", "hans"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); - Job j1 = c.issue(null, "2y"); - c2.issue(null, "2y").waitFor(60000); + Job j1 = c.issue(null, "2y", u); + c2.issue(null, "2y", u).waitFor(60000); j1.waitFor(60000); final X509Certificate ce = c.cert(); String scookie = login(pk, ce); diff --git a/tests/org/cacert/gigi/api/IssueCert.java b/tests/org/cacert/gigi/api/IssueCert.java index 74240b26..b4943591 100644 --- a/tests/org/cacert/gigi/api/IssueCert.java +++ b/tests/org/cacert/gigi/api/IssueCert.java @@ -28,9 +28,9 @@ public class IssueCert extends ClientTest { public void testIssueCert() throws Exception { KeyPair kp = generateKeypair(); String key1 = generatePEMCSR(kp, "EMAIL=testmail@example.com"); - Certificate c = new Certificate(u, Certificate.buildDN("EMAIL", "testmail@example.com"), "sha256", key1, CSRType.CSR, CertificateProfile.getById(1)); + Certificate c = new Certificate(u, u, Certificate.buildDN("EMAIL", "testmail@example.com"), "sha256", key1, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); - c.issue(null, "2y").waitFor(60000); + c.issue(null, "2y", u).waitFor(60000); final X509Certificate ce = c.cert(); HttpURLConnection connection = (HttpURLConnection) new URL("https://" + getServerName().replaceFirst("^www.", "api.") + "/account/certs/new").openConnection(); authenticateClientCert(pk, ce, connection); diff --git a/tests/org/cacert/gigi/pages/account/TestCertificateRequest.java b/tests/org/cacert/gigi/pages/account/TestCertificateRequest.java index 4d668b74..44306054 100644 --- a/tests/org/cacert/gigi/pages/account/TestCertificateRequest.java +++ b/tests/org/cacert/gigi/pages/account/TestCertificateRequest.java @@ -11,13 +11,17 @@ import org.cacert.gigi.GigiApiException; import org.cacert.gigi.dbObjects.Group; import org.cacert.gigi.pages.account.certs.CertificateRequest; import org.cacert.gigi.testUtils.ClientTest; +import org.cacert.gigi.util.AuthorizationContext; import org.junit.Test; public class TestCertificateRequest extends ClientTest { KeyPair kp = generateKeypair(); + AuthorizationContext ac; + public TestCertificateRequest() throws GeneralSecurityException, IOException { + ac = new AuthorizationContext(u, u); makeAssurer(u.getId()); grant(email, Group.CODESIGNING); @@ -26,7 +30,7 @@ public class TestCertificateRequest extends ClientTest { @Test public void testIssuingOtherName() throws Exception { try { - new CertificateRequest(u, generatePEMCSR(kp, "CN=hansi")).draft(); + new CertificateRequest(ac, generatePEMCSR(kp, "CN=hansi")).draft(); fail(); } catch (GigiApiException e) { assertThat(e.getMessage(), containsString("name you entered was invalid")); @@ -35,18 +39,18 @@ public class TestCertificateRequest extends ClientTest { @Test public void testIssuingDefault() throws Exception { - new CertificateRequest(u, generatePEMCSR(kp, "CN=" + CertificateRequest.DEFAULT_CN + ",EMAIL=" + email)).draft(); + new CertificateRequest(ac, generatePEMCSR(kp, "CN=" + CertificateRequest.DEFAULT_CN + ",EMAIL=" + email)).draft(); } @Test public void testIssuingRealName() throws Exception { - new CertificateRequest(u, generatePEMCSR(kp, "CN=a b,EMAIL=" + email)).draft(); + new CertificateRequest(ac, generatePEMCSR(kp, "CN=a b,EMAIL=" + email)).draft(); } @Test public void testIssuingModifiedName() throws Exception { try { - new CertificateRequest(u, generatePEMCSR(kp, "CN=a ab")).draft(); + new CertificateRequest(ac, generatePEMCSR(kp, "CN=a ab")).draft(); fail(); } catch (GigiApiException e) { assertThat(e.getMessage(), containsString("name you entered was invalid")); @@ -58,7 +62,7 @@ public class TestCertificateRequest extends ClientTest { @Test public void testCodesignModifiedName() throws Exception { try { - CertificateRequest cr = new CertificateRequest(u, generatePEMCSR(kp, "CN=a ab")); + CertificateRequest cr = new CertificateRequest(ac, generatePEMCSR(kp, "CN=a ab")); cr.update("name", "SHA512", "code-a", null, null, "email:" + email, null, null); } catch (GigiApiException e) { assertThat(e.getMessage(), containsString("does not match the details")); diff --git a/tests/org/cacert/gigi/ping/TestSSL.java b/tests/org/cacert/gigi/ping/TestSSL.java index 19aafe25..01386c53 100644 --- a/tests/org/cacert/gigi/ping/TestSSL.java +++ b/tests/org/cacert/gigi/ping/TestSSL.java @@ -185,8 +185,9 @@ public class TestSSL extends PingTest { private void createCertificate(String test, CertificateProfile profile) throws GeneralSecurityException, IOException, SQLException, InterruptedException, GigiApiException { kp = generateKeypair(); String csr = generatePEMCSR(kp, "CN=" + test); - c = new Certificate(User.getById(id), Certificate.buildDN("CN", test), "sha256", csr, CSRType.CSR, profile); - c.issue(null, "2y").waitFor(60000); + User u = User.getById(id); + c = new Certificate(u, u, Certificate.buildDN("CN", test), "sha256", csr, CSRType.CSR, profile); + c.issue(null, "2y", u).waitFor(60000); } private boolean acceptSSLServer(SSLServerSocket sss) throws IOException { diff --git a/util-testing/org/cacert/gigi/DevelLauncher.java b/util-testing/org/cacert/gigi/DevelLauncher.java index 9fab71c9..df5a790d 100644 --- a/util-testing/org/cacert/gigi/DevelLauncher.java +++ b/util-testing/org/cacert/gigi/DevelLauncher.java @@ -31,6 +31,7 @@ import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.template.Template; import org.cacert.gigi.pages.Page; +import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.ServerConstants; import org.kamranzafar.jtar.TarEntry; import org.kamranzafar.jtar.TarHeader; @@ -195,7 +196,7 @@ public class DevelLauncher { } sess.setAttribute(LOGGEDIN, true); sess.setAttribute(Language.SESSION_ATTRIB_NAME, user.getPreferredLocale()); - sess.setAttribute(USER, user); + sess.setAttribute(AUTH_CONTEXT, new AuthorizationContext(user, user)); req.getSession().setAttribute(LOGIN_METHOD, "Ticket"); resp.getWriter().println("ticket consumed"); ticketUsed = true; diff --git a/util-testing/org/cacert/gigi/pages/Manager.java b/util-testing/org/cacert/gigi/pages/Manager.java index 8b81820b..3701fb98 100644 --- a/util-testing/org/cacert/gigi/pages/Manager.java +++ b/util-testing/org/cacert/gigi/pages/Manager.java @@ -37,6 +37,7 @@ import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.template.IterableDataset; import org.cacert.gigi.output.template.Template; import org.cacert.gigi.pages.account.certs.CertificateRequest; +import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.Notary; import sun.security.x509.X509Key; @@ -243,10 +244,10 @@ public class Manager extends Page { byte[] res = s.getEncoded(sign); - CertificateRequest cr = new CertificateRequest(u, Base64.getEncoder().encodeToString(res), "challange"); + CertificateRequest cr = new CertificateRequest(new AuthorizationContext(u, u), Base64.getEncoder().encodeToString(res), "challange"); cr.update(CertificateRequest.DEFAULT_CN, Digest.SHA512.toString(), "client", null, "", "email:" + u.getEmail(), resp.getWriter(), req); Certificate draft = cr.draft(); - draft.issue(null, "2y").waitFor(10000); + draft.issue(null, "2y", u).waitFor(10000); if (draft.getStatus() == CertificateStatus.ISSUED) { resp.getWriter().println("added certificate"); } else { diff --git a/util-testing/org/cacert/gigi/util/SimpleSigner.java b/util-testing/org/cacert/gigi/util/SimpleSigner.java index b61f851e..843867b6 100644 --- a/util-testing/org/cacert/gigi/util/SimpleSigner.java +++ b/util-testing/org/cacert/gigi/util/SimpleSigner.java @@ -568,6 +568,21 @@ public class SimpleSigner { 2, 5, 4, 11 }; break; + case "ST": + oid = new int[] { + 2, 5, 4, 8 + }; + break; + case "L": + oid = new int[] { + 2, 5, 4, 7 + }; + break; + case "C": + oid = new int[] { + 2, 5, 4, 6 + }; + break; default: throw new Error("unknown RDN-type: " + key); } -- 2.39.2