-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
206 additions
and
0 deletions.
There are no files selected for viewing
206 changes: 206 additions & 0 deletions
206
jzlint-ca/src/main/java/de/mtg/jzlint/ca/CreateCertificate008.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
|
||
} |