Skip to content

Instantly share code, notes, and snippets.

@derfalx
Last active June 19, 2020 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derfalx/b2c651b3bcfc575ac37336089f1b8503 to your computer and use it in GitHub Desktop.
Save derfalx/b2c651b3bcfc575ac37336089f1b8503 to your computer and use it in GitHub Desktop.
package tech.falx.pki.task4;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.cert.HybridCertificateBuilder;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jce.X509KeyUsage;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pqc.crypto.qtesla.QTESLAContentSigner;
import org.bouncycastle.pqc.crypto.qtesla.QTESLAPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.qtesla.QTESLAPublicKeyParameters;
import org.bouncycastle.pqc.crypto.qtesla.QTESLASecurityCategory;
import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory;
import org.bouncycastle.pqc.crypto.util.PublicKeyFactory;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
import org.bouncycastle.pqc.jcajce.provider.qtesla.BCqTESLAPrivateKey;
import org.bouncycastle.pqc.jcajce.provider.qtesla.BCqTESLAPublicKey;
import org.jetbrains.annotations.NotNull;
import tech.falx.pki.CryptUtils;
import tech.falx.pki.Utils;
import javax.security.auth.x500.X500Principal;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.Calendar;
import java.util.Date;
/**
* @author falx
* @created 25.06.2019
*/
public class HybridCertGen {
@SuppressWarnings("Duplicates")
public static void main(@NotNull String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, OperatorCreationException, CertificateException {
Utils.printHeader("Task 4: Hybrid-CertGen");
// Adding the BouncyCastle-Provider so we can use it later easier
Provider provider = new BouncyCastleProvider();
Provider pqcProvider = new BouncyCastlePQCProvider();
Utils.printInfo("RSA keys to use:", args[0], args[1]);
Security.addProvider(provider);
PublicKey pubRSAKey = CryptUtils.publicKeyFromFile(args[0], "RSA", provider);
PrivateKey privRSAKey = CryptUtils.privateKeyFromFile(args[1], "RSA", provider);
Utils.printInfo("QTesla keys to use:", args[2], args[3]);
BCqTESLAPublicKey pubQTeslaKey = (BCqTESLAPublicKey) CryptUtils.publicKeyFromFile(
args[2],
"qTESLA",
pqcProvider
);
QTESLAPublicKeyParameters pubQTeslaKeyParam =(QTESLAPublicKeyParameters) PublicKeyFactory.createKey(pubQTeslaKey.getEncoded());
BCqTESLAPrivateKey privQTeslaKey = (BCqTESLAPrivateKey) CryptUtils.privateKeyFromFile(
args[3],
"qTESLA",
pqcProvider
);
QTESLAPrivateKeyParameters privQTeslaKeyParam = (QTESLAPrivateKeyParameters) PrivateKeyFactory.createKey(privQTeslaKey.getEncoded());
String distinguishedName = args[4];
Utils.printInfo("DistinguishedName to use:", distinguishedName);
boolean isCACert = args[5].equals("yes");
Utils.printInfo("This certificate is a CA-certificate:", isCACert ? "yes" : "no");
// Let's create the validity and serial
Date now = new Date(System.currentTimeMillis());
BigInteger serialNo = new BigInteger(Long.toString(now.getTime()));
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
calendar.add(Calendar.YEAR, 1);
Date endDate = calendar.getTime();
Utils.printInfo("The start date is:\n\t" + now);
Utils.printInfo("The end date is:\n\t" + endDate);
Utils.printInfo("The serial-no is:\n\t" + serialNo);
X500Principal principal = new X500Principal(distinguishedName);
HybridCertificateBuilder builder = new HybridCertificateBuilder(
principal,
serialNo,
now,
endDate,
principal,
pubRSAKey,
pubQTeslaKeyParam
);
Utils.printInfo("Adding BasicConstraint to mark the Cert as end-entity");
BasicConstraints basicConstraints = new BasicConstraints(isCACert);
builder.addExtension(Extension.basicConstraints, true, basicConstraints);
X509KeyUsage keyUsage;
if(isCACert){
Utils.printInfo("Setting keyusage to:", "keyCertSign", "cRLSign");
keyUsage = new X509KeyUsage(X509KeyUsage.keyCertSign | X509KeyUsage.cRLSign);
} else {
Utils.printInfo("Setting keyusage to:", "digitalsignature");
keyUsage = new X509KeyUsage(X509KeyUsage.digitalSignature);
}
builder.addExtension(Extension.keyUsage, true, keyUsage);
if(isCACert){
Utils.printInfo("Adding SubjectKeyIdentifier for the RSA key");
AlgorithmIdentifier sha1Identifier = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1);
DigestCalculator calculator = new BcDigestCalculatorProvider().get(sha1Identifier);
X509ExtensionUtils extensionUtils = new X509ExtensionUtils(calculator);
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(ASN1Sequence.getInstance(pubRSAKey.getEncoded()));
SubjectKeyIdentifier ski = extensionUtils.createSubjectKeyIdentifier(publicKeyInfo);
builder.addExtension(Extension.subjectKeyIdentifier, false, ski);
}
Utils.printInfo("Signing and building the hybrid-certificate");
ContentSigner rsaContentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(privRSAKey);
QTESLAContentSigner qteslaContentSigner = new QTESLAContentSigner(privQTeslaKeyParam);
X509CertificateHolder certHolder = builder.buildHybrid(rsaContentSigner, qteslaContentSigner);
X509Certificate cert = new JcaX509CertificateConverter().setProvider(provider).getCertificate(certHolder);
CryptUtils.certToPEM(args[6], cert);
}
}
/*
# ================================================
# PKI Summer Semester 2019
# - Task 4: Hybrid-CertGen
# ================================================
[+] RSA keys to use:
keys/task4/PubKeyCA_E75.pem
keys/task4/PrivKeyCA_E75.pem
[+] Reading public RSA key from keys/task4/PubKeyCA_E75.pem
[+] Reading private RSA key from keys/task4/PrivKeyCA_E75.pem
[+] QTesla keys to use:
keys/task4/pub_CA_qTesla_E75.pem
keys/task4/priv_CA_qTesla_E75.pem
[+] Reading public qTESLA key from keys/task4/pub_CA_qTesla_E75.pem
[+] Reading private qTESLA key from keys/task4/priv_CA_qTesla_E75.pem
[+] DistinguishedName to use:
CN = CA75, OU = PKI, O = C75 Inc, L = Darmstadt, ST = Hessen, C = DE
[+] This certificate is a CA-certificate:
yes
[+] The start date is:
Tue Jun 25 19:41:43 CEST 2019
[+] The end date is:
Thu Jun 25 19:41:43 CEST 2020
[+] The serial-no is:
1561484503112
[+] Adding BasicConstraint to mark the Cert as end-entity
[+] Setting keyusage to:
keyCertSign
cRLSign
[+] Adding SubjectKeyIdentifier for the RSA key
[+] Signing and building the hybrid-certificate
[+] Writing a certificate to:
keys/task4/CAcert_CA75.crt
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment