aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYuuta Liang <yuutaw@student.cs.ubc.ca>2023-10-25 03:30:45 +0800
committerYuuta Liang <yuutaw@student.cs.ubc.ca>2023-10-25 03:30:45 +0800
commitd7ff9d5e217873609d79efe279f2634e3a3dd8b4 (patch)
tree704729e5eed658728b521acd407c6ca767f7e865 /src
parent55df54e5dbf26e6824123410784d00aa793c3781 (diff)
downloadjca-d7ff9d5e217873609d79efe279f2634e3a3dd8b4.tar
jca-d7ff9d5e217873609d79efe279f2634e3a3dd8b4.tar.gz
jca-d7ff9d5e217873609d79efe279f2634e3a3dd8b4.tar.bz2
jca-d7ff9d5e217873609d79efe279f2634e3a3dd8b4.zip
Refactor: move all logics into CertificationAuthority
Signed-off-by: Yuuta Liang <yuutaw@student.cs.ubc.ca>
Diffstat (limited to 'src')
-rw-r--r--src/main/model/asn1/ASN1Time.java2
-rw-r--r--src/main/model/asn1/GeneralizedTime.java10
-rw-r--r--src/main/model/asn1/UtcTime.java10
-rw-r--r--src/main/model/asn1/exceptions/InvalidCAException.java10
-rw-r--r--src/main/model/ca/CertificationAuthority.java (renamed from src/main/model/ca/CACertificate.java)267
-rw-r--r--src/main/model/ca/Template.java53
-rw-r--r--src/main/ui/IssueScreen.java22
-rw-r--r--src/main/ui/JCA.java73
-rw-r--r--src/main/ui/MainScreen.java4
-rw-r--r--src/main/ui/MgmtScreen.java117
-rw-r--r--src/main/ui/TemplateSetScreen.java13
-rw-r--r--src/main/ui/TemplatesScreen.java17
-rw-r--r--src/main/ui/Utils.java14
-rw-r--r--src/test/model/TestConstants.java113
-rw-r--r--src/test/model/asn1/PrintableStringTest.java2
-rw-r--r--src/test/model/asn1/UTF8StringTest.java4
-rw-r--r--src/test/model/ca/CACertificateTest.java178
-rw-r--r--src/test/model/ca/CertificationAuthorityTest.java492
-rw-r--r--src/test/model/ca/TemplateTest.java55
-rw-r--r--src/test/model/csr/AttributesTest.java2
-rw-r--r--src/test/model/pki/cert/ExtensionsTest.java30
-rw-r--r--src/test/model/pki/cert/TbsCertificateTest.java3
-rw-r--r--src/test/model/pki/cert/ValidityTest.java2
-rw-r--r--src/test/ui/UtilsTest.java24
24 files changed, 956 insertions, 561 deletions
diff --git a/src/main/model/asn1/ASN1Time.java b/src/main/model/asn1/ASN1Time.java
index 8f386f5..94e58b3 100644
--- a/src/main/model/asn1/ASN1Time.java
+++ b/src/main/model/asn1/ASN1Time.java
@@ -15,7 +15,7 @@ public abstract class ASN1Time extends ASN1Object {
/**
* The time.
*/
- private ZonedDateTime timestamp;
+ private final ZonedDateTime timestamp;
/**
* EFFECTS: Initialize the time with the specific tag, parentTag, and timestamp. For tag and parentTag, consult
diff --git a/src/main/model/asn1/GeneralizedTime.java b/src/main/model/asn1/GeneralizedTime.java
index 5482906..c97a51b 100644
--- a/src/main/model/asn1/GeneralizedTime.java
+++ b/src/main/model/asn1/GeneralizedTime.java
@@ -22,7 +22,7 @@ public class GeneralizedTime extends ASN1Time {
/**
* Rather stupid impl ...
*/
- private static final DateTimeFormatter formatterNoSecs = new DateTimeFormatterBuilder()
+ private static final DateTimeFormatter FORMATTER_NO_SECS = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.DAY_OF_MONTH, 2)
@@ -32,7 +32,7 @@ public class GeneralizedTime extends ASN1Time {
.toFormatter()
.withZone(ZoneId.of("UTC"));
- private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
+ private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.DAY_OF_MONTH, 2)
@@ -71,7 +71,7 @@ public class GeneralizedTime extends ASN1Time {
@Override
public ZonedDateTime toDate(String str) throws ParseException {
try {
- return ZonedDateTime.parse(str, formatter);
+ return ZonedDateTime.parse(str, FORMATTER);
} catch (DateTimeParseException e) {
throw new ParseException(e.getMessage());
}
@@ -83,8 +83,8 @@ public class GeneralizedTime extends ASN1Time {
@Override
public String toString() {
if (getTimestamp().getSecond() == 0) {
- return getTimestamp().format(formatterNoSecs);
+ return getTimestamp().format(FORMATTER_NO_SECS);
}
- return getTimestamp().format(formatter);
+ return getTimestamp().format(FORMATTER);
}
}
diff --git a/src/main/model/asn1/UtcTime.java b/src/main/model/asn1/UtcTime.java
index 7fa93d1..54b7a5a 100644
--- a/src/main/model/asn1/UtcTime.java
+++ b/src/main/model/asn1/UtcTime.java
@@ -23,7 +23,7 @@ public class UtcTime extends ASN1Time {
/**
* Rather stupid impl ...
*/
- private static final DateTimeFormatter formatterNoSecs = new DateTimeFormatterBuilder()
+ private static final DateTimeFormatter FORMATTER_NO_SECS = new DateTimeFormatterBuilder()
.appendPattern("yy")
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.DAY_OF_MONTH, 2)
@@ -33,7 +33,7 @@ public class UtcTime extends ASN1Time {
.toFormatter()
.withZone(ZoneId.of("UTC"));
- private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
+ private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("yy")
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.DAY_OF_MONTH, 2)
@@ -72,7 +72,7 @@ public class UtcTime extends ASN1Time {
@Override
public ZonedDateTime toDate(String str) throws ParseException {
try {
- return ZonedDateTime.parse(str, formatter);
+ return ZonedDateTime.parse(str, FORMATTER);
} catch (DateTimeParseException e) {
throw new ParseException(e.getMessage());
}
@@ -84,8 +84,8 @@ public class UtcTime extends ASN1Time {
@Override
public String toString() {
if (getTimestamp().getSecond() == 0) {
- return getTimestamp().format(formatterNoSecs);
+ return getTimestamp().format(FORMATTER_NO_SECS);
}
- return getTimestamp().format(formatter);
+ return getTimestamp().format(FORMATTER);
}
}
diff --git a/src/main/model/asn1/exceptions/InvalidCAException.java b/src/main/model/asn1/exceptions/InvalidCAException.java
new file mode 100644
index 0000000..e487509
--- /dev/null
+++ b/src/main/model/asn1/exceptions/InvalidCAException.java
@@ -0,0 +1,10 @@
+package model.asn1.exceptions;
+
+/**
+ * Indicate the error that the CA being installed is invalid.
+ */
+public class InvalidCAException extends Exception {
+ public InvalidCAException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/model/ca/CACertificate.java b/src/main/model/ca/CertificationAuthority.java
index 1bd53c9..feb557c 100644
--- a/src/main/model/ca/CACertificate.java
+++ b/src/main/model/ca/CertificationAuthority.java
@@ -1,11 +1,14 @@
package model.ca;
import model.asn1.*;
+import model.asn1.exceptions.InvalidCAException;
import model.asn1.exceptions.ParseException;
+import model.asn1.parsing.BytesReader;
import model.csr.*;
import model.pki.AlgorithmIdentifier;
import model.pki.SubjectPublicKeyInfo;
import model.pki.cert.Certificate;
+import model.pki.cert.Extension;
import model.pki.cert.TbsCertificate;
import model.pki.cert.Validity;
import model.pki.crl.CertificateList;
@@ -18,23 +21,29 @@ import ui.Utils;
import java.math.BigInteger;
import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
import java.time.ZoneId;
import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
import java.util.stream.Stream;
/**
- * Holds a CA private key, its certificate, and signed / revoked list.
+ * Holds a CA private key, its certificate, signed / revoked list, template list, and logs list.
*/
-public class CACertificate {
+public class CertificationAuthority {
/**
- * The key pair.
+ * The RSA2048 private key.
*/
- private KeyPair key;
+ private RSAPrivateKey key;
+
+ /**
+ * The public key.
+ */
+ private RSAPublicKey publicKey;
/**
* The signed certificate.
@@ -44,7 +53,7 @@ public class CACertificate {
/**
* Signed certificates.
*/
- private List<Certificate> signed;
+ private final List<Certificate> signed;
/**
* The next serial number.
@@ -54,45 +63,153 @@ public class CACertificate {
/**
* Revoked certs.
*/
- private List<RevokedCertificate> revoked;
+ private final List<RevokedCertificate> revoked;
+
+ /**
+ * Certificate templates.
+ */
+ private final List<Template> templates;
+
+ /**
+ * Audit logs.
+ */
+ private final List<AuditLogEntry> logs;
+
+ /**
+ * Current operator.
+ */
+ private final String user;
/**
- * EFFECT: Init with a null key and null certificate, empty signed and revoked list, and serial at 1.
+ * EFFECT: Init with a null key and null certificate, empty signed, revoked template, and log list, serial at 1, and
+ * user "yuuta".
*/
- public CACertificate() {
+ public CertificationAuthority() {
this.key = null;
+ this.publicKey = null;
this.certificate = null;
this.serial = 1;
this.signed = new ArrayList<>();
this.revoked = new ArrayList<>();
+ this.templates = new ArrayList<>();
+ this.logs = new ArrayList<>();
+ this.user = "yuuta";
}
/**
- * EFFECTS: Generate a new RSA2048 private key.
+ * EFFECTS: Generate a new RSA2048 private key. This action will be logged.
* REQUIRES: getPublicKey() is null (i.e., no private key had been installed)
+ * MODIFIES: this
*/
public void generateKey() throws NoSuchAlgorithmException {
final KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048);
- this.key = gen.generateKeyPair();
+ final KeyPair pair = gen.generateKeyPair();
+ this.key = (RSAPrivateKey) pair.getPrivate();
+ this.publicKey = (RSAPublicKey) pair.getPublic();
+ log("Generated CA private key.");
}
/**
- * EFFECT: Install the CA certificate.
+ * EFFECTS: Load the RSA private and public exponents. This action will be logged.
+ * Throws {@link NoSuchAlgorithmException} if RSA is not available on the platform.
+ * Throws {@link InvalidKeySpecException} if the input is invalid.
+ * REQUIRES: getPublicKey() is null (i.e., no private key had been installed)
* MODIFIES: this
- * REQUIRES:
- * - The new certificate must have the same algorithm and public key as getPublicKey(), except for testing purpose
+ */
+ public void loadKey(BigInteger n, BigInteger p, BigInteger e)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ this.key = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(n, p));
+ this.publicKey =
+ (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(n, e));
+ log("Installed CA private key.");
+ }
+
+ /**
+ * EFFECTS: Throw {@link InvalidCAException} if the incoming cert is not v3.
+ */
+ private void validateCACertificateVersion(Certificate cert) throws InvalidCAException {
+ if (cert.getCertificate().getVersion() == null
+ || cert.getCertificate().getVersion().getLong() != TbsCertificate.VERSION_V3) {
+ throw new InvalidCAException("The input certificate must be V3");
+ }
+ }
+
+ /**
+ * EFFECTS: Throw {@link InvalidCAException} if the incoming cert does not have the matching public key.
+ */
+ private void validateCACertificatePublicKey(Certificate cert) throws InvalidCAException {
+ final SubjectPublicKeyInfo expectedPKInfo = 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 InvalidCAException("The input certificate does not have the corresponding public key");
+ }
+ }
+
+ /**
+ * EFFECTS: Throw {@link InvalidCAException} if the incoming cert does not have cA = true in its basicConstraints.
+ */
+ private void validateCACertificateBasicConstraints(Certificate cert) throws InvalidCAException, ParseException {
+ final Extension basicConstraints = cert.getCertificate().getExtension(ObjectIdentifier.OID_BASIC_CONSTRAINTS);
+ if (basicConstraints == null) {
+ throw new InvalidCAException("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 InvalidCAException("The certificate does not have a valid basicConstraints extension.");
+ }
+ final ASN1Object bool =
+ ASN1Object.parse(new BytesReader(basicConstraintsValue.encodeValueDER()), false);
+ if (!((Bool) bool).getValue()) {
+ throw new InvalidCAException("The certificate does not have a valid basicConstraints extension.");
+ }
+ }
+
+ /**
+ * EFFECTS: Throw {@link InvalidCAException} if the incoming cert does not have valid key usages.
+ */
+ private void validateCACertificateKeyUsage(Certificate cert) throws InvalidCAException, ParseException {
+ final Extension keyUsage = cert.getCertificate().getExtension(ObjectIdentifier.OID_KEY_USAGE);
+ if (keyUsage == null) {
+ throw new InvalidCAException("The certificate does not have a valid keyUsage extension.");
+ }
+ final ASN1Object keyUsageValue =
+ ASN1Object.parse(new BytesReader(keyUsage.getExtnValue().getBytes()), false);
+ final BitSet bitSet = BitSet.valueOf(Utils.byteToByte(((BitString) keyUsageValue).getVal()));
+ if (!bitSet.get(7) || !bitSet.get(2) || !bitSet.get(1)) {
+ throw new InvalidCAException("The certificate does not have a valid keyUsage extension.");
+ }
+ }
+
+ /**
+ * EFFECT: Install the CA certificate. Throws {@link InvalidCAException} if any of the
+ * following are violated:
* - It must be a v3 certificate
+ * - The new certificate must have the same algorithm and public key as getPublicKey()
* - It must have basicConstraints { cA = TRUE }
* - It must contain key usage Digital Signature, Certificate Sign, CRL Sign
+ * Throws {@link ParseException} if the cert has invalid extension values.
+ * This action will be logged.
+ * REQUIRES:
* - getCertificate() must be null (i.e., no certificate is installed yet).
+ * MODIFIES: this
*/
- public void installCertificate(Certificate certificate) {
+ public void installCertificate(Certificate certificate) throws InvalidCAException, ParseException {
+ validateCACertificateVersion(certificate);
+ validateCACertificatePublicKey(certificate);
+ validateCACertificateBasicConstraints(certificate);
+ validateCACertificateKeyUsage(certificate);
this.certificate = certificate;
+ log("CA certificate is installed.");
}
/**
* EFFECTS: Generate a CSR based on public key. It will have subject = CN=JCA.
+ * REQUIRES:
+ * - getCertificate() must be null (i.e., no certificate is installed yet).
*/
private CertificationRequestInfo generateCSR() throws ParseException {
return new CertificationRequestInfo(ASN1Object.TAG_SEQUENCE, null,
@@ -120,7 +237,7 @@ public class CACertificate {
}
private Byte[] getPubKeyBitStream() {
- final RSAPublicKey pub = (RSAPublicKey) key.getPublic();
+ final RSAPublicKey pub = getPublicKey();
final BigInteger exponent = pub.getPublicExponent();
byte[] modules = pub.getModulus().toByteArray();
final Int asn1Exponent = new Int(Int.TAG, null, exponent);
@@ -151,14 +268,17 @@ public class CACertificate {
/**
* EFFECT: Generate CSR and sign it, so the CA can request itself a certificate.
* REQUIRES: The CA cert must not be installed.
+ * MODIFIES: this (This action will be logged)
*/
public CertificationRequest signCSR()
throws ParseException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
final CertificationRequestInfo info = generateCSR();
- return new CertificationRequest(ASN1Object.TAG_SEQUENCE, null,
+ final CertificationRequest csr = new CertificationRequest(ASN1Object.TAG_SEQUENCE, null,
info,
getSigningAlgorithm(),
new BitString(BitString.TAG, null, 0, signBytes(info.encodeDER())));
+ log("Signed CA csr");
+ return csr;
}
/**
@@ -185,6 +305,7 @@ public class CACertificate {
new BitString(BitString.TAG, null, 0,
signBytes(newCert.encodeValueDER())));
this.signed.add(cert);
+ log("Signed a cert with serial number " + cert.getCertificate().getSerialNumber());
return cert;
}
@@ -194,7 +315,7 @@ public class CACertificate {
private Byte[] signBytes(Byte[] message)
throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
final Signature signature = Signature.getInstance("SHA256withRSA");
- signature.initSign(key.getPrivate());
+ signature.initSign(key);
signature.update(Utils.byteToByte(message));
return Utils.byteToByte(signature.sign());
}
@@ -205,6 +326,7 @@ public class CACertificate {
* - Issuer will be set to CA#getCertificate()#getSubject()
* - The template will be applied (subject, validity, cdp)
* - A serial number will be generated
+ * MODIFIES: this
*/
private TbsCertificate generateCert(CertificationRequestInfo req, Template template) {
final ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC"));
@@ -225,57 +347,134 @@ public class CACertificate {
}
/**
- * EFFECTS: Add the revocation info to revoked list.
+ * EFFECTS: Add the revocation info to revoked list. This action will be logged.
* REQUIRES: revoked should have the serial of an issued certificate; its date should be current.
* MODIFIES: this
*/
public void revoke(RevokedCertificate rev) {
revoked.add(rev);
+ log("Certificate " + rev.getSerialNumber().getLong() + " is revoked with reason " + rev.getReason());
}
/**
* EFFECTS: Generate and sign the CRL, based on getRevokedCerts(). The CSR will have current time as thisUpdate with
* no nextUptime, and it will have issuer same as the CA's subject.
* REQUIRES: The CA cert must be installed first.
+ * MODIFIES: this (This action will be logged)
*/
public CertificateList signCRL()
throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
- CertificateListContent content = new CertificateListContent(ASN1Object.TAG_SEQUENCE, null,
+ final CertificateListContent content = new CertificateListContent(ASN1Object.TAG_SEQUENCE, null,
certificate.getCertificate().getSubject(),
getSigningAlgorithm(),
new GeneralizedTime(GeneralizedTime.TAG, null, ZonedDateTime.now(ZoneId.of("UTC"))),
null,
revoked.toArray(new RevokedCertificate[0]));
- return new CertificateList(ASN1Object.TAG_SEQUENCE, null,
+ final CertificateList crl = new CertificateList(ASN1Object.TAG_SEQUENCE, null,
content,
getSigningAlgorithm(),
new BitString(BitString.TAG, null, 0,
signBytes(content.encodeValueDER())));
+ log("Signed CRL with " + revoked.size() + " revoked certs.");
+ return crl;
+ }
+
+ /**
+ * EFFECTS: Log the action with the current date and user.
+ * MODIFIES: this
+ */
+ private void log(String message) {
+ this.logs.add(new AuditLogEntry(user, ZonedDateTime.now(), message));
+ }
+
+ /**
+ * EFFECTS: Find the template based on name, or null if not found.
+ */
+ public Template findTemplate(String name, boolean requireEnabled) {
+ Optional<Template> opt = templates.stream().filter(temp -> {
+ if (requireEnabled && !temp.isEnabled()) {
+ return false;
+ }
+ return temp.getName().equals(name);
+ }).findFirst();
+ return opt.orElse(null);
+ }
+
+ /**
+ * EFFECTS: Install the new template. This action will be logged.
+ * REQUIRES: findTemplate(template.getName(), false) == null
+ * MODIFIES: this
+ */
+ public void addTemplate(Template template) {
+ this.templates.add(template);
+ log("Added a new template: " + template.getName());
+ }
+
+ /**
+ * EFFECTS: Set the given template to enabled / disabled. This action will be logged.
+ * REQUIRES: the template is valid (findTemplate does not return null)
+ * MODIFIES: this
+ */
+ public void setTemplateEnable(Template template, boolean enable) {
+ final Template t = findTemplate(template.getName(), false);
+ templates.remove(t);
+ templates.add(new Template(t.getName(), enable, t.getSubject(), t.getValidity()));
+ log("Template " + template.getName() + " has been " + (enable ? "enabled" : "disabled"));
+ }
+
+ /**
+ * EFFECTS: Remove the given template. This action will be logged.
+ * REQUIRES: the template is valid (findTemplate does not return null)
+ * MODIFIES: this
+ */
+ public void removeTemplate(Template template) {
+ templates.remove(findTemplate(template.getName(), false));
+ log("Template " + template.getName() + " is removed");
}
+ // Getters
+
public Certificate getCertificate() {
return certificate;
}
+ /**
+ * EFFECT: Get a read-only view of the signed certificates.
+ */
public List<Certificate> getSigned() {
- return signed;
+ return List.copyOf(signed);
}
/**
- * EFFECTS: Get the public key, or null if no private key is installed.
+ * EFFECT: Get a read-only view of the revoked certificates.
*/
- public PublicKey getPublicKey() {
- if (key == null) {
- return null;
- }
- return key.getPublic();
- }
-
public List<RevokedCertificate> getRevoked() {
- return revoked;
+ return List.copyOf(revoked);
}
public int getSerial() {
return serial;
}
+
+ /**
+ * EFFECT: Get a read-only view of the templates.
+ */
+ public List<Template> getTemplates() {
+ return List.copyOf(templates);
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ /**
+ * EFFECT: Get a read-only view of the logs.
+ */
+ public List<AuditLogEntry> getLogs() {
+ return List.copyOf(logs);
+ }
+
+ public RSAPublicKey getPublicKey() {
+ return publicKey;
+ }
}
diff --git a/src/main/model/ca/Template.java b/src/main/model/ca/Template.java
index af751dc..84e639e 100644
--- a/src/main/model/ca/Template.java
+++ b/src/main/model/ca/Template.java
@@ -16,22 +16,33 @@ public class Template {
/**
* Name of the template.
*/
- private String name;
+ private final String name;
/**
* Whether the template is usable or not.
*/
- private boolean enabled;
+ private final boolean enabled;
/**
* Subject of the issued certs. Null -> unspecified
*/
- private Name subject;
+ private final Name subject;
/**
* Length of validity in days since the point of issue.
*/
- private long validity;
+ private final long validity;
+
+ /**
+ * EFFECTS: Init with all given parameters, and commonName will be converted into CN=commonName,C=CA.
+ * Throws {@link ParseException} if the commonName is invalid.
+ */
+ public Template(String name,
+ boolean enabled,
+ String commonName,
+ long validity) throws ParseException {
+ this(name, enabled, parseString(commonName), validity);
+ }
/**
* EFFECTS: Init with all given parameters.
@@ -51,36 +62,24 @@ public class Template {
return name;
}
- public void setName(String name) {
- this.name = name;
- }
-
public boolean isEnabled() {
return enabled;
}
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
public Name getSubject() {
return subject;
}
- public void setSubject(Name subject) {
- this.subject = subject;
+ public long getValidity() {
+ return validity;
}
/**
- * EFFECTS: Set the subject to CN=commonName,C=CA
- * Throws {@link ParseException} if commonName is not a valid PrintableString
+ * EFFECTS: Convert the given commonName to RDN of CN=commonName,C=CA
+ * Throws {@link ParseException} if the given commonName is invalid.
*/
- public void setSubject(String commonName) throws ParseException {
- if (commonName == null) {
- this.subject = null;
- return;
- }
- setSubject(new Name(ASN1Object.TAG_SEQUENCE, null, new RelativeDistinguishedName[]{
+ private static Name parseString(String commonName) throws ParseException {
+ return new Name(ASN1Object.TAG_SEQUENCE, null, new RelativeDistinguishedName[]{
new RelativeDistinguishedName(ASN1Object.TAG_SET, null, new AttributeTypeAndValue[]{
new AttributeTypeAndValue(ASN1Object.TAG_SEQUENCE, null,
new ObjectIdentifier(ObjectIdentifier.TAG, null,
@@ -90,14 +89,6 @@ public class Template {
new AttributeTypeAndValue(ASN1Object.TAG_SEQUENCE, null,
new ObjectIdentifier(ObjectIdentifier.TAG, null,
ObjectIdentifier.OID_C),
- new PrintableString(PrintableString.TAG, null, "CA"))})}));
- }
-
- public long getValidity() {
- return validity;
- }
-
- public void setValidity(long validity) {
- this.validity = validity;
+ new PrintableString(PrintableString.TAG, null, "CA"))})});
}
}
diff --git a/src/main/ui/IssueScreen.java b/src/main/ui/IssueScreen.java
index 8376146..5e3ad50 100644
--- a/src/main/ui/IssueScreen.java
+++ b/src/main/ui/IssueScreen.java
@@ -66,7 +66,6 @@ public class IssueScreen implements UIHandler {
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());
@@ -75,11 +74,11 @@ public class IssueScreen implements UIHandler {
/**
* EFFECTS: Set or unset the subject.
- * MODIFIES: template
+ * MODIFIES: this
*/
private void handleIssueSetSubject(String val) {
try {
- template.setSubject(val);
+ template = new Template(template.getName(), template.isEnabled(), val, template.getValidity());
} catch (ParseException e) {
System.out.println(e.getMessage());
}
@@ -87,7 +86,7 @@ public class IssueScreen implements UIHandler {
/**
* EFFECTS: Set or unset the validity.
- * MODIFIES: template
+ * MODIFIES: this
*/
private void handleIssueSetValidity(String val) {
if (val == null) {
@@ -100,7 +99,7 @@ public class IssueScreen implements UIHandler {
System.out.println("Invalid validity days");
return;
}
- template.setValidity(i);
+ template = new Template(template.getName(), template.isEnabled(), template.getSubject(), i);
} catch (NumberFormatException ignored) {
System.out.println("Invalid validity days");
}
@@ -108,7 +107,7 @@ public class IssueScreen implements UIHandler {
/**
* EFFECTS: Handle the set command.
- * MODIFIES: template
+ * MODIFIES: this
*/
private void handleIssueSet(String... args) {
if (args.length != 2 && args.length != 3) {
@@ -132,13 +131,10 @@ public class IssueScreen implements UIHandler {
@Override
public void command(String... args) {
- switch (args[0]) {
- case "set":
- handleIssueSet(args);
- break;
- default:
- help();
- break;
+ if (args[0].equals("set")) {
+ handleIssueSet(args);
+ } else {
+ help();
}
}
diff --git a/src/main/ui/JCA.java b/src/main/ui/JCA.java
index 7892850..882c546 100644
--- a/src/main/ui/JCA.java
+++ b/src/main/ui/JCA.java
@@ -1,16 +1,11 @@
package ui;
import model.asn1.exceptions.ParseException;
-import model.ca.AuditLogEntry;
-import model.ca.CACertificate;
-import model.ca.Template;
+import model.ca.CertificationAuthority;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.security.spec.InvalidKeySpecException;
import java.util.Scanner;
/**
@@ -26,31 +21,19 @@ public class JCA {
private final UIHandler templatesScreen;
private final UIHandler templateSetScreen;
/**
- * Templates
- */
- private final List<Template> templates;
- /**
* The CA
*/
- private final CACertificate ca;
- /**
- * Audit logs
- */
- private final List<AuditLogEntry> logs;
- /**
- * Current user
- */
- private final String user;
+ private final CertificationAuthority ca;
/**
* The current screen.
*/
private UIHandler screen;
/**
- * EFFECTS: Init with main screen, empty templates, logs, user 'yuuta', and generate a private key with no CA cert.
+ * EFFECTS: Init with main screen and empty CA. No private key and no CA cert.
* Throws {@link NoSuchAlgorithmException} when crypto issue happens.
*/
- public JCA() throws NoSuchAlgorithmException {
+ public JCA() throws NoSuchAlgorithmException, InvalidKeySpecException {
this.mainScreen = new MainScreen(this);
this.mgmtScreen = new MgmtScreen(this);
this.issueScreen = new IssueScreen(this);
@@ -59,12 +42,7 @@ public class JCA {
setScreen(Screen.MAIN);
- this.templates = new ArrayList<>();
- this.ca = new CACertificate();
- this.logs = new ArrayList<>();
- this.user = "yuuta";
-
- this.ca.generateKey();
+ this.ca = new CertificationAuthority();
}
/**
@@ -73,10 +51,10 @@ public class JCA {
*/
public boolean checkCA(boolean requireInstalled) {
if (requireInstalled && ca.getCertificate() == null) {
- System.out.println("The CA is not installed yet");
+ System.out.println("No CA installed");
return false;
} else if (!requireInstalled && ca.getCertificate() != null) {
- System.out.println("The CA is already installed");
+ System.out.println("CA already installed");
return false;
}
return true;
@@ -101,19 +79,6 @@ public class JCA {
}
/**
- * EFFECTS: Find the template based on name, or null if not found.
- */
- public Template findTemplate(String name, boolean requireEnabled) {
- Optional<Template> opt = templates.stream().filter(temp -> {
- if (requireEnabled && !temp.isEnabled()) {
- return false;
- }
- return temp.getName().equals(name);
- }).findFirst();
- return opt.orElse(null);
- }
-
- /**
* EFFECT: Set the current screen with optional args. Exit the program when mode is null.
* MODIFIES: this
*/
@@ -143,7 +108,7 @@ public class JCA {
private void handleLine(String... args) {
if (args[0].equals("log")) {
- getLogs().forEach(System.out::println);
+ ca.getLogs().forEach(System.out::println);
return;
}
switch (args[0]) {
@@ -168,15 +133,7 @@ public class JCA {
}
private void printPS1() {
- System.out.printf("%s@JCA %s ", user, screen.getPS1());
- }
-
- /**
- * EFFECT: Log an action to the audit log
- * MODIFIES: this
- */
- public void log(String action) {
- this.logs.add(new AuditLogEntry(user, ZonedDateTime.now(), action));
+ System.out.printf("%s@JCA %s ", ca.getUser(), screen.getPS1());
}
/**
@@ -195,15 +152,7 @@ public class JCA {
}
}
- public List<Template> getTemplates() {
- return templates;
- }
-
- public CACertificate getCa() {
+ public CertificationAuthority getCa() {
return ca;
}
-
- public List<AuditLogEntry> getLogs() {
- return logs;
- }
}
diff --git a/src/main/ui/MainScreen.java b/src/main/ui/MainScreen.java
index b6e4372..2eaf882 100644
--- a/src/main/ui/MainScreen.java
+++ b/src/main/ui/MainScreen.java
@@ -86,7 +86,7 @@ public class MainScreen implements UIHandler {
System.out.println("Usage: issue <template>");
return;
}
- Template tmp = session.findTemplate(args[1], true);
+ Template tmp = session.getCa().findTemplate(args[1], true);
if (tmp == null) {
System.out.println("Cannot find the template specified");
return;
@@ -138,7 +138,6 @@ public class MainScreen implements UIHandler {
session.getCa().revoke(new RevokedCertificate(ASN1Object.TAG_SEQUENCE, null,
c.getCertificate().getSerialNumber(),
new UtcTime(UtcTime.TAG, null, ZonedDateTime.now(ZoneId.of("UTC"))), reason));
- session.log("A certificate has been revoked.");
} catch (IllegalArgumentException ignored) {
System.out.println("Illegal serial number or reason");
}
@@ -179,7 +178,6 @@ public class MainScreen implements UIHandler {
}
try {
System.out.println(Utils.toPEM(session.getCa().signCRL().encodeDER(), "X509 CRL"));
- session.log("A CRL was signed");
} catch (Throwable e) {
System.out.println(e.getMessage());
}
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;
diff --git a/src/main/ui/TemplateSetScreen.java b/src/main/ui/TemplateSetScreen.java
index 42f393b..a0b39c1 100644
--- a/src/main/ui/TemplateSetScreen.java
+++ b/src/main/ui/TemplateSetScreen.java
@@ -32,11 +32,11 @@ public class TemplateSetScreen implements UIHandler {
/**
* EFFECTS: Parse and set / unset the subject of the template
- * MODIFIES: this#template
+ * MODIFIES: this
*/
private void handleSetSubject(String val) {
try {
- template.setSubject(val);
+ template = new Template(template.getName(), template.isEnabled(), val, template.getValidity());
} catch (ParseException e) {
System.out.println(e.getMessage());
}
@@ -44,7 +44,7 @@ public class TemplateSetScreen implements UIHandler {
/**
* EFFECTS: Set the validity of the template to the given integer
- * MODIFIES: this#template
+ * MODIFIES: this
*/
private void handleSetValidity(String val) {
if (val == null) {
@@ -57,7 +57,7 @@ public class TemplateSetScreen implements UIHandler {
System.out.println("Invalid validity days");
return;
}
- template.setValidity(i);
+ template = new Template(template.getName(), template.isEnabled(), template.getSubject(), i);
} catch (NumberFormatException ignored) {
System.out.println("Invalid validity days");
}
@@ -65,7 +65,7 @@ public class TemplateSetScreen implements UIHandler {
/**
* EFFECTS: Handle the `set` command.
- * MODIFIES: this#template
+ * MODIFIES: this
*/
private void handleSet(String... args) {
if (args.length != 2 && args.length != 3) {
@@ -93,9 +93,8 @@ public class TemplateSetScreen implements UIHandler {
*/
@Override
public void commit() {
- session.getTemplates().add(template);
+ session.getCa().addTemplate(template);
session.setScreen(Screen.TEMPLATES);
- session.log("A new template is added.");
}
/**
diff --git a/src/main/ui/TemplatesScreen.java b/src/main/ui/TemplatesScreen.java
index 3bdbebe..e08df50 100644
--- a/src/main/ui/TemplatesScreen.java
+++ b/src/main/ui/TemplatesScreen.java
@@ -1,6 +1,7 @@
package ui;
import model.ca.Template;
+import model.x501.Name;
/**
* The screen that allows users to list templates and manage them.
@@ -34,7 +35,7 @@ public class TemplatesScreen implements UIHandler {
*/
@Override
public void show() {
- session.getTemplates().forEach(tem ->
+ session.getCa().getTemplates().forEach(tem ->
System.out.printf("%s[%s]\t%s\t%d Days\n",
tem.getName(),
tem.isEnabled() ? "ENABLED" : "DISABLED",
@@ -50,13 +51,13 @@ public class TemplatesScreen implements UIHandler {
System.out.println("Usage: add <name>");
return;
}
- if (session.findTemplate(args[1], false) != null) {
+ if (session.getCa().findTemplate(args[1], false) != null) {
System.out.println("The template already exists.");
return;
}
session.setScreen(Screen.TEMPLATE_SET,
- new Template(args[1], false, null, 30));
+ new Template(args[1], false, (Name) null, 30));
}
/**
@@ -68,13 +69,12 @@ public class TemplatesScreen implements UIHandler {
System.out.printf("Usage: %s <template>\n", enable ? "enable" : "disable");
return;
}
- Template tmp = session.findTemplate(args[1], false);
+ Template tmp = session.getCa().findTemplate(args[1], false);
if (tmp == null) {
System.out.println("Cannot find the template specified");
return;
}
- tmp.setEnabled(enable);
- session.log("A template was enabled / disabled.");
+ session.getCa().setTemplateEnable(tmp, enable);
}
/**
@@ -86,13 +86,12 @@ public class TemplatesScreen implements UIHandler {
System.out.println("Usage: delete <template>");
return;
}
- Template tmp = session.findTemplate(args[1], true);
+ Template tmp = session.getCa().findTemplate(args[1], true);
if (tmp == null) {
System.out.println("Cannot find the template specified");
return;
}
- session.getTemplates().remove(tmp);
- session.log("A template was deleted.");
+ session.getCa().removeTemplate(tmp);
}
/**
diff --git a/src/main/ui/Utils.java b/src/main/ui/Utils.java
index 6841536..f653ffa 100644
--- a/src/main/ui/Utils.java
+++ b/src/main/ui/Utils.java
@@ -88,14 +88,10 @@ public final class Utils {
* REQUIRES: desiredTag must be upper case and not empty.
*/
public static String toPEM(Byte[] input, String tag) {
- StringBuilder builder = new StringBuilder();
- builder.append("-----BEGIN ");
- builder.append(tag);
- builder.append("-----\n");
- builder.append(Base64.getEncoder().encodeToString(byteToByte(input)));
- builder.append("\n-----END ");
- builder.append(tag);
- builder.append("-----");
- return builder.toString();
+ return "-----BEGIN " + tag + "-----\n"
+ + Base64.getEncoder().encodeToString(byteToByte(input))
+ + "\n-----END "
+ + tag
+ + "-----";
}
}
diff --git a/src/test/model/TestConstants.java b/src/test/model/TestConstants.java
index 04a3aa7..7b2767f 100644
--- a/src/test/model/TestConstants.java
+++ b/src/test/model/TestConstants.java
@@ -150,18 +150,18 @@ public final class TestConstants {
* Signature Value:
*/
public static final String CERT_L1_ECC_PEM =
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIBrzCCAVWgAwIBAgIUcPoP+qbX9LSTBV2p0+RCqFJgs/gwCgYIKoZIzj0EAwIw\n" +
- "JTEWMBQGA1UEAwwNWXV1dGEgUm9vdCBDQTELMAkGA1UEBhMCQ0EwHhcNMjMwNjIz\n" +
- "MDI1MDQ2WhcNNDgwNjIzMDI1MDQ2WjAlMRYwFAYDVQQDDA1ZdXV0YSBSb290IENB\n" +
- "MQswCQYDVQQGEwJDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABB3ocbzdSHAm\n" +
- "cWzdBFs/Xd4UMYs/MYAYKjPlGYYT1udIL5UVOlmN7QnkUxrzYbI1YW5mX1/PCuJl\n" +
- "ZT0iKzBxLCSjYzBhMB0GA1UdDgQWBBR4kuBscPWjvgLuRLqnjNrWtUOnkzAfBgNV\n" +
- "HSMEGDAWgBR4kuBscPWjvgLuRLqnjNrWtUOnkzAPBgNVHRMBAf8EBTADAQH/MA4G\n" +
- "A1UdDwEB/wQEAwIBhjAKBggqhkjOPQQDAgNIADBFAiAJr6S6xkgxMitFmnS/0cIu\n" +
- "E7W9Ykii5d2Fe9+Lu4nL9wIhAIwHnAvZ4YzwfY6P5K4SaBwzzKPiq2zdpaXBm0lX\n" +
- "qcsz\n" +
- "-----END CERTIFICATE-----";
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIBrzCCAVWgAwIBAgIUcPoP+qbX9LSTBV2p0+RCqFJgs/gwCgYIKoZIzj0EAwIw\n"
+ + "JTEWMBQGA1UEAwwNWXV1dGEgUm9vdCBDQTELMAkGA1UEBhMCQ0EwHhcNMjMwNjIz\n"
+ + "MDI1MDQ2WhcNNDgwNjIzMDI1MDQ2WjAlMRYwFAYDVQQDDA1ZdXV0YSBSb290IENB\n"
+ + "MQswCQYDVQQGEwJDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABB3ocbzdSHAm\n"
+ + "cWzdBFs/Xd4UMYs/MYAYKjPlGYYT1udIL5UVOlmN7QnkUxrzYbI1YW5mX1/PCuJl\n"
+ + "ZT0iKzBxLCSjYzBhMB0GA1UdDgQWBBR4kuBscPWjvgLuRLqnjNrWtUOnkzAfBgNV\n"
+ + "HSMEGDAWgBR4kuBscPWjvgLuRLqnjNrWtUOnkzAPBgNVHRMBAf8EBTADAQH/MA4G\n"
+ + "A1UdDwEB/wQEAwIBhjAKBggqhkjOPQQDAgNIADBFAiAJr6S6xkgxMitFmnS/0cIu\n"
+ + "E7W9Ykii5d2Fe9+Lu4nL9wIhAIwHnAvZ4YzwfY6P5K4SaBwzzKPiq2zdpaXBm0lX\n"
+ + "qcsz\n"
+ + "-----END CERTIFICATE-----";
/**
* Certificate:
* Data:
@@ -197,31 +197,31 @@ public final class TestConstants {
* Signature Value:
*/
public static final String CERT_L2_RSA_PEM =
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIEMjCCA9mgAwIBAgIUPhCTneRXjTmH/f9Ce9plWx8hywcwCgYIKoZIzj0EAwQw\n" +
- "JTEWMBQGA1UEAwwNWXV1dGEgUm9vdCBDQTELMAkGA1UEBhMCQ0EwHhcNMjMwNjI0\n" +
- "MDAxNTIyWhcNMzMwNjIxMDAxNTIyWjBgMRMwEQYKCZImiZPyLGQBGRYDTU9FMRUw\n" +
- "EwYKCZImiZPyLGQBGRYFWVVVVEExEjAQBgoJkiaJk/IsZAEZFgJBRDEeMBwGA1UE\n" +
- "AwwVWXV1dGEgSG9tZSBJc3N1aW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\n" +
- "MIICCgKCAgEA2WTLz4X8B2XN/AiDJNsQQNMiBDjye/TfpbC3dLsUZr4BneH9EX+I\n" +
- "lKkaoJaSIXU7iXoN43FeLX5iuoq+aj4f3x+qevWySD7xLLt8gpozN5MKBdRXtaem\n" +
- "4js3Nm3YLUbjv115sddHN/3QTQXgBSUGdjyi8woL54IKdKYzB1g2Jn2Et383usMA\n" +
- "yHd3gCbwszvE5jpOgBIHxZMgMnmVAQhbQNzoEDMIkwaXmSt4jwX03oigf0KAaD+a\n" +
- "XIwQRl15iIDZnG6rRw6+eiIR8c+x1ot1/u5qncwNhRUtLbbX3QfBQ6D/XBSfrqmA\n" +
- "zhddM/i2Qt5Iw44CcLSGujFeb9ybU7NLx02EjfQsSAUGQR4VuXyD+//FsLYkh7g3\n" +
- "WmdBTWzIhVnYEU9ohTeXaZZNTp9T67czqnntFbaCdOxnwOrcmFt1v0skrHd5mHKe\n" +
- "1W3OU6XOjM6vQwcwhPUUGxAXYBcqwQ84fzD26CZz5g8I8HpnpmJ+SNtFIg+SnPOs\n" +
- "sslnsoeMZpDPESwORYgayXIWkglop1fYeD4/ictH4me70vOIHF9fWqI8ydHoNxuw\n" +
- "uZjZDa0mQgsHTmr40NhDLP/q6MEnS2w/MwHuSd3YbhbjPWFbu0Zo7XreiRkXjRLa\n" +
- "R22XkuH+FkEGB3ZxQVIkkWf1znaKQS+ZdPuTzpZph5BPL50gE58k+i0CAwEAAaOB\n" +
- "4DCB3TAdBgNVHQ4EFgQUscKngWNmS3IK3f19ICm9a0kJYcAwHwYDVR0jBBgwFoAU\n" +
- "eJLgbHD1o74C7kS6p4za1rVDp5MwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8B\n" +
- "Af8EBAMCAYYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2hvbWUueXV1dGEubW9l\n" +
- "L3BraS9yb290Y2EuY3JsMEAGCCsGAQUFBwEBBDQwMjAwBggrBgEFBQcwAoYkaHR0\n" +
- "cDovL2hvbWUueXV1dGEubW9lL3BraS9yb290Y2EuY3J0MAoGCCqGSM49BAMEA0cA\n" +
- "MEQCIHShp7SwbQ2rQC7l8u4u9rSU6Zl4DRfyor4jiHGAjm0gAiAbOHk6q+3Vm3uq\n" +
- "Jj92o1yDl09pFNIryojHMDRBpHl6yQ==\n" +
- "-----END CERTIFICATE-----";
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIEMjCCA9mgAwIBAgIUPhCTneRXjTmH/f9Ce9plWx8hywcwCgYIKoZIzj0EAwQw\n"
+ + "JTEWMBQGA1UEAwwNWXV1dGEgUm9vdCBDQTELMAkGA1UEBhMCQ0EwHhcNMjMwNjI0\n"
+ + "MDAxNTIyWhcNMzMwNjIxMDAxNTIyWjBgMRMwEQYKCZImiZPyLGQBGRYDTU9FMRUw\n"
+ + "EwYKCZImiZPyLGQBGRYFWVVVVEExEjAQBgoJkiaJk/IsZAEZFgJBRDEeMBwGA1UE\n"
+ + "AwwVWXV1dGEgSG9tZSBJc3N1aW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\n"
+ + "MIICCgKCAgEA2WTLz4X8B2XN/AiDJNsQQNMiBDjye/TfpbC3dLsUZr4BneH9EX+I\n"
+ + "lKkaoJaSIXU7iXoN43FeLX5iuoq+aj4f3x+qevWySD7xLLt8gpozN5MKBdRXtaem\n"
+ + "4js3Nm3YLUbjv115sddHN/3QTQXgBSUGdjyi8woL54IKdKYzB1g2Jn2Et383usMA\n"
+ + "yHd3gCbwszvE5jpOgBIHxZMgMnmVAQhbQNzoEDMIkwaXmSt4jwX03oigf0KAaD+a\n"
+ + "XIwQRl15iIDZnG6rRw6+eiIR8c+x1ot1/u5qncwNhRUtLbbX3QfBQ6D/XBSfrqmA\n"
+ + "zhddM/i2Qt5Iw44CcLSGujFeb9ybU7NLx02EjfQsSAUGQR4VuXyD+//FsLYkh7g3\n"
+ + "WmdBTWzIhVnYEU9ohTeXaZZNTp9T67czqnntFbaCdOxnwOrcmFt1v0skrHd5mHKe\n"
+ + "1W3OU6XOjM6vQwcwhPUUGxAXYBcqwQ84fzD26CZz5g8I8HpnpmJ+SNtFIg+SnPOs\n"
+ + "sslnsoeMZpDPESwORYgayXIWkglop1fYeD4/ictH4me70vOIHF9fWqI8ydHoNxuw\n"
+ + "uZjZDa0mQgsHTmr40NhDLP/q6MEnS2w/MwHuSd3YbhbjPWFbu0Zo7XreiRkXjRLa\n"
+ + "R22XkuH+FkEGB3ZxQVIkkWf1znaKQS+ZdPuTzpZph5BPL50gE58k+i0CAwEAAaOB\n"
+ + "4DCB3TAdBgNVHQ4EFgQUscKngWNmS3IK3f19ICm9a0kJYcAwHwYDVR0jBBgwFoAU\n"
+ + "eJLgbHD1o74C7kS6p4za1rVDp5MwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8B\n"
+ + "Af8EBAMCAYYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2hvbWUueXV1dGEubW9l\n"
+ + "L3BraS9yb290Y2EuY3JsMEAGCCsGAQUFBwEBBDQwMjAwBggrBgEFBQcwAoYkaHR0\n"
+ + "cDovL2hvbWUueXV1dGEubW9lL3BraS9yb290Y2EuY3J0MAoGCCqGSM49BAMEA0cA\n"
+ + "MEQCIHShp7SwbQ2rQC7l8u4u9rSU6Zl4DRfyor4jiHGAjm0gAiAbOHk6q+3Vm3uq\n"
+ + "Jj92o1yDl09pFNIryojHMDRBpHl6yQ==\n"
+ + "-----END CERTIFICATE-----";
/**
* Certificate:
@@ -229,7 +229,8 @@ public final class TestConstants {
* Version: 1 (0x0)
* Serial Number: 3580 (0xdfc)
* Signature Algorithm: sha1WithRSAEncryption
- * Issuer: C = JP, ST = Tokyo, L = Chuo-ku, O = Frank4DD, OU = WebCert Support, CN = Frank4DD Web CA, emailAddress = support@frank4dd.com
+ * Issuer: C = JP, ST = Tokyo, L = Chuo-ku, O = Frank4DD, OU = WebCert Support, CN = Frank4DD Web CA,
+ * emailAddress = support@frank4dd.com
* Validity
* Not Before: Aug 22 05:27:41 2012 GMT
* Not After : Aug 21 05:27:41 2017 GMT
@@ -243,24 +244,24 @@ public final class TestConstants {
* Signature Value:
*/
public static final String CERT_V1_PEM =
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n" +
- "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n" +
- "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n" +
- "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n" +
- "ODIyMDUyNzQxWhcNMTcwODIxMDUyNzQxWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n" +
- "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n" +
- "ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0z9FeMynsC8+u\n" +
- "dvX+LciZxnh5uRj4C9S6tNeeAlIGCfQYk0zUcNFCoCkTknNQd/YEiawDLNbxBqut\n" +
- "bMDZ1aarys1a0lYmUeVLCIqvzBkPJTSQsCopQQ9V8WuT252zzNzs68dVGNdCJd5J\n" +
- "NRQykpwexmnjPPv0mvj7i8XgG379TyW6P+WWV5okeUkXJ9eJS2ouDYdR2SM9BoVW\n" +
- "+FgxDu6BmXhozW5EfsnajFp7HL8kQClI0QOc79yuKl3492rH6bzFsFn2lfwWy9ic\n" +
- "7cP8EpCTeFp1tFaD+vxBhPZkeTQ1HKx6hQ5zeHIB5ySJJZ7af2W8r4eTGYzbdRW2\n" +
- "4DDHCPhZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQMv+BFvGdMVzkQaQ3/+2noVz\n" +
- "/uAKbzpEL8xTcxYyP3lkOeh4FoxiSWqy5pGFALdPONoDuYFpLhjJSZaEwuvjI/Tr\n" +
- "rGhLV1pRG9frwDFshqD2Vaj4ENBCBh6UpeBop5+285zQ4SI7q4U9oSebUDJiuOx6\n" +
- "+tZ9KynmrbJpTSi0+BM=\n" +
- "-----END CERTIFICATE-----";
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n"
+ + "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n"
+ + "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n"
+ + "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n"
+ + "ODIyMDUyNzQxWhcNMTcwODIxMDUyNzQxWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n"
+ + "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n"
+ + "ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0z9FeMynsC8+u\n"
+ + "dvX+LciZxnh5uRj4C9S6tNeeAlIGCfQYk0zUcNFCoCkTknNQd/YEiawDLNbxBqut\n"
+ + "bMDZ1aarys1a0lYmUeVLCIqvzBkPJTSQsCopQQ9V8WuT252zzNzs68dVGNdCJd5J\n"
+ + "NRQykpwexmnjPPv0mvj7i8XgG379TyW6P+WWV5okeUkXJ9eJS2ouDYdR2SM9BoVW\n"
+ + "+FgxDu6BmXhozW5EfsnajFp7HL8kQClI0QOc79yuKl3492rH6bzFsFn2lfwWy9ic\n"
+ + "7cP8EpCTeFp1tFaD+vxBhPZkeTQ1HKx6hQ5zeHIB5ySJJZ7af2W8r4eTGYzbdRW2\n"
+ + "4DDHCPhZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQMv+BFvGdMVzkQaQ3/+2noVz\n"
+ + "/uAKbzpEL8xTcxYyP3lkOeh4FoxiSWqy5pGFALdPONoDuYFpLhjJSZaEwuvjI/Tr\n"
+ + "rGhLV1pRG9frwDFshqD2Vaj4ENBCBh6UpeBop5+285zQ4SI7q4U9oSebUDJiuOx6\n"
+ + "+tZ9KynmrbJpTSi0+BM=\n"
+ + "-----END CERTIFICATE-----";
public static final Byte[] CERT_L1_ECC;
public static final Byte[] CERT_L2_RSA;
diff --git a/src/test/model/asn1/PrintableStringTest.java b/src/test/model/asn1/PrintableStringTest.java
index c6eb7b1..08f080b 100644
--- a/src/test/model/asn1/PrintableStringTest.java
+++ b/src/test/model/asn1/PrintableStringTest.java
@@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class PrintableStringTest {
- private final String ILLEGAL_CHARS_TO_TEST =
+ private static final String ILLEGAL_CHARS_TO_TEST =
"<>\\[]{}@!*&^%$#_|`~";
@Test
diff --git a/src/test/model/asn1/UTF8StringTest.java b/src/test/model/asn1/UTF8StringTest.java
index 4e879f4..f3cf085 100644
--- a/src/test/model/asn1/UTF8StringTest.java
+++ b/src/test/model/asn1/UTF8StringTest.java
@@ -18,8 +18,8 @@ public class UTF8StringTest {
@Test
void testAcceptedString() throws ParseException {
final ASN1String string =
- new UTF8String(PrintableString.TAG, null, "0123456789abCdExYz '()+,-./:=?*@" +
- String.join("", UTF8_CHARS));
+ new UTF8String(PrintableString.TAG, null, "0123456789abCdExYz '()+,-./:=?*@"
+ + String.join("", UTF8_CHARS));
assertEquals("0123456789abCdExYz '()+,-./:=?*@" + String.join("", UTF8_CHARS),
string.getString());
}
diff --git a/src/test/model/ca/CACertificateTest.java b/src/test/model/ca/CACertificateTest.java
deleted file mode 100644
index 4db7bf4..0000000
--- a/src/test/model/ca/CACertificateTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-package model.ca;
-
-import model.TestConstants;
-import model.asn1.ASN1Object;
-import model.asn1.ObjectIdentifier;
-import model.asn1.UtcTime;
-import model.asn1.parsing.BytesReader;
-import model.csr.CertificationRequest;
-import model.csr.CertificationRequestInfo;
-import model.pki.cert.Certificate;
-import model.pki.crl.Reason;
-import model.pki.crl.RevokedCertificate;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import ui.Utils;
-
-import java.nio.charset.StandardCharsets;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-public class CACertificateTest {
- private static final String CA = "-----BEGIN CERTIFICATE-----\n" +
- "MIIC3zCCAoagAwIBAgIUWcL8J0hbxGSffN0fR76j8TlGxJswCgYIKoZIzj0EAwQw\n" +
- "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMTMw\n" +
- "MTQ3MzFaFw0zMzEwMTAwMTQ3MzFaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n" +
- "hvcNAQEBBQADggEPADCCAQoCggEBAINbCR88MTUsx/poxNzXxN1aWt/DkkFrRA3r\n" +
- "dHmLXQLjopULgHIJTshSq2jDe1QEYJ0Nrj9U9YclmxkWO0HvzedmTyl0YzAhPJXj\n" +
- "HUK0T9sYSg+eE4WI03yuy7lGBJLUl9VEBR0JEZdy/mT5CRW44ryGGeeBNK3fqQrk\n" +
- "5Rm9/wY5M2cKjYmvyp5D8E+HEd+FXNreO+r9pWpKSajPn+B6OwFUUESbRf8iWiF4\n" +
- "v6ZLXDOBCEHFZcd2lTVHExuE+V3eDG3evn8HV5SB7FzRDZBV2Jz0Pfiqu2WlH4r8\n" +
- "c1804G4WCjQlSX4bPs7994+KjUoFC95r40vexi2O9mVIIEF4LtkCAwEAAaOB4DCB\n" +
- "3TAdBgNVHQ4EFgQU+c9PnChWwj4sWHFMN/dikzOS5o8wHwYDVR0jBBgwFoAUba4m\n" +
- "yCy2hdnsc6Hhw4m8dvIbit0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E\n" +
- "BAMCAYYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2hvbWUueXV1dGEubW9lL3Br\n" +
- "aS9yb290Y2EuY3JsMEAGCCsGAQUFBwEBBDQwMjAwBggrBgEFBQcwAoYkaHR0cDov\n" +
- "L2hvbWUueXV1dGEubW9lL3BraS9yb290Y2EuY3J0MAoGCCqGSM49BAMEA0cAMEQC\n" +
- "IETA9hpUnbrWpLfu2HUWr9UQC273jyg/nt30rJ96PNS+AiAsNzbKVyBpkG41Hf1/\n" +
- "+355E7vortNonvf0DDGJZjC7MA==\n" +
- "-----END CERTIFICATE-----";
-
- private static final String CSR = "-----BEGIN CERTIFICATE REQUEST-----\n" +
- "MIIEZjCCAk4CAQAwITELMAkGA1UEBhMCQ0ExEjAQBgNVBAMMCVRlc3QgTGVhZjCC\n" +
- "AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYDEoMbxZEuerV5G9IXUXfe\n" +
- "UB3u3Yf4b9QI7ewea3Vw04eS/XY4J/KC58OAKc+/3B0Vjghza1+bMalkdFHuIYls\n" +
- "/57wbmKIoRSZouma31gHJATWPdDpzcAeZVGRfqfniw3dDfVpIea5gi63gmTFGD7l\n" +
- "rmdn5BhQBijWXQY5gD52vGmnalqPBBL+HXgynYiTxmoGI/UNW16V1k8OTnT2F3kt\n" +
- "OES+5/mu2r4c7fExmkh64wXYqL2EUvh7xvd4KKIh05Bsl5J2G0Lkl1gh89FJHOVW\n" +
- "5+jrMku1wU4KBSZWNvxgcSgfKOI3IAx6iqxflhb7FKK3VTYZ7zJ/cAhaJvv1gJ7N\n" +
- "S5AlxsFxMRMgLoFtad9Qk5wH+wX+9Ozf7jNoWZQnLgzfr7CdvjBPmYR/THg0OWFS\n" +
- "0bkr20G8lMvtGMbmjN6Ot70KzYCIDjaCV5sX60i76p7rSheibgCslO49cRU7G266\n" +
- "HB1GXZNQbT3xBzoaVN9B5uQnL8tUnTn0PsQ4KN2MKIfQt+IO0yesBI7yjXRHSOJX\n" +
- "WmbZnrojfYbyAWPBKXnQ4vFcqBdXIXGuI4f67Y8BBuJjV9FOUxcCu++ypP2RtS8h\n" +
- "sly2wgtRwPCN7BbLOY9A7qm821DJ3MneHKloGodNvcBvq9VLcwFA9QFX5tgnETV8\n" +
- "4oc0VHxaiB7zuNchjINFAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEAiRKUSg4m\n" +
- "i+qozc3Nx80LfCO9b4+oWp7/bcv0fUADfet7nsobwY8Y6INYMEs6aBNnj2ofFmEd\n" +
- "Kup3VHh3vce7Grwkn0MWXKRdCbsLVJ5joWixxxbCDgiRZLYDVlhnU7ZFm3mxmC4l\n" +
- "KfKMiHfW833gnemQYRAyamDErKgPV8O9spm0TLj2nLllcA5ugR98kh9TnvnQqRdq\n" +
- "dO0ic8C2OECRPV9OVmP13qXiVJRApWYBrw+WJT+sz3LRGfQMIzaTPYWen0dd8+iG\n" +
- "HhJot7DNbdLMf6jtWXazrsmUhjjgr5KHMZdOWcbqBCRZkVTkf1HfoRbBTt/wEkBX\n" +
- "fJrXVpGbA7H7xXDXKFVUM19q7JJr9M5CfAvCtUGg/UnqfhDnqsFHgQqro21YwNQP\n" +
- "/bahU44eNoz8RUiyDEKUW9ginyd0zc3aSAkd98r5u1+tOTmU0KeIr3yc0P+tKxgB\n" +
- "bAQaKrXMlLwSHHHutEkJH2KtwKx8w66VtpYtkggfTic1ae6EoVV5LpLHIlZmRMdg\n" +
- "CDUatEdRweCdtO0TTR7ik8wMzs6GxAVDfTMaQ41Ks8OBnmLDZQTdRfssm2u6jYut\n" +
- "DQxdF5LWe8RVlkEHB2KZJg2fWZ8bjEWr3DkCvnxRlK4Tabo5/mlymjVxTRxxRoGR\n" +
- "TXU09TZASjVPzxKIyZbhgNqQvkZl2/hSCE8=\n" +
- "-----END CERTIFICATE REQUEST-----";
-
- private CACertificate ca;
-
- @BeforeEach
- void setup() {
- ca = new CACertificate();
- }
-
- @Test
- void testConstructor() {
- assertNull(ca.getPublicKey());
- assertNull(ca.getCertificate());
- assertEquals(1, ca.getSerial());
- assertEquals(0, ca.getSigned().size());
- assertEquals(0, ca.getRevoked().size());
- }
-
- @Test
- void testGenerateKey() throws Throwable {
- ca.generateKey();
- assertNotNull(ca.getPublicKey());
- }
-
- @Test
- void testInstallCertificate() throws Throwable {
- ca.generateKey();
- ca.installCertificate(new Certificate(new BytesReader(TestConstants.CERT_L2_RSA), false));
- assertNotNull(ca.getCertificate());
- }
-
- @Test
- void testSignCSR() throws Throwable {
- ca.generateKey();
- CertificationRequest req = ca.signCSR();
- assertArrayEquals(ObjectIdentifier.OID_SHA256_WITH_RSA_ENCRYPTION,
- req.getSignatureAlgorithm().getType().getInts());
- assertEquals("CN=JCA", req.getCertificationRequestInfo().getSubject().toString());
- assertArrayEquals(ObjectIdentifier.OID_RSA_ENCRYPTION, req.getCertificationRequestInfo().getSubjectPKInfo()
- .getAlgorithm().getType().getInts());
- }
-
- @Test
- void testGetCAPublicKeyInfo() throws Throwable {
- ca.generateKey();
- ca.installCertificate(new Certificate(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CA.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE")), false));
- assertArrayEquals(ObjectIdentifier.OID_RSA_ENCRYPTION,
- ca.getCAPublicKeyInfo().getAlgorithm().getType().getInts());
- }
-
- @Test
- void testSignCert() throws Throwable {
- ca.generateKey();
- ca.installCertificate(new Certificate(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CA.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE")), false));
- CertificationRequestInfo req = new CertificationRequest(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CSR.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE REQUEST")),
- false).getCertificationRequestInfo();
- Template template = new Template("123", true, null, 60);
- Certificate cert = ca.signCert(req, template);
- assertEquals(req.getSubject().toString(), cert.getCertificate().getSubject().toString());
- assertEquals(60,
- cert.getCertificate().getValidity().getNotAfter().getTimestamp().getDayOfYear()
- - cert.getCertificate().getValidity().getNotBefore().getTimestamp().getDayOfYear());
- assertEquals(1, ca.getSigned().size());
-
- template = new Template("123", true, null, 60);
- template.setSubject("Test Test");
- cert = ca.signCert(req, template);
- assertEquals(60,
- cert.getCertificate().getValidity().getNotAfter().getTimestamp().getDayOfYear()
- - cert.getCertificate().getValidity().getNotBefore().getTimestamp().getDayOfYear());
- assertEquals(template.getSubject().toString(), cert.getCertificate().getSubject().toString());
- assertEquals(2, ca.getSigned().size());
- }
-
- @Test
- void testRevoke() throws Throwable {
- ca.generateKey();
- ca.installCertificate(new Certificate(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CA.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE")), false));
- CertificationRequestInfo req = new CertificationRequest(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CSR.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE REQUEST")),
- false).getCertificationRequestInfo();
- Template template = new Template("123", true, null, 60);
- Certificate cert = ca.signCert(req, template);
- ca.revoke(new RevokedCertificate(ASN1Object.TAG_SEQUENCE, null,
- cert.getCertificate().getSerialNumber(),
- new UtcTime(UtcTime.TAG, null, ZonedDateTime.now(ZoneId.of("UTC"))),
- Reason.KEY_COMPROMISE));
- assertEquals(1, ca.getRevoked().size());
- }
-
- @Test
- void testSignCRL() throws Throwable {
- ca.generateKey();
- ca.installCertificate(new Certificate(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CA.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE")), false));
- CertificationRequestInfo req = new CertificationRequest(new BytesReader(Utils.parsePEM(
- Utils.byteToByte(CSR.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE REQUEST")),
- false).getCertificationRequestInfo();
- Template template = new Template("123", true, null, 60);
- Certificate cert = ca.signCert(req, template);
- ca.revoke(new RevokedCertificate(ASN1Object.TAG_SEQUENCE, null,
- cert.getCertificate().getSerialNumber(),
- new UtcTime(UtcTime.TAG, null, ZonedDateTime.now(ZoneId.of("UTC"))),
- Reason.KEY_COMPROMISE));
- assertEquals(1, ca.signCRL().getCrl().getRevokedCertificates().length);
- }
-}
diff --git a/src/test/model/ca/CertificationAuthorityTest.java b/src/test/model/ca/CertificationAuthorityTest.java
new file mode 100644
index 0000000..0a9a3eb
--- /dev/null
+++ b/src/test/model/ca/CertificationAuthorityTest.java
@@ -0,0 +1,492 @@
+package model.ca;
+
+import model.asn1.ASN1Object;
+import model.asn1.ObjectIdentifier;
+import model.asn1.UtcTime;
+import model.asn1.exceptions.InvalidCAException;
+import model.asn1.exceptions.ParseException;
+import model.asn1.parsing.BytesReader;
+import model.csr.CertificationRequest;
+import model.pki.cert.Certificate;
+import model.pki.crl.Reason;
+import model.pki.crl.RevokedCertificate;
+import model.x501.Name;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import ui.Utils;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class CertificationAuthorityTest {
+ // openssl genrsa -out /dev/stdout 2048 | openssl rsa -text -noout -in /dev/stdin
+ private static final BigInteger KEY_N =
+ new BigInteger("00c9fed848b2b17e39b8d1fc27216e"
+ + "06d0a10030c32c9044e4608cac5a4b"
+ + "4aa4fa2f6d78f167ae5ac565003976"
+ + "2696f05e5aa77e734e2bb3becf3b7b"
+ + "a68eff30f56997c2cb307787a54300"
+ + "326283aaf917649e5b66aa77459309"
+ + "d74a70e2e54ce8c242335d7f6e4b8b"
+ + "a70209ea65ba9ed3bce68595e19299"
+ + "5576b0f7bc62b8d1d6db4c7ba44a7a"
+ + "5f5b68321a110869fdb5649ba39683"
+ + "c291bbecf89ac951325be26dbcf449"
+ + "82677328375a4ffc3257bc0fe8a261"
+ + "021cb8b1316723b26e05cd7abd030c"
+ + "c0eb386604f9ce5eb5dac5047b7002"
+ + "b9f49e78e390c62705c609a730f5ff"
+ + "2e59f600b46dd37fff29e013c6b0cd"
+ + "4b924b365dd0b2a45f833c1fa58180"
+ + "b7d5", 16);
+
+ private static final BigInteger KEY_P =
+ new BigInteger("2e432f8270e8ad55e782324bbd008f"
+ + "cf82fc41eec57b5247f2e3ed0a6e11"
+ + "8db8de1966b8754c4dae456c587cba"
+ + "a859ab667c537df1929943737f7659"
+ + "a689044bc4b0151547c7ac79b95f67"
+ + "6ac028ad8d81c631fd50bfe9df9c02"
+ + "a2a239991634fddebf186419dcf402"
+ + "5f3969a57c692969eb6aff718f0b8e"
+ + "b315235c12492d87ad047537854adf"
+ + "8ebcc5f69c930e2f3a51f818225e64"
+ + "885431049accb474b764aeebae052d"
+ + "50a094354f2905a600fb0e3314de9c"
+ + "4f8af3afc16ae2231b09511d60ecba"
+ + "0bf5f7abaa74a0d2208b52558f2383"
+ + "85e06672280014a9d545547938606b"
+ + "947549a0ea9b6e92fa84ac42bdbe91"
+ + "86c1e428246d635aec1fc0209c0d1b"
+ + "29", 16);
+
+
+ private static final BigInteger KEY_E = new BigInteger("65537", 10);
+
+ private static final String CA_NORMAL = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICYjCCAgigAwIBAgIUHflZOHj+NxNnCdHe68pxL5ed4GowCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNjMGEw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGG\n"
+ + "MAoGCCqGSM49BAMEA0gAMEUCIEMXMU30a3M5fjhq2M2wsAe5j2d1iuRIn+mXf4BB\n"
+ + "1uVhAiEA5UynPbqF1zav4/fqPaDB3UyWArzFqi6mjXQUdHOyvXo=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_BASIC_CONSTRAINTS_NO = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICUDCCAfegAwIBAgIUIBXIjis7QbevVm8ywXyDxxGWW/4wCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNSMFAw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA4GA1UdDwEB/wQEAwIBhjAKBggqhkjOPQQDBANHADBE\n"
+ + "AiAXYbWzCQ4wjw50avMVtC0H5Z0zWxVJx0f2T1x+2g+5dQIgc8HMxFPYONLCK0hS\n"
+ + "KNBoht6VUv8UEAabNYI94Oe18J8=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_BASIC_CONSTRAINTS_WRONG = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICXzCCAgWgAwIBAgIUWMccLZPdSplt4sUkyvjdmm8YvGUwCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNgMF4w\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgGGMAoG\n"
+ + "CCqGSM49BAMEA0gAMEUCIHJD0tNitQbXoDhtfU/0QZzrQOMbGWOjoa/MVDD8sk9f\n"
+ + "AiEAqJh9gl7CqHhl+g6YpmCt07muQPYLqwg7wA9ieWDMWAo=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_BASIC_CONSTRAINTS_WRONG_1 = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICYjCCAgigAwIBAgIUWMccLZPdSplt4sUkyvjdmm8YvGUwCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNjMGEw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA8GA1UdEwEB/wQFMAMBAQAwDgYDVR0PAQH/BAQDAgGG\n"
+ + "MAoGCCqGSM49BAMEA0gAMEUCIHJD0tNitQbXoDhtfU/0QZzrQOMbGWOjoa/MVDD8\n"
+ + "sk9fAiEAqJh9gl7CqHhl+g6YpmCt07muQPYLqwg7wA9ieWDMWAo=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_KEY_USAGE_NO = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICUTCCAfigAwIBAgIUc6s/9WDXTrYkTZAnQIwKVCiugsowCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNTMFEw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwQDRwAw\n"
+ + "RAIgCYoK8MHJ4VDL5nlfn9QBu+TDNJ3pQye1P5fAVxlSjXoCIHBXQ7/GiV5boVZh\n"
+ + "+I4BMH1A7iD3T4w5Bac9JWLqjOiw\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_KEY_USAGE_WRONG_1 = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICYjCCAgigAwIBAgIUFBXd38tfIIwA3nQiNLEUellWeVwwCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNjMGEw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG\n"
+ + "MAoGCCqGSM49BAMEA0gAMEUCIQCHBeDQIUvYlFv8f/YjbDb5nNyUiH/w66VbSqDd\n"
+ + "OnQlyQIgVvvmCin5sMXFN0t90ZxlT9QtX6nXWq5nPuLNiNb/Ka8=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_KEY_USAGE_WRONG_2 = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICYjCCAgigAwIBAgIUFlQfTUXmYWgVMi8IZxP2LMztBoEwCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNjMGEw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgKE\n"
+ + "MAoGCCqGSM49BAMEA0gAMEUCIQC0wekpTe83hkgxSDs8odWWZX51bz3r0xQE7NNk\n"
+ + "PnWyZQIgDzKe0mPQg0bMlmA7JfuWKJEPNej9b94qb9dYb/u4484=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_KEY_USAGE_WRONG_3 = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICYjCCAgigAwIBAgIUEB4O3DWS3LG9+p7Dm7ERCDIsknAwCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAAaNjMGEw\n"
+ + "HQYDVR0OBBYEFKLntJQ7phJGu7A9dfIovZy6rV6SMB8GA1UdIwQYMBaAFPMn0b1s\n"
+ + "t26LXxJKvjFSvn8X1IetMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGC\n"
+ + "MAoGCCqGSM49BAMEA0gAMEUCIQCLEeyvD7Ap2ZJuNn5ElkdgT7TugBuyZu1EBAhZ\n"
+ + "emddIAIgK+h7W/SRn7IC3fgfLui9qp/Sdsdpv/x6gm/Ly6e2c8Y=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_V1 = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIB+DCCAZ4CFDLEYIlbLYpdN7KCcbYs8vWup6h5MAoGCCqGSM49BAMEMCQxFTAT\n"
+ + "BgNVBAMMDFRlc3QgUm9vdCBDQTELMAkGA1UEBhMCQ0EwHhcNMjMxMDI0MDUzMDAy\n"
+ + "WhcNMzMxMDIxMDUzMDAyWjAOMQwwCgYDVQQDEwNKQ0EwggEiMA0GCSqGSIb3DQEB\n"
+ + "AQUAA4IBDwAwggEKAoIBAQDJ/thIsrF+ObjR/CchbgbQoQAwwyyQRORgjKxaS0qk\n"
+ + "+i9tePFnrlrFZQA5diaW8F5ap35zTiuzvs87e6aO/zD1aZfCyzB3h6VDADJig6r5\n"
+ + "F2SeW2aqd0WTCddKcOLlTOjCQjNdf25Li6cCCeplup7TvOaFleGSmVV2sPe8YrjR\n"
+ + "1ttMe6RKel9baDIaEQhp/bVkm6OWg8KRu+z4mslRMlvibbz0SYJncyg3Wk/8Mle8\n"
+ + "D+iiYQIcuLExZyOybgXNer0DDMDrOGYE+c5etdrFBHtwArn0nnjjkMYnBcYJpzD1\n"
+ + "/y5Z9gC0bdN//yngE8awzUuSSzZd0LKkX4M8H6WBgLfVAgMBAAEwCgYIKoZIzj0E\n"
+ + "AwQDSAAwRQIhAL7p/tcs0GF85oepkgvbFWgadeDtL070sUZNaj+vKBsVAiBv/2Zp\n"
+ + "fd64OJmI+xefF51qrFW212UjZA7H8JY91LHKaw==\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_WRONG_KEY = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIC3zCCAoagAwIBAgIUWcL8J0hbxGSffN0fR76j8TlGxJswCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMTMw\n"
+ + "MTQ3MzFaFw0zMzEwMTAwMTQ3MzFaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAINbCR88MTUsx/poxNzXxN1aWt/DkkFrRA3r\n"
+ + "dHmLXQLjopULgHIJTshSq2jDe1QEYJ0Nrj9U9YclmxkWO0HvzedmTyl0YzAhPJXj\n"
+ + "HUK0T9sYSg+eE4WI03yuy7lGBJLUl9VEBR0JEZdy/mT5CRW44ryGGeeBNK3fqQrk\n"
+ + "5Rm9/wY5M2cKjYmvyp5D8E+HEd+FXNreO+r9pWpKSajPn+B6OwFUUESbRf8iWiF4\n"
+ + "v6ZLXDOBCEHFZcd2lTVHExuE+V3eDG3evn8HV5SB7FzRDZBV2Jz0Pfiqu2WlH4r8\n"
+ + "c1804G4WCjQlSX4bPs7994+KjUoFC95r40vexi2O9mVIIEF4LtkCAwEAAaOB4DCB\n"
+ + "3TAdBgNVHQ4EFgQU+c9PnChWwj4sWHFMN/dikzOS5o8wHwYDVR0jBBgwFoAUba4m\n"
+ + "yCy2hdnsc6Hhw4m8dvIbit0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E\n"
+ + "BAMCAYYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2hvbWUueXV1dGEubW9lL3Br\n"
+ + "aS9yb290Y2EuY3JsMEAGCCsGAQUFBwEBBDQwMjAwBggrBgEFBQcwAoYkaHR0cDov\n"
+ + "L2hvbWUueXV1dGEubW9lL3BraS9yb290Y2EuY3J0MAoGCCqGSM49BAMEA0cAMEQC\n"
+ + "IETA9hpUnbrWpLfu2HUWr9UQC273jyg/nt30rJ96PNS+AiAsNzbKVyBpkG41Hf1/\n"
+ + "+355E7vortNonvf0DDGJZjC7MA==\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_WRONG_KEY_ECC = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIBrjCCAVOgAwIBAgIUUd7mZGEF1iT9+R3K7y+M/k6P2L4wCgYIKoZIzj0EAwIw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMTMy\n"
+ + "MTI3MzdaFw00ODEwMTMyMTI3MzdaMCQxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTEL\n"
+ + "MAkGA1UEBhMCQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQjgXFX7Ul6Zmeg\n"
+ + "cTDw460HUpBTaxKFrRFJ66BbYvmAu+yoBB8Yc+pDV+qo6M5EdjwmAEeeI/BGlZ4m\n"
+ + "RfO+rfQTo2MwYTAdBgNVHQ4EFgQU8yfRvWy3botfEkq+MVK+fxfUh60wHwYDVR0j\n"
+ + "BBgwFoAU8yfRvWy3botfEkq+MVK+fxfUh60wDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n"
+ + "HQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDSQAwRgIhALFKqvFhzHPNRBWwjKho8QUL\n"
+ + "ztHOtTXmnM9BN6eS5edlAiEAm8PTq0e9a9pqwovLXtAFXlb6iuvj85pACvBdvqqJ\n"
+ + "qeQ=\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_V2 = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIB/TCCAaOgAwIBAQIUMsRgiVstil03soJxtizy9a6nqHkwCgYIKoZIzj0EAwQw\n"
+ + "JDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJDQTAeFw0yMzEwMjQw\n"
+ + "NTMwMDJaFw0zMzEwMjEwNTMwMDJaMA4xDDAKBgNVBAMTA0pDQTCCASIwDQYJKoZI\n"
+ + "hvcNAQEBBQADggEPADCCAQoCggEBAMn+2EiysX45uNH8JyFuBtChADDDLJBE5GCM\n"
+ + "rFpLSqT6L2148WeuWsVlADl2JpbwXlqnfnNOK7O+zzt7po7/MPVpl8LLMHeHpUMA\n"
+ + "MmKDqvkXZJ5bZqp3RZMJ10pw4uVM6MJCM11/bkuLpwIJ6mW6ntO85oWV4ZKZVXaw\n"
+ + "97xiuNHW20x7pEp6X1toMhoRCGn9tWSbo5aDwpG77PiayVEyW+JtvPRJgmdzKDda\n"
+ + "T/wyV7wP6KJhAhy4sTFnI7JuBc16vQMMwOs4ZgT5zl612sUEe3ACufSeeOOQxicF\n"
+ + "xgmnMPX/Lln2ALRt03//KeATxrDNS5JLNl3QsqRfgzwfpYGAt9UCAwEAATAKBggq\n"
+ + "hkjOPQQDBANIADBFAiEAvun+1yzQYXzmh6mSC9sVaBp14O0vTvSxRk1qP68oGxUC\n"
+ + "IG//Zml93rg4mYj7F58XnWqsVbbXZSNkDsfwlj3Uscpr\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CSR = "-----BEGIN CERTIFICATE REQUEST-----\n"
+ + "MIIEZjCCAk4CAQAwITELMAkGA1UEBhMCQ0ExEjAQBgNVBAMMCVRlc3QgTGVhZjCC\n"
+ + "AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYDEoMbxZEuerV5G9IXUXfe\n"
+ + "UB3u3Yf4b9QI7ewea3Vw04eS/XY4J/KC58OAKc+/3B0Vjghza1+bMalkdFHuIYls\n"
+ + "/57wbmKIoRSZouma31gHJATWPdDpzcAeZVGRfqfniw3dDfVpIea5gi63gmTFGD7l\n"
+ + "rmdn5BhQBijWXQY5gD52vGmnalqPBBL+HXgynYiTxmoGI/UNW16V1k8OTnT2F3kt\n"
+ + "OES+5/mu2r4c7fExmkh64wXYqL2EUvh7xvd4KKIh05Bsl5J2G0Lkl1gh89FJHOVW\n"
+ + "5+jrMku1wU4KBSZWNvxgcSgfKOI3IAx6iqxflhb7FKK3VTYZ7zJ/cAhaJvv1gJ7N\n"
+ + "S5AlxsFxMRMgLoFtad9Qk5wH+wX+9Ozf7jNoWZQnLgzfr7CdvjBPmYR/THg0OWFS\n"
+ + "0bkr20G8lMvtGMbmjN6Ot70KzYCIDjaCV5sX60i76p7rSheibgCslO49cRU7G266\n"
+ + "HB1GXZNQbT3xBzoaVN9B5uQnL8tUnTn0PsQ4KN2MKIfQt+IO0yesBI7yjXRHSOJX\n"
+ + "WmbZnrojfYbyAWPBKXnQ4vFcqBdXIXGuI4f67Y8BBuJjV9FOUxcCu++ypP2RtS8h\n"
+ + "sly2wgtRwPCN7BbLOY9A7qm821DJ3MneHKloGodNvcBvq9VLcwFA9QFX5tgnETV8\n"
+ + "4oc0VHxaiB7zuNchjINFAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEAiRKUSg4m\n"
+ + "i+qozc3Nx80LfCO9b4+oWp7/bcv0fUADfet7nsobwY8Y6INYMEs6aBNnj2ofFmEd\n"
+ + "Kup3VHh3vce7Grwkn0MWXKRdCbsLVJ5joWixxxbCDgiRZLYDVlhnU7ZFm3mxmC4l\n"
+ + "KfKMiHfW833gnemQYRAyamDErKgPV8O9spm0TLj2nLllcA5ugR98kh9TnvnQqRdq\n"
+ + "dO0ic8C2OECRPV9OVmP13qXiVJRApWYBrw+WJT+sz3LRGfQMIzaTPYWen0dd8+iG\n"
+ + "HhJot7DNbdLMf6jtWXazrsmUhjjgr5KHMZdOWcbqBCRZkVTkf1HfoRbBTt/wEkBX\n"
+ + "fJrXVpGbA7H7xXDXKFVUM19q7JJr9M5CfAvCtUGg/UnqfhDnqsFHgQqro21YwNQP\n"
+ + "/bahU44eNoz8RUiyDEKUW9ginyd0zc3aSAkd98r5u1+tOTmU0KeIr3yc0P+tKxgB\n"
+ + "bAQaKrXMlLwSHHHutEkJH2KtwKx8w66VtpYtkggfTic1ae6EoVV5LpLHIlZmRMdg\n"
+ + "CDUatEdRweCdtO0TTR7ik8wMzs6GxAVDfTMaQ41Ks8OBnmLDZQTdRfssm2u6jYut\n"
+ + "DQxdF5LWe8RVlkEHB2KZJg2fWZ8bjEWr3DkCvnxRlK4Tabo5/mlymjVxTRxxRoGR\n"
+ + "TXU09TZASjVPzxKIyZbhgNqQvkZl2/hSCE8=\n"
+ + "-----END CERTIFICATE REQUEST-----";
+
+ private Certificate crtNormal;
+ private Certificate crtBasicConstraintsNo;
+ private Certificate crtBasicConstraintsWrong;
+ private Certificate crtBasicConstraintsWrong1;
+ private Certificate crtKeyUsageNo;
+ private Certificate crtKeyUsageWrong1;
+ private Certificate crtKeyUsageWrong2;
+ private Certificate crtKeyUsageWrong3;
+ private Certificate crtWrongKey;
+ private Certificate crtWrongKeyECC;
+ private Certificate crtV1;
+ private Certificate crtV2;
+ private Template template;
+
+ private CertificationRequest csr;
+
+ private CertificationAuthority ca;
+
+ private CertificationAuthority caWithPrivateKey;
+
+ private static Certificate getCert(String pem) throws ParseException {
+ return new Certificate(new BytesReader(Utils.parsePEM(Utils.byteToByte(pem.getBytes(StandardCharsets.UTF_8)),
+ "CERTIFICATE")), false);
+ }
+
+ @BeforeEach
+ void setupCerts() throws Throwable {
+ crtNormal = getCert(CA_NORMAL);
+ crtBasicConstraintsNo = getCert(CA_BASIC_CONSTRAINTS_NO);
+ crtBasicConstraintsWrong = getCert(CA_BASIC_CONSTRAINTS_WRONG);
+ crtBasicConstraintsWrong1 = getCert(CA_BASIC_CONSTRAINTS_WRONG_1);
+ crtKeyUsageNo = getCert(CA_KEY_USAGE_NO);
+ crtKeyUsageWrong1 = getCert(CA_KEY_USAGE_WRONG_1);
+ crtKeyUsageWrong2 = getCert(CA_KEY_USAGE_WRONG_2);
+ crtKeyUsageWrong3 = getCert(CA_KEY_USAGE_WRONG_3);
+ crtWrongKey = getCert(CA_WRONG_KEY);
+ crtWrongKeyECC = getCert(CA_WRONG_KEY_ECC);
+ crtV1 = getCert(CA_V1);
+ crtV2 = getCert(CA_V2);
+ csr = new CertificationRequest(new BytesReader(Utils.parsePEM(
+ Utils.byteToByte(CSR.getBytes(StandardCharsets.UTF_8)), "CERTIFICATE REQUEST")),
+ false);
+ template = new Template("123", true, (Name) null, 60);
+ }
+
+ @BeforeEach
+ void setup() throws Throwable {
+ ca = new CertificationAuthority();
+ caWithPrivateKey = new CertificationAuthority();
+ caWithPrivateKey.loadKey(KEY_N, KEY_P, KEY_E);
+ }
+
+ @Test
+ void testConstructor() {
+ assertNull(ca.getPublicKey());
+ assertNull(ca.getCertificate());
+ assertEquals(1, ca.getSerial());
+ assertEquals(0, ca.getSigned().size());
+ assertEquals(0, ca.getRevoked().size());
+ assertEquals(0, ca.getTemplates().size());
+ assertEquals(0, ca.getLogs().size());
+ assertEquals("yuuta", ca.getUser());
+ }
+
+ @Test
+ void testGenerateKey() throws Throwable {
+ int logCount = ca.getLogs().size();
+ ca.generateKey();
+ assertNotNull(ca.getPublicKey());
+ assertEquals(logCount + 1, ca.getLogs().size());
+ }
+
+ @Test
+ void testInstallCertificate() throws Throwable {
+ int logCount = caWithPrivateKey.getLogs().size();
+ caWithPrivateKey.installCertificate(crtNormal);
+ assertNotNull(caWithPrivateKey.getCertificate());
+ assertEquals(logCount + 1, caWithPrivateKey.getLogs().size());
+ }
+
+ @Test
+ void testInstallCertificateFailed() {
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtBasicConstraintsNo));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtBasicConstraintsWrong));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtBasicConstraintsWrong1));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtKeyUsageNo));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtKeyUsageWrong1));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtKeyUsageWrong2));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtKeyUsageWrong3));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtWrongKey));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtWrongKeyECC));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtV1));
+ assertThrows(InvalidCAException.class, () ->
+ caWithPrivateKey.installCertificate(crtV2));
+ }
+
+ @Test
+ void testSignCSR() throws Throwable {
+ caWithPrivateKey.installCertificate(crtNormal);
+ int logCount = caWithPrivateKey.getLogs().size();
+ CertificationRequest req = caWithPrivateKey.signCSR();
+ assertArrayEquals(ObjectIdentifier.OID_SHA256_WITH_RSA_ENCRYPTION,
+ req.getSignatureAlgorithm().getType().getInts());
+ assertEquals("CN=JCA", req.getCertificationRequestInfo().getSubject().toString());
+ assertArrayEquals(ObjectIdentifier.OID_RSA_ENCRYPTION, req.getCertificationRequestInfo().getSubjectPKInfo()
+ .getAlgorithm().getType().getInts());
+ assertEquals(logCount + 1, caWithPrivateKey.getLogs().size());
+ }
+
+ @Test
+ void testGetCAPublicKeyInfo() throws Throwable {
+ caWithPrivateKey.installCertificate(crtNormal);
+ assertArrayEquals(ObjectIdentifier.OID_RSA_ENCRYPTION,
+ caWithPrivateKey.getCAPublicKeyInfo().getAlgorithm().getType().getInts());
+ }
+
+ @Test
+ void testSignCert() throws Throwable {
+ caWithPrivateKey.installCertificate(crtNormal);
+
+ int logCount = caWithPrivateKey.getLogs().size();
+
+ Certificate cert = caWithPrivateKey.signCert(csr.getCertificationRequestInfo(),
+ new Template(template.getName(), true, (Name) null, template.getValidity()));
+ assertEquals(csr.getCertificationRequestInfo().getSubject().toString(),
+ cert.getCertificate().getSubject().toString());
+ assertEquals(60,
+ cert.getCertificate().getValidity().getNotAfter().getTimestamp().getDayOfYear()
+ - cert.getCertificate().getValidity().getNotBefore().getTimestamp().getDayOfYear());
+ assertEquals(1, caWithPrivateKey.getSigned().size());
+ assertEquals(logCount + 1, caWithPrivateKey.getLogs().size());
+
+ Template tmp = new Template(template.getName(), true, "ABCC", template.getValidity());
+ cert = caWithPrivateKey.signCert(csr.getCertificationRequestInfo(), tmp);
+ assertEquals(60,
+ cert.getCertificate().getValidity().getNotAfter().getTimestamp().getDayOfYear()
+ - cert.getCertificate().getValidity().getNotBefore().getTimestamp().getDayOfYear());
+ assertEquals(tmp.getSubject().toString(), cert.getCertificate().getSubject().toString());
+ assertEquals(2, caWithPrivateKey.getSigned().size());
+ assertEquals(logCount + 2, caWithPrivateKey.getLogs().size());
+ }
+
+ @Test
+ void testRevoke() throws Throwable {
+ caWithPrivateKey.installCertificate(crtNormal);
+
+ int logCount = caWithPrivateKey.getLogs().size();
+
+ Certificate cert = caWithPrivateKey.signCert(csr.getCertificationRequestInfo(), template);
+ assertEquals(++logCount, caWithPrivateKey.getLogs().size());
+ caWithPrivateKey.revoke(new RevokedCertificate(ASN1Object.TAG_SEQUENCE, null,
+ cert.getCertificate().getSerialNumber(),
+ new UtcTime(UtcTime.TAG, null, ZonedDateTime.now(ZoneId.of("UTC"))),
+ Reason.KEY_COMPROMISE));
+ assertEquals(++logCount, caWithPrivateKey.getLogs().size());
+ assertEquals(1, caWithPrivateKey.getRevoked().size());
+ }
+
+ @Test
+ void testSignCRL() throws Throwable {
+ caWithPrivateKey.installCertificate(crtNormal);
+
+ int logCount = caWithPrivateKey.getLogs().size();
+
+ Certificate cert = caWithPrivateKey.signCert(csr.getCertificationRequestInfo(), template);
+ assertEquals(++logCount, caWithPrivateKey.getLogs().size());
+
+ caWithPrivateKey.revoke(new RevokedCertificate(ASN1Object.TAG_SEQUENCE, null,
+ cert.getCertificate().getSerialNumber(),
+ new UtcTime(UtcTime.TAG, null, ZonedDateTime.now(ZoneId.of("UTC"))),
+ Reason.KEY_COMPROMISE));
+ assertEquals(++logCount, caWithPrivateKey.getLogs().size());
+ assertEquals(1, caWithPrivateKey.signCRL().getCrl().getRevokedCertificates().length);
+ assertEquals(++logCount, caWithPrivateKey.getLogs().size());
+ }
+
+ @Test
+ void testTemplateOperations() {
+ int logCount = ca.getLogs().size();
+ assertNull(ca.findTemplate(template.getName(), false));
+
+ ca.addTemplate(template);
+ assertEquals(++logCount, ca.getLogs().size());
+ assertNotNull(ca.findTemplate(template.getName(), false));
+
+ ca.setTemplateEnable(template, false);
+ assertEquals(++logCount, ca.getLogs().size());
+ assertNull(ca.findTemplate(template.getName(), true));
+
+ ca.setTemplateEnable(template, true);
+ assertEquals(++logCount, ca.getLogs().size());
+ assertNotNull(ca.findTemplate(template.getName(), true));
+
+ ca.removeTemplate(template);
+ assertEquals(++logCount, ca.getLogs().size());
+ assertNull(ca.findTemplate(template.getName(), false));
+ }
+}
diff --git a/src/test/model/ca/TemplateTest.java b/src/test/model/ca/TemplateTest.java
index 4014599..1926078 100644
--- a/src/test/model/ca/TemplateTest.java
+++ b/src/test/model/ca/TemplateTest.java
@@ -13,48 +13,35 @@ import static org.junit.jupiter.api.Assertions.*;
public class TemplateTest {
@Test
- void testConstructor() {
- Template template = new Template("123", true, null, 123);
+ void testConstructor() throws ParseException {
+ Template template = new Template("123", true, (Name) null, 123);
assertEquals("123", template.getName());
assertTrue(template.isEnabled());
assertNull(template.getSubject());
assertEquals(123, template.getValidity());
- }
- @Test
- void testSetSubject() throws ParseException {
- Template template = new Template("123", true, null, 123);
- template.setSubject("123");
- assertEquals("CN=123,C=CA", template.getSubject().toString());
- template.setSubject((String) null);
- assertNull(template.getSubject());
- assertThrows(ParseException.class, () -> template.setSubject("*"));
+ template = new Template("123", true,
+ new Name(ASN1Object.TAG_SEQUENCE, null, new RelativeDistinguishedName[]{
+ new RelativeDistinguishedName(ASN1Object.TAG_SET, null, new AttributeTypeAndValue[]{
+ new AttributeTypeAndValue(ASN1Object.TAG_SEQUENCE, null,
+ new ObjectIdentifier(ObjectIdentifier.TAG, null,
+ ObjectIdentifier.OID_CN),
+ new PrintableString(PrintableString.TAG, null, "Test"))}),
+ new RelativeDistinguishedName(ASN1Object.TAG_SET, null, new AttributeTypeAndValue[]{
+ new AttributeTypeAndValue(ASN1Object.TAG_SEQUENCE, null,
+ new ObjectIdentifier(ObjectIdentifier.TAG, null,
+ ObjectIdentifier.OID_C),
+ new PrintableString(PrintableString.TAG, null, "CA"))})}),
+ 123);
+ assertEquals("CN=Test,C=CA", template.getSubject().toString());
}
@Test
- void testSetters() throws ParseException {
- Template template = new Template("123", true, null, 123);
-
- template.setName("114514");
- assertEquals("114514", template.getName());
-
- template.setSubject(new Name(ASN1Object.TAG_SEQUENCE, null, new RelativeDistinguishedName[]{
- new RelativeDistinguishedName(ASN1Object.TAG_SET, null, new AttributeTypeAndValue[]{
- new AttributeTypeAndValue(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null,
- ObjectIdentifier.OID_CN),
- new PrintableString(PrintableString.TAG, null, "Test"))}),
- new RelativeDistinguishedName(ASN1Object.TAG_SET, null, new AttributeTypeAndValue[]{
- new AttributeTypeAndValue(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null,
- ObjectIdentifier.OID_C),
- new PrintableString(PrintableString.TAG, null, "CA"))})}));
- assertEquals("CN=Test,C=CA", template.getSubject().toString());
-
- template.setEnabled(false);
- assertFalse(template.isEnabled());
+ void testSetSubject() throws ParseException {
+ Template template = new Template("123", true, "ABC", 123);
+ assertEquals("CN=ABC,C=CA", template.getSubject().toString());
- template.setValidity(233);
- assertEquals(233, template.getValidity());
+ assertThrows(ParseException.class, () -> new Template("123", true, "*",
+ 123));
}
}
diff --git a/src/test/model/csr/AttributesTest.java b/src/test/model/csr/AttributesTest.java
index eebdbfb..5c40a65 100644
--- a/src/test/model/csr/AttributesTest.java
+++ b/src/test/model/csr/AttributesTest.java
@@ -59,7 +59,7 @@ public class AttributesTest {
Byte[] a2 = TestConstants.CSR_ATTR_2.encodeDER();
Byte[] a1 = TestConstants.CSR_ATTR_1.encodeDER();
assertArrayEquals(
- Stream.of(Arrays.asList(new Byte[]{0x31, (byte) (a2.length + a1.length)}),
+ Stream.of(Arrays.asList((byte) 0x31, (byte) (a2.length + a1.length)),
Arrays.asList(a2),
Arrays.asList(a1))
.flatMap(Collection::stream)
diff --git a/src/test/model/pki/cert/ExtensionsTest.java b/src/test/model/pki/cert/ExtensionsTest.java
index e50b3e6..e4d9e0b 100644
--- a/src/test/model/pki/cert/ExtensionsTest.java
+++ b/src/test/model/pki/cert/ExtensionsTest.java
@@ -35,14 +35,16 @@ public class ExtensionsTest {
assertEquals(2, extensions.getExtensions().length);
assertArrayEquals(ObjectIdentifier.OID_BASIC_CONSTRAINTS, extensions.getExtensions()[0].getExtnId().getInts());
- assertArrayEquals(ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER, extensions.getExtensions()[1].getExtnId().getInts());
+ assertArrayEquals(ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER,
+ extensions.getExtensions()[1].getExtnId().getInts());
}
@Test
void testParse() throws ParseException {
final Extensions parsed = new Extensions(new BytesReader(
- Stream.of(Arrays.asList(new Byte[]{0x30,
- (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)}),
+ Stream.of(Arrays.asList((byte) 0x30,
+ (byte) (ExtensionTest.EXT_KEY_USAGE.length
+ + ExtensionTest.EXT_SUBJECT_KEY_ID.length)),
Arrays.asList(ExtensionTest.EXT_KEY_USAGE),
Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID))
.flatMap(Collection::stream)
@@ -58,8 +60,9 @@ public class ExtensionsTest {
});
assertThrows(ParseException.class, () -> {
Byte[] bytes =
- Stream.of(Arrays.asList(new Byte[]{0x30,
- (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)}),
+ Stream.of(Arrays.asList((byte) 0x30,
+ (byte) (ExtensionTest.EXT_KEY_USAGE.length
+ + ExtensionTest.EXT_SUBJECT_KEY_ID.length)),
Arrays.asList(ExtensionTest.EXT_KEY_USAGE),
Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID))
.flatMap(Collection::stream)
@@ -70,8 +73,9 @@ public class ExtensionsTest {
});
assertThrows(ParseException.class, () -> {
Byte[] bytes =
- Stream.of(Arrays.asList(new Byte[]{0x30,
- (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)}),
+ Stream.of(Arrays.asList((byte) 0x30,
+ (byte) (ExtensionTest.EXT_KEY_USAGE.length
+ + ExtensionTest.EXT_SUBJECT_KEY_ID.length)),
Arrays.asList(ExtensionTest.EXT_KEY_USAGE),
Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID))
.flatMap(Collection::stream)
@@ -85,16 +89,17 @@ public class ExtensionsTest {
@Test
void testEncode() {
assertArrayEquals(
- Stream.of(Arrays.asList(new Byte[]{0x30,
- (byte) (ExtensionTest.EXT_KEY_USAGE.length +
- ExtensionTest.EXT_SUBJECT_KEY_ID.length)}),
+ Stream.of(Arrays.asList((byte) 0x30,
+ (byte) (ExtensionTest.EXT_KEY_USAGE.length
+ + ExtensionTest.EXT_SUBJECT_KEY_ID.length)),
Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID),
Arrays.asList(ExtensionTest.EXT_KEY_USAGE))
.flatMap(Collection::stream)
.toArray(Byte[]::new),
new Extensions(ASN1Object.TAG_SEQUENCE, null, new Extension[]{
new Extension(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null, ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER),
+ new ObjectIdentifier(ObjectIdentifier.TAG, null,
+ ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER),
null,
new OctetString(OctetString.TAG, null, new Byte[]{
0x04, 0x14, -79, -62, -89, -127, 0x63, 0x66,
@@ -102,7 +107,8 @@ public class ExtensionsTest {
-67, 0x6B, 0x49, 0x09, 0x61, -64
})),
new Extension(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null, ObjectIdentifier.OID_KEY_USAGE),
+ new ObjectIdentifier(ObjectIdentifier.TAG, null,
+ ObjectIdentifier.OID_KEY_USAGE),
new Bool(Bool.TAG, null, true),
new OctetString(OctetString.TAG, null, new Byte[]{
0x03, 0x02, 0x01, -122
diff --git a/src/test/model/pki/cert/TbsCertificateTest.java b/src/test/model/pki/cert/TbsCertificateTest.java
index ee2a9c7..e778350 100644
--- a/src/test/model/pki/cert/TbsCertificateTest.java
+++ b/src/test/model/pki/cert/TbsCertificateTest.java
@@ -21,7 +21,8 @@ public class TbsCertificateTest {
void testConstructor() {
assertEquals(TbsCertificate.VERSION_V3, TestConstants.CERT_GENERATED.getVersion().getLong());
assertEquals(100, TestConstants.CERT_GENERATED.getSerialNumber().getLong());
- assertArrayEquals(ObjectIdentifier.OID_RSA_ENCRYPTION, TestConstants.CERT_GENERATED.getSignature().getType().getInts());
+ assertArrayEquals(ObjectIdentifier.OID_RSA_ENCRYPTION,
+ TestConstants.CERT_GENERATED.getSignature().getType().getInts());
assertEquals("CN=Test CA,C=CA", TestConstants.CERT_GENERATED.getIssuer().toString());
assertEquals(TestConstants.NOW, TestConstants.CERT_GENERATED.getValidity().getNotBefore().getTimestamp());
assertEquals(TestConstants.NOW.plusYears(1),
diff --git a/src/test/model/pki/cert/ValidityTest.java b/src/test/model/pki/cert/ValidityTest.java
index 2471ced..0eb60b5 100644
--- a/src/test/model/pki/cert/ValidityTest.java
+++ b/src/test/model/pki/cert/ValidityTest.java
@@ -109,7 +109,7 @@ public class ValidityTest {
final Byte[] utcBytes = utc.encodeDER();
final Byte[] genBytes = gen.encodeDER();
- assertArrayEquals(Stream.of(Arrays.asList(new Byte[]{0x30, (byte) (utcBytes.length + genBytes.length)}),
+ assertArrayEquals(Stream.of(Arrays.asList((byte) 0x30, (byte) (utcBytes.length + genBytes.length)),
Arrays.asList(utcBytes),
Arrays.asList(genBytes))
.flatMap(Collection::stream)
diff --git a/src/test/ui/UtilsTest.java b/src/test/ui/UtilsTest.java
index 0b22286..3a6c885 100644
--- a/src/test/ui/UtilsTest.java
+++ b/src/test/ui/UtilsTest.java
@@ -39,29 +39,29 @@ public class UtilsTest {
@Test
void testParsePEM() throws ParseException {
assertArrayEquals(IntStream.range(0, 48).mapToObj(i -> (byte) 1).toArray(Byte[]::new),
- Utils.parsePEM(Utils.byteToByte(("-----BEGIN BLABLA-----\n" +
- "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n" +
- "-----END BLABLA-----").getBytes(StandardCharsets.UTF_8)),
+ Utils.parsePEM(Utils.byteToByte(("-----BEGIN BLABLA-----\n"
+ + "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n"
+ + "-----END BLABLA-----").getBytes(StandardCharsets.UTF_8)),
"BLABLA"));
assertThrows(ParseException.class, () -> {
- Utils.parsePEM(Utils.byteToByte(("-----BEGIN BLABLA-----\n" +
- "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n" +
- "-----END BLABLA-----").getBytes(StandardCharsets.UTF_8)),
+ Utils.parsePEM(Utils.byteToByte(("-----BEGIN BLABLA-----\n"
+ + "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n"
+ + "-----END BLABLA-----").getBytes(StandardCharsets.UTF_8)),
"LALA");
});
assertThrows(ParseException.class, () -> {
- Utils.parsePEM(Utils.byteToByte(("-----BEGIN BLABLA-----" +
- "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB" +
- "-----END BLABLA-----").getBytes(StandardCharsets.UTF_8)),
+ Utils.parsePEM(Utils.byteToByte(("-----BEGIN BLABLA-----"
+ + "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB"
+ + "-----END BLABLA-----").getBytes(StandardCharsets.UTF_8)),
"BLABLA");
});
}
@Test
void testToPEM() {
- assertEquals("-----BEGIN ABC-----\n" +
- "AQ==\n" +
- "-----END ABC-----",
+ assertEquals("-----BEGIN ABC-----\n"
+ + "AQ==\n"
+ + "-----END ABC-----",
Utils.toPEM(new Byte[]{0x1}, "ABC"));
}
}