From: Felix Dörre Date: Tue, 20 Feb 2018 20:21:39 +0000 (+0100) Subject: Merge changes I18f5f27f,I27ec303f,I78009fe3 X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=985d31f75a724d141ff37bb678c28aaa474d5915;hp=cbd469caf6d9b18a9e1b74ba5292e4f5a71fcbfd Merge changes I18f5f27f,I27ec303f,I78009fe3 * changes: fix: avoid resource leak when generating OCSP requests fix: prevent possible NPE on failure to list the CA directory chg: ensure actor, target and support ticket are non-null --- diff --git a/src/club/wpia/gigi/crypto/OCSPRequest.java b/src/club/wpia/gigi/crypto/OCSPRequest.java index 180297e3..d8fdf53e 100644 --- a/src/club/wpia/gigi/crypto/OCSPRequest.java +++ b/src/club/wpia/gigi/crypto/OCSPRequest.java @@ -109,40 +109,52 @@ public class OCSPRequest { byte[] encodeBytes() throws IOException { - // encode tbsRequest - DerOutputStream tmp = new DerOutputStream(); - DerOutputStream requestsOut = new DerOutputStream(); - for (CertId certId : certIds) { - DerOutputStream certIdOut = new DerOutputStream(); - certId.encode(certIdOut); - requestsOut.write(DerValue.tag_Sequence, certIdOut); - } + try (DerOutputStream ocspRequest = new DerOutputStream()) { + try (DerOutputStream tbsRequest = new DerOutputStream()) { + try (DerOutputStream tmp = new DerOutputStream()) { + + // encode tbsRequest + try (DerOutputStream requestsOut = new DerOutputStream()) { + for (CertId certId : certIds) { + try (DerOutputStream certIdOut = new DerOutputStream()) { + certId.encode(certIdOut); + requestsOut.write(DerValue.tag_Sequence, certIdOut); + } + } + + tmp.write(DerValue.tag_Sequence, requestsOut); + } - tmp.write(DerValue.tag_Sequence, requestsOut); - if ( !extensions.isEmpty()) { - DerOutputStream extOut = new DerOutputStream(); - for (Extension ext : extensions) { - ext.encode(extOut); - if (ext.getId().equals(NONCE_EXTENSION_OID.toString())) { - nonce = ext.getValue(); - nonceExt = ext; - } - } - DerOutputStream extsOut = new DerOutputStream(); - extsOut.write(DerValue.tag_Sequence, extOut); - tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 2), extsOut); - } + if ( !extensions.isEmpty()) { + try (DerOutputStream extsOut = new DerOutputStream()) { + try (DerOutputStream extOut = new DerOutputStream()) { + for (Extension ext : extensions) { + ext.encode(extOut); + + if (ext.getId().equals(NONCE_EXTENSION_OID.toString())) { + nonce = ext.getValue(); + nonceExt = ext; + } + } - DerOutputStream tbsRequest = new DerOutputStream(); - tbsRequest.write(DerValue.tag_Sequence, tmp); + extsOut.write(DerValue.tag_Sequence, extOut); + } - // OCSPRequest without the signature - DerOutputStream ocspRequest = new DerOutputStream(); - ocspRequest.write(DerValue.tag_Sequence, tbsRequest); + tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 2), extsOut); + } + } + + tbsRequest.write(DerValue.tag_Sequence, tmp); + } - byte[] bytes = ocspRequest.toByteArray(); + // OCSPRequest without the signature + ocspRequest.write(DerValue.tag_Sequence, tbsRequest); + } + + byte[] bytes = ocspRequest.toByteArray(); - return bytes; + return bytes; + } } public List getCertIds() { diff --git a/src/club/wpia/gigi/ocsp/OCSPIssuerManager.java b/src/club/wpia/gigi/ocsp/OCSPIssuerManager.java index 40e6d67c..400737f0 100644 --- a/src/club/wpia/gigi/ocsp/OCSPIssuerManager.java +++ b/src/club/wpia/gigi/ocsp/OCSPIssuerManager.java @@ -97,9 +97,15 @@ public class OCSPIssuerManager implements Runnable { */ private void scanAndUpdateCAs(File f, KeyStore keys, Map toServe) { if (f.isDirectory()) { - for (File f1 : f.listFiles()) { - scanAndUpdateCAs(f1, keys, toServe); + File[] list = f.listFiles(); + if (list == null) { + return; + } + + for (File file : list) { + scanAndUpdateCAs(file, keys, toServe); } + return; } if ( !f.getName().equals("ca.crt")) { diff --git a/src/club/wpia/gigi/pages/LoginPage.java b/src/club/wpia/gigi/pages/LoginPage.java index b0ed6e69..66412a91 100644 --- a/src/club/wpia/gigi/pages/LoginPage.java +++ b/src/club/wpia/gigi/pages/LoginPage.java @@ -120,24 +120,31 @@ public class LoginPage extends Page { try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `password`, `id` FROM `users` WHERE `email`=? AND verified='1'")) { ps.setString(1, un); GigiResultSet rs = ps.executeQuery(); - if (rs.next()) { - String dbHash = rs.getString(1); - String hash = PasswordHash.verifyHash(pw, dbHash); - if (hash != null) { - if ( !hash.equals(dbHash)) { - try (GigiPreparedStatement gps = new GigiPreparedStatement("UPDATE `users` SET `password`=? WHERE `email`=?")) { - gps.setString(1, hash); - gps.setString(2, un); - gps.executeUpdate(); - } + if ( !rs.next()) { + throw new GigiApiException("Username and password didn't match."); + } + + User user = User.getById(rs.getInt(2)); + if (user == null) { + throw new GigiApiException("Username and password didn't match."); + } + + String dbHash = rs.getString(1); + String hash = PasswordHash.verifyHash(pw, dbHash); + if (hash != null) { + if ( !hash.equals(dbHash)) { + try (GigiPreparedStatement gps = new GigiPreparedStatement("UPDATE `users` SET `password`=? WHERE `email`=?")) { + gps.setString(1, hash); + gps.setString(2, un); + gps.executeUpdate(); } - loginSession(req, User.getById(rs.getInt(2))); - req.getSession().setAttribute(LOGIN_METHOD, new TranslateCommand("Password")); - return; } + + loginSession(req, user); + req.getSession().setAttribute(LOGIN_METHOD, new TranslateCommand("Password")); + return; } } - throw new GigiApiException("Username and password didn't match."); } public static User getUser(HttpServletRequest req) { diff --git a/src/club/wpia/gigi/util/AuthorizationContext.java b/src/club/wpia/gigi/util/AuthorizationContext.java index 40a63335..5d70b382 100644 --- a/src/club/wpia/gigi/util/AuthorizationContext.java +++ b/src/club/wpia/gigi/util/AuthorizationContext.java @@ -18,24 +18,37 @@ public class AuthorizationContext implements Outputable, Serializable { private static final long serialVersionUID = -2596733469159940154L; - private CertificateOwner target; + private final CertificateOwner target; - private User actor; + private final User actor; - private String supporterTicketId; + private final String supporterTicketId; public AuthorizationContext(CertificateOwner target, User actor) { + if (actor == null) { + throw new Error("Internal Error: The actor of an AuthorizationContext must not be null!"); + } + if (target == null) { + throw new Error("Internal Error: The target of an AuthorizationContext must not be null!"); + } this.target = target; this.actor = actor; + this.supporterTicketId = null; } public AuthorizationContext(User actor, String supporterTicket) throws GigiApiException { + if (actor == null) { + throw new Error("Internal Error: The actor of an AuthorizationContext must not be null!"); + } + if (supporterTicket == null) { + throw new Error("Internal Error: The AuthorizationContext for a Support Engineer requires a valid ticket!"); + } this.target = actor; this.actor = actor; if ( !isInGroup(Group.SUPPORTER)) { throw new GigiApiException("requires a supporter"); } - supporterTicketId = supporterTicket; + this.supporterTicketId = supporterTicket; } public CertificateOwner getTarget() { @@ -50,7 +63,7 @@ public class AuthorizationContext implements Outputable, Serializable { return actor.isInGroup(g); } - public User getActor(AuthorizationContext ac) { + public static User getActor(AuthorizationContext ac) { if (ac == null) { return null; }