aboutsummaryrefslogtreecommitdiff
path: root/src/main/model/ca/CACertificate.java
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/main/model/ca/CACertificate.java
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/main/model/ca/CACertificate.java')
-rw-r--r--src/main/model/ca/CACertificate.java281
1 files changed, 0 insertions, 281 deletions
diff --git a/src/main/model/ca/CACertificate.java b/src/main/model/ca/CACertificate.java
deleted file mode 100644
index 1bd53c9..0000000
--- a/src/main/model/ca/CACertificate.java
+++ /dev/null
@@ -1,281 +0,0 @@
-package model.ca;
-
-import model.asn1.*;
-import model.asn1.exceptions.ParseException;
-import model.csr.*;
-import model.pki.AlgorithmIdentifier;
-import model.pki.SubjectPublicKeyInfo;
-import model.pki.cert.Certificate;
-import model.pki.cert.TbsCertificate;
-import model.pki.cert.Validity;
-import model.pki.crl.CertificateList;
-import model.pki.crl.CertificateListContent;
-import model.pki.crl.RevokedCertificate;
-import model.x501.AttributeTypeAndValue;
-import model.x501.Name;
-import model.x501.RelativeDistinguishedName;
-import ui.Utils;
-
-import java.math.BigInteger;
-import java.security.*;
-import java.security.interfaces.RSAPublicKey;
-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.stream.Stream;
-
-/**
- * Holds a CA private key, its certificate, and signed / revoked list.
- */
-public class CACertificate {
- /**
- * The key pair.
- */
- private KeyPair key;
-
- /**
- * The signed certificate.
- */
- private Certificate certificate;
-
- /**
- * Signed certificates.
- */
- private List<Certificate> signed;
-
- /**
- * The next serial number.
- */
- private int serial;
-
- /**
- * Revoked certs.
- */
- private List<RevokedCertificate> revoked;
-
- /**
- * EFFECT: Init with a null key and null certificate, empty signed and revoked list, and serial at 1.
- */
- public CACertificate() {
- this.key = null;
- this.certificate = null;
- this.serial = 1;
- this.signed = new ArrayList<>();
- this.revoked = new ArrayList<>();
- }
-
- /**
- * EFFECTS: Generate a new RSA2048 private key.
- * REQUIRES: getPublicKey() is null (i.e., no private key had been installed)
- */
- public void generateKey() throws NoSuchAlgorithmException {
- final KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
- gen.initialize(2048);
- this.key = gen.generateKeyPair();
- }
-
- /**
- * EFFECT: Install the CA certificate.
- * MODIFIES: this
- * REQUIRES:
- * - The new certificate must have the same algorithm and public key as getPublicKey(), except for testing purpose
- * - It must be a v3 certificate
- * - It must have basicConstraints { cA = TRUE }
- * - It must contain key usage Digital Signature, Certificate Sign, CRL Sign
- * - getCertificate() must be null (i.e., no certificate is installed yet).
- */
- public void installCertificate(Certificate certificate) {
- this.certificate = certificate;
- }
-
- /**
- * EFFECTS: Generate a CSR based on public key. It will have subject = CN=JCA.
- */
- private CertificationRequestInfo generateCSR() throws ParseException {
- return new CertificationRequestInfo(ASN1Object.TAG_SEQUENCE, null,
- new Int(Int.TAG, null, CertificationRequestInfo.VERSION_V1),
- 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, "JCA"))
- })
- }),
- getCAPublicKeyInfo(),
- new Attributes(new Tag(TagClass.CONTEXT_SPECIFIC, true, 0), // IMPLICIT
- null,
- new Attribute[]{
- new Attribute(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null,
- new Integer[]{1, 3, 6, 1, 4, 1, 311, 13, 2, 3}),
- new Values(ASN1Object.TAG_SET, null,
- new ASN1Object[]{
- new IA5String(IA5String.TAG, null,
- "10.0.20348.2")
- }))}));
- }
-
- private Byte[] getPubKeyBitStream() {
- final RSAPublicKey pub = (RSAPublicKey) key.getPublic();
- final BigInteger exponent = pub.getPublicExponent();
- byte[] modules = pub.getModulus().toByteArray();
- final Int asn1Exponent = new Int(Int.TAG, null, exponent);
- // Use OctetString to avoid leading zero issues.
- final ASN1Object asn1Modules = new OctetString(Int.TAG, null, Utils.byteToByte(modules));
- final Byte[] asn1ExponentDER = asn1Exponent.encodeDER();
- final Byte[] asn1ModulesDER = asn1Modules.encodeDER();
- return Stream.of(Arrays.asList(ASN1Object.TAG_SEQUENCE.encodeDER()),
- Arrays.asList(new ASN1Length(asn1ModulesDER.length + asn1ExponentDER.length).encodeDER()),
- Arrays.asList(asn1ModulesDER),
- Arrays.asList(asn1ExponentDER))
- .flatMap(Collection::stream)
- .toArray(Byte[]::new);
- }
-
- /**
- * EFFECTS: Encode the RSA public key into SubjectPubicKeyInfo format (BIT STRING -> SEQUENCE -> { INT INT }).
- */
- public SubjectPublicKeyInfo getCAPublicKeyInfo() {
- return new SubjectPublicKeyInfo(ASN1Object.TAG_SEQUENCE, null,
- new AlgorithmIdentifier(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null,
- ObjectIdentifier.OID_RSA_ENCRYPTION),
- new Null(Null.TAG, null)),
- new BitString(BitString.TAG, null, 0, getPubKeyBitStream()));
- }
-
- /**
- * EFFECT: Generate CSR and sign it, so the CA can request itself a certificate.
- * REQUIRES: The CA cert must not be installed.
- */
- public CertificationRequest signCSR()
- throws ParseException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
- final CertificationRequestInfo info = generateCSR();
- return new CertificationRequest(ASN1Object.TAG_SEQUENCE, null,
- info,
- getSigningAlgorithm(),
- new BitString(BitString.TAG, null, 0, signBytes(info.encodeDER())));
- }
-
- /**
- * EFFECT: Return SHA256withRSA.
- */
- private AlgorithmIdentifier getSigningAlgorithm() {
- return new AlgorithmIdentifier(ASN1Object.TAG_SEQUENCE, null,
- new ObjectIdentifier(ObjectIdentifier.TAG, null,
- ObjectIdentifier.OID_SHA256_WITH_RSA_ENCRYPTION),
- new Null(Null.TAG, null));
- }
-
- /**
- * EFFECTS: Sign the CSR based on the template.
- * REQUIRES: The CA cert must be installed first, req must have a subject, template must be enabled.
- * MODIFIES: this
- */
- public Certificate signCert(CertificationRequestInfo req, Template template)
- throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
- final TbsCertificate newCert = generateCert(req, template);
- final Certificate cert = new Certificate(ASN1Object.TAG_SEQUENCE, null,
- newCert,
- getSigningAlgorithm(),
- new BitString(BitString.TAG, null, 0,
- signBytes(newCert.encodeValueDER())));
- this.signed.add(cert);
- return cert;
- }
-
- /**
- * EFFECTS: Hash the input message with SHA256 and sign it with RSA and get the signature.
- */
- private Byte[] signBytes(Byte[] message)
- throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
- final Signature signature = Signature.getInstance("SHA256withRSA");
- signature.initSign(key.getPrivate());
- signature.update(Utils.byteToByte(message));
- return Utils.byteToByte(signature.sign());
- }
-
- /**
- * EFFECTS: Apply the template.
- * For the new certificate:
- * - Issuer will be set to CA#getCertificate()#getSubject()
- * - The template will be applied (subject, validity, cdp)
- * - A serial number will be generated
- */
- private TbsCertificate generateCert(CertificationRequestInfo req, Template template) {
- final ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC"));
- return new TbsCertificate(ASN1Object.TAG_SEQUENCE, null,
- new Int(Int.TAG, new Tag(TagClass.CONTEXT_SPECIFIC, true, 0),
- TbsCertificate.VERSION_V3),
- new Int(Int.TAG, null, serial++),
- getSigningAlgorithm(),
- certificate.getCertificate().getSubject(),
- new Validity(ASN1Object.TAG_SEQUENCE, null,
- new GeneralizedTime(GeneralizedTime.TAG, null, now),
- new UtcTime(UtcTime.TAG, null,
- now.plusDays(template.getValidity()))),
- template.getSubject() == null ? req.getSubject() :
- template.getSubject(),
- req.getSubjectPKInfo(),
- null);
- }
-
- /**
- * EFFECTS: Add the revocation info to revoked list.
- * 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);
- }
-
- /**
- * 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.
- */
- public CertificateList signCRL()
- throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
- 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,
- content,
- getSigningAlgorithm(),
- new BitString(BitString.TAG, null, 0,
- signBytes(content.encodeValueDER())));
- }
-
- public Certificate getCertificate() {
- return certificate;
- }
-
- public List<Certificate> getSigned() {
- return signed;
- }
-
- /**
- * EFFECTS: Get the public key, or null if no private key is installed.
- */
- public PublicKey getPublicKey() {
- if (key == null) {
- return null;
- }
- return key.getPublic();
- }
-
- public List<RevokedCertificate> getRevoked() {
- return revoked;
- }
-
- public int getSerial() {
- return serial;
- }
-}