Skip to content

Commit

Permalink
added
Browse files Browse the repository at this point in the history
  • Loading branch information
mtgag committed Jun 8, 2024
1 parent 1afdacc commit e150e6b
Showing 1 changed file with 206 additions and 0 deletions.
206 changes: 206 additions & 0 deletions jzlint-ca/src/main/java/de/mtg/jzlint/ca/CreateCertificate008.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package de.mtg.jzlint.ca;

import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;


/**
* Certificates for lint: e_aia_ca_issuers_must_have_http_only
*/
public class CreateCertificate008 {

public static final String SHA_256_WITH_ECDSA = "SHA256WithECDSA";

public static void main(String[] args) throws Exception {

Security.addProvider(new BouncyCastleProvider());

X500Name caIssuerDN = new X500Name("CN=Lint CA, O=Lint, C=DE");

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
AlgorithmParameterSpec algParSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
keyPairGenerator.initialize(algParSpec);

KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();

ZonedDateTime notBefore = ZonedDateTime.of(2023, 9, 15, 0, 0, 0, 0, ZoneId.of("UTC"));

{
String name = "aiaCaIssuersHTTPOnly";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate = createTestCertificate(privateKey, caIssuerDN, notBefore, "http://ocsp.example.com/ocsp");

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));
}

{
String name = "aiaCaIssuersHTTPAndLDAP";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate =
createTestCertificate(privateKey, caIssuerDN, notBefore, "http://issuers.example.com/ca", "ldap://issuers.example.com/");

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));
}

{
String name = "aiaCaIssuersLDAPOnly";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate = createTestCertificate(privateKey, caIssuerDN, notBefore, "ldap://issuers.example.com/");

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));
}

{
String name = "aiaCaIssuersFTPOnly";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate = createTestCertificate(privateKey, caIssuerDN, notBefore, "ftp://issuers.example.com/");

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));
}

{
ZonedDateTime notBeforeNE = ZonedDateTime.of(2023, 9, 14, 23, 59, 59, 0, ZoneId.of("UTC"));
String name = "aiaCaIssuersHttpOnlyNE";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate = createTestCertificate(privateKey, caIssuerDN, notBeforeNE, "http://issuers.example.com/");

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));
}

{
String name = "aiaCaIssuersHttpOnlyNoCAIssuers";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate = createTestCertificate(privateKey, caIssuerDN, notBefore, null);

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));
}


{
String name = "aiaCaIssuersHttpsOnly";
String nameDER = String.format("%s.der", name);
String namePEM = String.format("%s.pem", name);
X509Certificate testCertificate = createTestCertificate(privateKey, caIssuerDN, notBefore, "https://ocsp.example.com/ocsp");

Files.write(Paths.get(nameDER), testCertificate.getEncoded());

System.out.println(String.format("openssl x509 -inform DER -outform PEM -in %s -out %s -text", nameDER, namePEM));

}


}

/**
* For lint_aia_ca_issuers_must_have_http_only
*/
private static X509Certificate createTestCertificate(PrivateKey caPrivateKey, X500Name issuerDN, ZonedDateTime notBefore, String... uris)
throws Exception {

BigInteger serialNumber = new BigInteger(96, new Random());

Date notBeforeDate = Date.from(notBefore.toInstant());
Date noteAfterDate = Date.from(notBefore.plusYears(1).toInstant());

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
AlgorithmParameterSpec algParSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
keyPairGenerator.initialize(algParSpec);

KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());

Extension certificatePolicies = getCertificatePolicies("2.23.140.1.2.1");

X509v3CertificateBuilder certificateBuilder =
new X509v3CertificateBuilder(issuerDN, serialNumber, notBeforeDate, noteAfterDate, new X500Name(""),
subjectPublicKeyInfo);
certificateBuilder.addExtension(certificatePolicies);

if (uris == null) {
AccessDescription[] accessDescriptions = new AccessDescription[1];

GeneralName generalName = new GeneralName(GeneralName.uniformResourceIdentifier, "http://ocsp.example.com/ocsp");
AccessDescription accessDescription = new AccessDescription(AccessDescription.id_ad_ocsp, generalName);
accessDescriptions[0] = accessDescription;

AuthorityInformationAccess authorityInformationAccess = new AuthorityInformationAccess(accessDescriptions);
byte[] encodedExtension = authorityInformationAccess.toASN1Primitive().getEncoded(ASN1Encoding.DER);
Extension aia = new Extension(Extension.authorityInfoAccess, false, encodedExtension);
certificateBuilder.addExtension(aia);
} else {
Extension aia = getAuthorityInformationAccess(uris);
certificateBuilder.addExtension(aia);
}

JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(SHA_256_WITH_ECDSA);
ContentSigner contentSigner = jcaContentSignerBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(caPrivateKey);
X509CertificateHolder x509CertificateHolder = certificateBuilder.build(contentSigner);

return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(x509CertificateHolder);
}

private static Extension getAuthorityInformationAccess(String[] uris) throws IOException {
AccessDescription[] accessDescriptions = new AccessDescription[uris.length];
int counter = 0;
for (String uri : uris) {
GeneralName generalName = new GeneralName(GeneralName.uniformResourceIdentifier, uri);
AccessDescription accessDescription = new AccessDescription(AccessDescription.id_ad_caIssuers, generalName);
accessDescriptions[counter] = accessDescription;
counter = counter + 1;
}
AuthorityInformationAccess authorityInformationAccess = new AuthorityInformationAccess(accessDescriptions);
return new Extension(Extension.authorityInfoAccess, false, authorityInformationAccess.toASN1Primitive().getEncoded(ASN1Encoding.DER));
}

private static Extension getCertificatePolicies(String policyOID) throws IOException {
PolicyInformation[] policies = new PolicyInformation[1];
List<PolicyInformation> policiesList = new ArrayList<>();
PolicyInformation policyInformation = new PolicyInformation(new ASN1ObjectIdentifier(policyOID));
policiesList.add(policyInformation);
CertificatePolicies cps = new CertificatePolicies(policiesList.toArray(policies));
return new Extension(Extension.certificatePolicies, false, cps.toASN1Primitive().getEncoded(ASN1Encoding.DER));
}

}

0 comments on commit e150e6b

Please sign in to comment.