DROP TABLE IF EXISTS `profiles`;
CREATE TABLE `profiles` (
`id` int(3) NOT NULL AUTO_INCREMENT,
- `keyname` varchar(10) NOT NULL,
+ `keyname` varchar(60) NOT NULL,
`keyUsage` varchar(100) NOT NULL,
`extendedKeyUsage` varchar(100) NOT NULL,
`rootcert` int(2) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE (`keyname`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
-INSERT INTO `profiles` SET keyname='client', name='ssl-client', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth';
-INSERT INTO `profiles` SET keyname='server', name='ssl-server', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='serverAuth';
-INSERT INTO `profiles` SET keyname='mail', name='mail', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='emailProtection';
+INSERT INTO `profiles` SET rootcert=0, keyname='client', name='ssl-client (unassured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth';
+INSERT INTO `profiles` SET rootcert=0, keyname='mail', name='mail (unassured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='emailProtection';
+INSERT INTO `profiles` SET rootcert=0, keyname='client-mail', name='ssl-client + mail (unassured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth, emailProtection';
+INSERT INTO `profiles` SET rootcert=0, keyname='server', name='ssl-server (unassured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='serverAuth';
+INSERT INTO `profiles` SET rootcert=1, keyname='client-a', name='ssl-client (assured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth';
+INSERT INTO `profiles` SET rootcert=1, keyname='mail-a', name='mail (assured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='emailProtection';
+INSERT INTO `profiles` SET rootcert=1, keyname='client-mail-a', name='ssl-client + mail(assured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth, emailProtection';
+INSERT INTO `profiles` SET rootcert=1, keyname='server-a', name='ssl-server (assured)', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='serverAuth';
+
+-- 0=unassured, 1=assured, 2=codesign, 3=orga, 4=orga-sign
DROP TABLE IF EXISTS `subjectAlternativeNames`;
CREATE TABLE `subjectAlternativeNames` (
`certId` int(11) NOT NULL,
public class CertificateProfile {
- final int id;
+ private final int id;
- final String keyName;
+ private final String keyName;
- final String visibleName;
+ private final String visibleName;
- static HashMap<String, CertificateProfile> byName = new HashMap<>();
+ private static HashMap<String, CertificateProfile> byName = new HashMap<>();
- static HashMap<Integer, CertificateProfile> byId = new HashMap<>();
+ private static HashMap<Integer, CertificateProfile> byId = new HashMap<>();
private CertificateProfile(int id, String keyName, String visibleName) {
this.id = id;
public enum Digest {
SHA256("Currently recommended, because the other algorithms" + " might break on some older versions of the GnuTLS library" + " (older than 3.x) still shipped in Debian for example."), SHA384(null), SHA512("Highest protection against hash collision attacks of the algorithms offered here.");
- final String exp;
+ private final String exp;
private Digest(String explanation) {
exp = explanation;
public class Domain {
- User owner;
+ private User owner;
- String suffix;
+ private String suffix;
- int id;
+ private int id;
public Domain(int id) throws SQLException {
PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT memid, domain FROM `domains` WHERE id=? AND deleted IS NULL");
import org.cacert.gigi.pages.Page;
import org.cacert.gigi.pages.TestSecure;
import org.cacert.gigi.pages.Verify;
-import org.cacert.gigi.pages.account.ChangePasswordPage;
-import org.cacert.gigi.pages.account.DomainOverview;
import org.cacert.gigi.pages.account.CertificateAdd;
import org.cacert.gigi.pages.account.Certificates;
+import org.cacert.gigi.pages.account.ChangePasswordPage;
+import org.cacert.gigi.pages.account.DomainOverview;
import org.cacert.gigi.pages.account.MailOverview;
import org.cacert.gigi.pages.account.MyDetails;
import org.cacert.gigi.pages.error.PageNotFound;
private HashMap<String, Page> pages = new HashMap<String, Page>();
- Menu m;
+ private Menu m;
public Gigi(Properties conf) {
DatabaseConnection.init(conf);
final Page p = getPage(req.getPathInfo());
if (p != null) {
- if (p.needsLogin() && hs.getAttribute("loggedin") == null) {
+ if ( !p.isPermitted(LoginPage.getUser(req)) && hs.getAttribute("loggedin") == null) {
String request = req.getPathInfo();
request = request.split("\\?")[0];
hs.setAttribute(LoginPage.LOGIN_RETURNPATH, request);
public class GigiApiException extends Exception {
- SQLException e;
+ private SQLException e;
- LinkedList<String> messages = new LinkedList<>();
+ private LinkedList<String> messages = new LinkedList<>();
public GigiApiException(SQLException e) {
super(e);
public static final String GIGI_CONFIG_VERSION = "GigiConfigV1.0";
- byte[] cacerts;
+ private byte[] cacerts;
- byte[] keystore;
+ private byte[] keystore;
- Properties mainProps = new Properties();
+ private Properties mainProps = new Properties();
private char[] keystorpw;
ServerConnector connector = new ServerConnector(s, createConnectionFactory(conf), new HttpConnectionFactory(https_config));
connector.setHost(conf.getMainProps().getProperty("host"));
connector.setPort(Integer.parseInt(conf.getMainProps().getProperty("port")));
+ connector.setAcceptQueueSize(100);
s.setConnectors(new Connector[] {
connector
});
--- /dev/null
+package org.cacert.gigi;
+
+
+public interface PermissionCheckable {
+
+ public boolean isPermitted(User u);
+
+}
private int id;
- Name name = new Name(null, null, null, null);
+ private Name name = new Name(null, null, null, null);
- Date dob;
+ private Date dob;
- String email;
+ private String email;
public User(int id) {
this.id = id;
mimeEncode(contents, Base64.getEncoder().encodeToString(bOut.toByteArray()).replaceAll("(.{64})(?=.)", "$1\n"), to);
}
- static Random r = new Random();
+ private static Random r = new Random();
private static void mimeEncode(String contents, String signature, PrintWriter to) {
String boundary = generateBoundary(contents, null);
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
import java.util.HashMap;
import java.util.Properties;
-import java.sql.Statement;
public class DatabaseConnection {
public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
- Connection c;
+ private Connection c;
- HashMap<String, PreparedStatement> statements = new HashMap<String, PreparedStatement>();
+ private HashMap<String, PreparedStatement> statements = new HashMap<String, PreparedStatement>();
private static Properties credentials;
- Statement adHoc;
+ private Statement adHoc;
public DatabaseConnection() {
try {
return statement;
}
- long lastAction = System.currentTimeMillis();
+ private long lastAction = System.currentTimeMillis();
private void ensureOpen() {
if (System.currentTimeMillis() - lastAction > CONNECTION_TIMEOUT * 1000L) {
return id;
}
- static ThreadLocal<DatabaseConnection> instances = new ThreadLocal<DatabaseConnection>() {
+ private static ThreadLocal<DatabaseConnection> instances = new ThreadLocal<DatabaseConnection>() {
@Override
protected DatabaseConnection initialValue() {
class TestEmailProvider extends EmailProvider {
- ServerSocket servs;
+ private ServerSocket servs;
- Socket client;
+ private Socket client;
- DataOutputStream out;
+ private DataOutputStream out;
- DataInputStream in;
+ private DataInputStream in;
protected TestEmailProvider(Properties props) {
try {
private static HashMap<String, Language> langs = new HashMap<String, Language>();
- HashMap<String, String> translations = new HashMap<String, String>();
+ private HashMap<String, String> translations = new HashMap<String, String>();
- Locale l;
+ private Locale l;
protected Language(String language) throws ParserConfigurationException, IOException, SAXException {
if (language.contains("_")) {
public class CertificateIterable implements IterableDataset {
- Certificate[] certificates;
+ private Certificate[] certificates;
public CertificateIterable(Certificate[] certificates) {
this.certificates = certificates;
}
- int i = 0;
+ private int i = 0;
@Override
public boolean next(Language l, Map<String, Object> vars) {
public class ClientCSRGenerate {
- static Template normal;
+ private static Template normal;
- static Template IE;
+ private static Template IE;
static {
normal = new Template(ClientCSRGenerate.class.getResource("ClientCSRGenerate.templ"));
IE = new Template(ClientCSRGenerate.class.getResource("ClientCSRGenerateIE.templ"));
public class DateSelector implements Outputable {
- String[] names;
+ private String[] names;
public DateSelector(String day, String month, String year) {
this.names = new String[] {
};
}
- int day;
+ private int day;
- int month;
+ private int month;
- int year;
+ private int year;
@Override
public void output(PrintWriter out, Language l, Map<String, Object> vars) {
public static final String CSRF_FIELD = "csrf";
- String csrf;
+ private String csrf;
public Form(HttpServletRequest hsr) {
csrf = RandomToken.generateToken(32);
--- /dev/null
+package org.cacert.gigi.output;
+
+/**
+ * Markerinterface for an {@link Outputable} speicially used in a {@link Menu}.
+ *
+ * @author janis
+ */
+public interface IMenuItem extends Outputable {
+ // Nothing to see here.
+}
public class Menu implements Outputable {
- String menuName;
+ private String menuName;
- String id;
+ private String id;
- private MenuItem[] content;
+ private IMenuItem[] content;
- public Menu(String menuName, String id, MenuItem... content) {
+ public Menu(String menuName, String id, IMenuItem... content) {
this.menuName = menuName;
this.id = id;
this.content = content;
out.print("<ul class=\"menu\" id=\"");
out.print(id);
out.print("\">");
- for (MenuItem mi : content) {
+ for (Outputable mi : content) {
mi.output(out, l, vars);
}
import org.cacert.gigi.localisation.Language;
-public class MenuItem implements Outputable {
+public class MenuItem implements Outputable, IMenuItem {
- final String href;
+ private final String href;
- final String name;
+ private final String name;
public MenuItem(String href, String name) {
this.href = href;
public class HashAlgorithms implements IterableDataset {
- int i = 0;
+ private int i = 0;
- Digest selected;
+ private Digest selected;
public HashAlgorithms(Digest selected) {
this.selected = selected;
public class Template implements Outputable {
- TemplateBlock data;
+ private TemplateBlock data;
- long lastLoaded;
+ private long lastLoaded;
- File source;
+ private File source;
private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-z]+)\\(\\$([^)]+)\\) ?\\{ ?");
return null;
}
+ @Override
public void output(PrintWriter out, Language l, Map<String, Object> vars) {
if (source != null && DevelLauncher.DEVEL) {
if (lastLoaded < source.lastModified()) {
class TemplateBlock implements Outputable {
- String[] contents;
+ private String[] contents;
- Outputable[] vars;
+ private Outputable[] vars;
public TemplateBlock(String[] contents, Outputable[] vars) {
this.contents = contents;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.cacert.gigi.PermissionCheckable;
import org.cacert.gigi.User;
import org.cacert.gigi.localisation.Language;
import org.cacert.gigi.output.template.Template;
* This class encapsulates a sub page of Gigi. A template residing nearby this
* class with name <className>.templ will be loaded automatically.
*/
-public abstract class Page {
+public abstract class Page implements PermissionCheckable {
private String title;
return LoginPage.getUser(req);
}
+ @Override
+ public boolean isPermitted(User u) {
+ return !needsLogin() || u != null;
+ }
+
}
1, 3, 6, 1, 5, 5, 7, 3, 9
});
- User u;
+ private User u;
private CSRType csrType;
- String csr;
+ private String csr;
- String spkacChallenge;
+ private String spkacChallenge;
public String CN = DEFAULT_CN;
- Set<SubjectAlternateName> SANs = new LinkedHashSet<>();
+ private Set<SubjectAlternateName> SANs = new LinkedHashSet<>();
- Digest selectedDigest = Digest.getDefault();
+ private Digest selectedDigest = Digest.getDefault();
CertificateValiditySelector issueDate = new CertificateValiditySelector();
- boolean login;
+ private boolean login;
- CertificateProfile profile = CertificateProfile.getById(1);
+ private CertificateProfile profile = CertificateProfile.getById(1);
public CertificateIssueForm(HttpServletRequest hsr) {
super(hsr);
spkacChallenge = RandomToken.generateToken(16);
}
- Certificate result;
+ private Certificate result;
public Certificate getResult() {
return result;
public class Certificates extends Page {
- Template certDisplay = new Template(Certificates.class.getResource("CertificateDisplay.templ"));
+ private Template certDisplay = new Template(Certificates.class.getResource("CertificateDisplay.templ"));
public static final String PATH = "/account/certs";
return true;
}
- Template certTable = new Template(CertificateIterable.class.getResource("CertificateTable.templ"));
+ private Template certTable = new Template(CertificateIterable.class.getResource("CertificateTable.templ"));
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
public class ChangeForm extends Form {
- User target;
+ private User target;
public ChangeForm(HttpServletRequest hsr, User target) {
super(hsr);
t = new Template(ChangePasswordPage.class.getResource("MailAddForm.templ"));
}
- User target;
+ private User target;
public MailAddForm(HttpServletRequest hsr, User target) {
super(hsr);
</tr>
<? foreach($emails) {?>
<tr>
- <td><input type="radio" name="emailid" value="<?=$id?>" <?=$checked?>></td>
+ <td><input type="radio" name="emailid" value="<?=$id?>" <?=$!checked?>></td>
<td><?=$verification?></td>
- <td><?=$delete?></td>
+ <td><?=$!delete?></td>
<td><?=$address?></td>
</tr>
<? } ?>
import java.io.IOException;
import java.io.PrintWriter;
+import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
public class Signup extends Form {
- User buildup = new User();
+ private User buildup = new User();
- Template t;
+ private Template t;
boolean general = true, country = true, regional = true, radius = true;
public class AssuranceForm extends Form {
- User assuree;
+ private User assuree;
- static final Template templ;
+ private static final Template templ;
static {
templ = new Template(AssuranceForm.class.getResource("AssuranceForm.templ"));
}
return false;
}
+ public User getAssuree() {
+ return assuree;
+ }
+
}
out.println(translate(req, check.getMessage()));
return;
}
- if (form == null || form.assuree.getId() != mid) {
+ if (form == null || form.getAssuree().getId() != mid) {
form = new AssuranceForm(req, mid);
}
}
AssuranceForm form = Form.getForm(req, AssuranceForm.class);
- if (mid != form.assuree.getId()) {
+ if (mid != form.getAssuree().getId()) {
return;
}
if (form.submit(out, req)) {
public class Job {
- int id;
+ private int id;
private Job(int id) {
this.id = id;
public class PasswordStrengthChecker {
- static Pattern digits = Pattern.compile("\\d");
+ private static Pattern digits = Pattern.compile("\\d");
- static Pattern lower = Pattern.compile("[a-z]");
+ private static Pattern lower = Pattern.compile("[a-z]");
- static Pattern upper = Pattern.compile("[A-Z]");
+ private static Pattern upper = Pattern.compile("[A-Z]");
- static Pattern whitespace = Pattern.compile("\\s");
+ private static Pattern whitespace = Pattern.compile("\\s");
- static Pattern special = Pattern.compile("(?!\\s)\\W");
+ private static Pattern special = Pattern.compile("(?!\\s)\\W");
private PasswordStrengthChecker() {}
public class RandomToken {
- static SecureRandom sr = new SecureRandom();
+ private static SecureRandom sr = new SecureRandom();
public static String generateToken(int length) {
StringBuffer token = new StringBuffer();
private static Thread runner;
private static SimpleDateFormat sdf = new SimpleDateFormat("YYMMddHHmmss'Z'");
+
static {
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
}
throw new IllegalStateException("already running");
}
running = true;
- readyCerts = DatabaseConnection.getInstance().prepare("SELECT certs.id AS id, certs.csr_name, certs.subject, jobs.id AS jobid, csr_type, md, keyUsage, extendedKeyUsage, executeFrom, executeTo FROM jobs " + //
+ readyCerts = DatabaseConnection.getInstance().prepare("SELECT certs.id AS id, certs.csr_name, certs.subject, jobs.id AS jobid, csr_type, md, keyUsage, extendedKeyUsage, executeFrom, executeTo, rootcert FROM jobs " + //
"INNER JOIN certs ON certs.id=jobs.targetId " + //
"INNER JOIN profiles ON profiles.id=certs.profile " + //
"WHERE jobs.state='open' "//
cfg.println("extendedKeyUsage=" + ekeyUsage);
cfg.close();
+ int rootcert = rs.getInt("rootcert");
+ String ca = "unassured";
+ if (rootcert == 0) {
+ ca = "unassured";
+ } else if (rootcert == 1) {
+ ca = "assured";
+ }
+
String[] call = new String[] {
"openssl", "ca",//
"-in",
"../../" + csrname,//
"-cert",
- "../unassured.crt",//
+ "../" + ca + ".crt",//
"-keyfile",
- "../unassured.key",//
+ "../" + ca + ".key",//
"-out",
"../../" + crt.getPath(),//
"-utf8",