From 0bcc057e741af3fbc108f42b75f9d42f48f6a51e Mon Sep 17 00:00:00 2001 From: Yuuta Liang Date: Sat, 14 Oct 2023 05:12:06 +0800 Subject: Implement the CA Signed-off-by: Yuuta Liang --- src/main/ui/IssueScreen.java | 138 +++++++++++++++++++++++++ src/main/ui/JCA.java | 203 +++++++++++++++++++++++++++++++++++++ src/main/ui/Main.java | 4 +- src/main/ui/MainScreen.java | 200 ++++++++++++++++++++++++++++++++++++ src/main/ui/MgmtScreen.java | 170 +++++++++++++++++++++++++++++++ src/main/ui/Screen.java | 31 ++++++ src/main/ui/TemplateSetScreen.java | 131 ++++++++++++++++++++++++ src/main/ui/TemplatesScreen.java | 108 ++++++++++++++++++++ src/main/ui/UIHandler.java | 45 ++++++++ src/main/ui/Utils.java | 44 ++++---- 10 files changed, 1049 insertions(+), 25 deletions(-) create mode 100644 src/main/ui/IssueScreen.java create mode 100644 src/main/ui/JCA.java create mode 100644 src/main/ui/MainScreen.java create mode 100644 src/main/ui/MgmtScreen.java create mode 100644 src/main/ui/Screen.java create mode 100644 src/main/ui/TemplateSetScreen.java create mode 100644 src/main/ui/TemplatesScreen.java create mode 100644 src/main/ui/UIHandler.java (limited to 'src/main/ui') diff --git a/src/main/ui/IssueScreen.java b/src/main/ui/IssueScreen.java new file mode 100644 index 0000000..e152b0d --- /dev/null +++ b/src/main/ui/IssueScreen.java @@ -0,0 +1,138 @@ +package ui; + +import model.asn1.exceptions.ParseException; +import model.asn1.parsing.BytesReader; +import model.ca.Template; +import model.csr.CertificationRequest; +import model.pki.cert.Certificate; + +public class IssueScreen implements UIHandler { + private final JCA session; + + private Template template; + private CertificationRequest incomingCSR; + + /** + * EFFECTS: Init with the session. + */ + public IssueScreen(JCA session) { + this.session = session; + } + + /** + * EFFECTS: Set current template and CSR in use by args. + * REQUIRES: args.length = 2, args[0] instanceof CertificateRequest, args[1] instanceof Template + * MODIFIES: args[1] + */ + @Override + public void enter(Object... args) { + this.incomingCSR = (CertificationRequest) args[0]; + this.template = (Template) args[1]; + } + + @Override + public void help() { + System.out.print("show\tView the current certificate\n" + + "set\tSet properties or template\n" + + "commit\tIssue the certificate\n" + + "exit\tDiscard and go to main menu\n" + + "help\tPrint this message\n"); + } + + @Override + public void show() { + System.out.println("Requested Subject:\t" + incomingCSR.getCertificationRequestInfo().getSubject()); + System.out.println("Subject:\t" + (template.getSubject() == null + ? incomingCSR.getCertificationRequestInfo().getSubject() + : template.getSubject())); + System.out.println("Template:\t" + template.getName()); + System.out.println("Validity:\t" + template.getValidity() + " days"); + } + + @Override + public void commit() { + try { + Certificate certificate = session.getCa().signCert(incomingCSR.getCertificationRequestInfo(), template); + System.out.println(Utils.toPEM(certificate.encodeDER(), "CERTIFICATE")); + session.log("A certificate was issued."); + session.setScreen(Screen.MAIN); + } catch (Throwable e) { + System.out.println(e.getMessage()); + } + } + + private void handleIssueSetSubject(String val) { + try { + template.setSubject(val); + } catch (ParseException e) { + System.out.println(e.getMessage()); + } + } + + private void handleIssueSetValidity(String val) { + if (val == null) { + System.out.println("Cannot unset validity"); + return; + } + try { + long i = Long.parseLong(val); + if (i <= 0) { + System.out.println("Invalid validity days"); + return; + } + template.setValidity(i); + } catch (NumberFormatException ignored) { + System.out.println("Invalid validity days"); + } + } + + private void handleIssueSet(String... args) { + if (args.length != 2 && args.length != 3) { + System.out.println("Usage: set "); + System.out.println("Supported keys: subject validity"); + return; + } + String val = args.length == 3 ? args[2] : null; + switch (args[1]) { + case "subject": + handleIssueSetSubject(val); + break; + case "validity": + handleIssueSetValidity(val); + break; + default: + System.out.println("Unknown key"); + break; + } + } + + @Override + public void command(String... args) { + switch (args[0]) { + case "set": + handleIssueSet(args); + break; + default: + help(); + break; + } + } + + /** + * EFFECTS: Clear the certificates and return main. + * MODIFIES: this + */ + @Override + public Screen exit() { + incomingCSR = null; + template = null; + return Screen.MAIN; + } + + @Override + public String getPS1() { + return String.format("/%s/ %%", template.getSubject() == null + ? incomingCSR.getCertificationRequestInfo().getSubject() + : template.getSubject()); + } +} diff --git a/src/main/ui/JCA.java b/src/main/ui/JCA.java new file mode 100644 index 0000000..f9467ea --- /dev/null +++ b/src/main/ui/JCA.java @@ -0,0 +1,203 @@ +package ui; + +import model.asn1.exceptions.ParseException; +import model.ca.AuditLogEntry; +import model.ca.CACertificate; +import model.ca.Template; + +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.time.ZonedDateTime; +import java.util.*; + +/** + * Main program + */ +public class JCA { + /** + * The current screen. + */ + private UIHandler screen; + + /** + * Instances of the five screens; + */ + private final UIHandler mainScreen; + private final UIHandler mgmtScreen; + private final UIHandler issueScreen; + private final UIHandler templatesScreen; + private final UIHandler templateSetScreen; + + /** + * Templates + */ + private final List