From d7ff9d5e217873609d79efe279f2634e3a3dd8b4 Mon Sep 17 00:00:00 2001 From: Yuuta Liang Date: Wed, 25 Oct 2023 03:30:45 +0800 Subject: Refactor: move all logics into CertificationAuthority Signed-off-by: Yuuta Liang --- src/main/ui/MgmtScreen.java | 117 +++++++++++++------------------------------- 1 file changed, 33 insertions(+), 84 deletions(-) (limited to 'src/main/ui/MgmtScreen.java') diff --git a/src/main/ui/MgmtScreen.java b/src/main/ui/MgmtScreen.java index 1957c7e..0a25bfe 100644 --- a/src/main/ui/MgmtScreen.java +++ b/src/main/ui/MgmtScreen.java @@ -1,20 +1,14 @@ package ui; -import model.asn1.ASN1Object; -import model.asn1.BitString; -import model.asn1.Bool; -import model.asn1.ObjectIdentifier; +import model.asn1.exceptions.InvalidCAException; import model.asn1.exceptions.ParseException; import model.asn1.parsing.BytesReader; import model.csr.CertificationRequest; -import model.pki.SubjectPublicKeyInfo; import model.pki.cert.Certificate; -import model.pki.cert.Extension; import model.pki.cert.TbsCertificate; -import java.util.Arrays; +import java.security.NoSuchAlgorithmException; import java.util.Base64; -import java.util.BitSet; /** * Manage the private key and CA certificate. It can print the public key, generate CSR, and install CA cert. @@ -35,6 +29,7 @@ public class MgmtScreen implements UIHandler { @Override public void help() { System.out.print("show\tView the public key and CA certificate\n" + + "genkey\tGenerate a RSA private key\n" + "csr\tGenerate a CSR for a upper-level CA to sign\n" + "install\tInstall a CA certificate\n" + "exit\tGo to main menu\n" @@ -46,8 +41,14 @@ public class MgmtScreen implements UIHandler { */ @Override public void show() { - System.out.printf("Public Key:\t%s\n", - Base64.getEncoder().encodeToString(session.getCa().getPublicKey().getEncoded())); + if (session.getCa().getPublicKey() == null) { + System.out.println("No private key installed"); + } else { + System.out.println("Public Key (RSA2048):"); + System.out.printf("\tModules:\t\t%s\n", session.getCa().getPublicKey().getModulus().toString(10)); + System.out.printf("\tPublic Exponent:\t%s\n", + session.getCa().getPublicKey().getPublicExponent().toString(16)); + } if (!session.checkCA(true)) { return; } @@ -63,6 +64,7 @@ public class MgmtScreen implements UIHandler { /** * EFFECT: Generate a CSR + * MODIFIES: session */ private void handleCSR() { if (!session.checkCA(false)) { @@ -71,80 +73,14 @@ public class MgmtScreen implements UIHandler { try { CertificationRequest req = session.getCa().signCSR(); System.out.println(Utils.toPEM(req.encodeDER(), "CERTIFICATE REQUEST")); - session.log("Signed CA CSR."); } catch (Throwable e) { System.out.println(e.getMessage()); } } - /** - * EFFECTS: Throw {@link ParseException} if the incoming cert is not v3. - */ - private void validateCACertificateVersion(Certificate cert) throws ParseException { - if (cert.getCertificate().getVersion() == null - || cert.getCertificate().getVersion().getLong() != TbsCertificate.VERSION_V3) { - throw new ParseException("The input certificate must be V3"); - } - } - - /** - * EFFECTS: Throw {@link ParseException} if the incoming cert does not have the matching public key. - */ - private void validateCACertificatePublicKey(Certificate cert) throws ParseException { - final SubjectPublicKeyInfo expectedPKInfo = session.getCa().getCAPublicKeyInfo(); - if (!Arrays.equals(cert.getCertificate().getSubjectPublicKeyInfo().getAlgorithm().getType().getInts(), - expectedPKInfo.getAlgorithm().getType().getInts()) - || !Arrays.equals(cert.getCertificate().getSubjectPublicKeyInfo().getSubjectPublicKey().getVal(), - expectedPKInfo.getSubjectPublicKey().getVal())) { - throw new ParseException("The input certificate does not have the corresponding public key"); - } - } - - /** - * EFFECTS: Throw {@link ParseException} if the incoming cert does not have cA = true in its basicConstraints. - */ - private void validateCACertificateBasicConstraints(Certificate cert) throws ParseException { - final Extension basicConstraints = cert.getCertificate().getExtension(ObjectIdentifier.OID_BASIC_CONSTRAINTS); - if (basicConstraints == null - || basicConstraints.getExtnValue().getBytes().length <= 0) { - throw new ParseException("The certificate does not have a valid basicConstraints extension."); - } - final ASN1Object basicConstraintsValue = - new ASN1Object(new BytesReader(basicConstraints.getExtnValue().getBytes()), false); - if (basicConstraintsValue.getLength() <= 0) { - throw new ParseException("The certificate does not have a valid basicConstraints extension."); - } - final ASN1Object bool = - ASN1Object.parse(new BytesReader(basicConstraintsValue.encodeValueDER()), false); - if (!(bool instanceof Bool) - || !((Bool) bool).getValue()) { - throw new ParseException("The certificate does not have a valid basicConstraints extension."); - } - } - - /** - * EFFECTS: Throw {@link ParseException} if the incoming cert does not have valid key usages. - */ - private void validateCACertificateKeyUsage(Certificate cert) throws ParseException { - final Extension keyUsage = cert.getCertificate().getExtension(ObjectIdentifier.OID_KEY_USAGE); - if (keyUsage == null - || keyUsage.getExtnValue().getBytes().length <= 0) { - throw new ParseException("The certificate does not have a valid keyUsage extension."); - } - final ASN1Object keyUsageValue = - ASN1Object.parse(new BytesReader(keyUsage.getExtnValue().getBytes()), false); - if (keyUsageValue.getLength() <= 0 - || !(keyUsageValue instanceof BitString)) { - throw new ParseException("The certificate does not have a valid keyUsage extension."); - } - final BitSet bitSet = BitSet.valueOf(Utils.byteToByte(((BitString) keyUsageValue).getVal())); - if (!bitSet.get(7) || !bitSet.get(2) || !bitSet.get(1)) { - throw new ParseException("The certificate does not have a valid keyUsage extension."); - } - } - /** * EFFECTS: Handle the 'install' command. Read incoming certificate and validate it. + * MODIFIES: session */ private void handleInstall() { if (!session.checkCA(false)) { @@ -152,14 +88,24 @@ public class MgmtScreen implements UIHandler { } try { final Byte[] in = session.handleInputPEM("CERTIFICATE"); - Certificate cert = new Certificate(new BytesReader(in), false); - validateCACertificateVersion(cert); - validateCACertificatePublicKey(cert); - validateCACertificateBasicConstraints(cert); - validateCACertificateKeyUsage(cert); + final Certificate cert = new Certificate(new BytesReader(in), false); session.getCa().installCertificate(cert); - session.log("A CA certificate is installed."); - } catch (ParseException e) { + } catch (InvalidCAException | ParseException e) { + System.out.println(e.getMessage()); + } + } + + /** + * EFFECTS: Handle the 'genkey' command. Generate a RSA2048 private key. + * MODIFIES: session + */ + private void handleGenKey() { + if (session.getCa().getPublicKey() != null) { + System.out.println("A private key is already installed."); + } + try { + session.getCa().generateKey(); + } catch (NoSuchAlgorithmException e) { System.out.println(e.getMessage()); } } @@ -170,6 +116,9 @@ public class MgmtScreen implements UIHandler { @Override public void command(String... args) { switch (args[0]) { + case "genkey": + handleGenKey(); + break; case "csr": handleCSR(); break; -- cgit v1.2.3