I have tried running the examples from the book but most of them are deprecated by this time and require an updated version of bouncy castle. I have rewritten the certificate generation methods bellow:
Code:
/**
* Generate a sample V1 certificate to use as a CA root certificate
*/
public static X509Certificate generateRootCert(KeyPair pair) {
try {
// Pick the public-key signature algorithm to sign certificates. We are using RSA
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(X509_CERTIFICATE_SIGNATURE_ALGORITHM);
// Pick the algorithm to perform the hashing on the information to be signed. We
// sign the resulting hash
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
// Retrieve the private key which is used to sign the certificate
AsymmetricKeyParameter privateKeyAsymKeyParam = PrivateKeyFactory.createKey(pair.getPrivate().getEncoded());
// Retrieve the pulic key information used by the subject to verify
// the signature
SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded());
ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privateKeyAsymKeyParam);
// Define the validity period. The certificate may expire before the
// end date but not after.
Date startDate = new Date(System.currentTimeMillis());
Date endDate = new Date(System.currentTimeMillis() + VALIDITY_PERIOD);
X500Name name = new X500Name("CN=Root");
// Create unique serial number for the certificate (need to check if it
// it's actually unique)
BigInteger serialNum = BigInteger.valueOf(new SecureRandom().nextLong());
// Generate the actual certificate
X509v1CertificateBuilder certGen = new X509v1CertificateBuilder(name, serialNum, startDate, endDate, name, subPubKeyInfo);
// Sign it
X509CertificateHolder certificateHolder = certGen.build(sigGen);
return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certificateHolder);
}
catch (CertificateException e1) {
System.out.println("[E] Certificate exception: " + e1.toString());
log.warn("[E] Certificate exception: " + e1.toString());
}
catch (Exception e) {
System.out.println("[E] Certificate exception: " + e.toString());
log.warn("[E] Certificate exception: " + e.toString());
}
// Failed to create certificate
return null;
}
/**
* Generate a sample V3 certificate to use as an intermediate CA certificate
*/
public static X509Certificate generateIntermediateCert(PublicKey intKey, PrivateKey caKey, X509Certificate caCert) {
ASN1Sequence seq = null;
try {
seq = (ASN1Sequence) new ASN1InputStream(intKey.getEncoded()).readObject();
} catch (IOException e) {
System.out.println("[E] ASN1 sequence exception: " + e.toString());
log.warn("[E] ASN1 sequence exception: " + e.toString());
}
SubjectPublicKeyInfo parentPubKeyInfo = new SubjectPublicKeyInfo(seq);
// Define the validity period. The certificate may expire before the
// end date but not after.
Date startDate = new Date(System.currentTimeMillis());
Date endDate = new Date(System.currentTimeMillis() + VALIDITY_PERIOD);
ContentSigner signer = null;
try {
signer = new JcaContentSignerBuilder(X509_CERTIFICATE_SIGNATURE_ALGORITHM).build(caKey);
} catch (OperatorCreationException e) {
System.out.println("[E] ASN1 sequence exception: " + e.toString());
log.warn("[E] ASN1 sequence exception: " + e.toString());
}
// Create unique serial number for the certificate (need to check if it
// it's actually unique)
BigInteger serialNum = BigInteger.valueOf(new SecureRandom().nextLong());
X509v3CertificateBuilder certGen = null;
try {
certGen = new JcaX509v3CertificateBuilder(
caCert,
serialNum,
startDate,
endDate,
new X500Principal("CN=Intermediate Certificate"),
intKey)
.addExtension(
new ASN1ObjectIdentifier("2.5.29.35"),
false,
new AuthorityKeyIdentifier(parentPubKeyInfo))
.addExtension(
new ASN1ObjectIdentifier("2.5.29.19"),
false,
new BasicConstraints(false)) // true if it is allowed to sign other certs
.addExtension(
new ASN1ObjectIdentifier("2.5.29.15"),
true,
new X509KeyUsage(
X509KeyUsage.digitalSignature |
X509KeyUsage.nonRepudiation |
X509KeyUsage.keyEncipherment |
X509KeyUsage.dataEncipherment));
} catch (CertIOException e) {
System.out.println("[E] Certificate builder exception: " + e.toString());
log.warn("[E] Certificate builder exception: " + e.toString());
}
// Build/sign the certificate.
X509CertificateHolder certHolder = certGen.build(signer);
try {
X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
return cert;
} catch (CertificateException e) {
System.out.println("[E] Certificate build exception: " + e.toString());
log.warn("[E] Certificate build exception: " + e.toString());
}
return null;
}
/**
* Generate a sample V3 certificate to use as an end entity certificate
*/
public static X509Certificate generateEndEntityCert(PublicKey entityKey, PrivateKey caKey, X509Certificate caCert) {
ASN1Sequence seq = null;
try {
seq = (ASN1Sequence) new ASN1InputStream(entityKey.getEncoded()).readObject();
} catch (IOException e) {
System.out.println("[E] ASN1 sequence exception: " + e.toString());
log.warn("[E] ASN1 sequence exception: " + e.toString());
}
SubjectPublicKeyInfo parentPubKeyInfo = new SubjectPublicKeyInfo(seq);
// Define the validity period. The certificate may expire before the
// end date but not after.
Date startDate = new Date(System.currentTimeMillis());
Date endDate = new Date(System.currentTimeMillis() + VALIDITY_PERIOD);
ContentSigner signer = null;
try {
signer = new JcaContentSignerBuilder(X509_CERTIFICATE_SIGNATURE_ALGORITHM).build(caKey);
} catch (OperatorCreationException e) {
System.out.println("[E] ASN1 sequence exception: " + e.toString());
log.warn("[E] ASN1 sequence exception: " + e.toString());
}
// Create unique serial number for the certificate (need to check if it
// it's actually unique)
BigInteger serialNum = BigInteger.valueOf(new SecureRandom().nextLong());
X509v3CertificateBuilder certGen = null;
try {
certGen = new JcaX509v3CertificateBuilder(
caCert,
serialNum,
startDate,
endDate,
new X500Principal("CN=End Certificate"),
entityKey)
.addExtension(
new ASN1ObjectIdentifier("2.5.29.35"),
false,
new AuthorityKeyIdentifier(parentPubKeyInfo))
.addExtension(
new ASN1ObjectIdentifier("2.5.29.19"),
false,
new BasicConstraints(false)) // true if it is allowed to sign other certs
.addExtension(
new ASN1ObjectIdentifier("2.5.29.15"),
true,
new X509KeyUsage(
X509KeyUsage.digitalSignature |
X509KeyUsage.nonRepudiation |
X509KeyUsage.keyEncipherment |
X509KeyUsage.keyCertSign |
X509KeyUsage.cRLSign |
X509KeyUsage.dataEncipherment));
} catch (CertIOException e) {
System.out.println("[E] Certificate builder exception: " + e.toString());
log.warn("[E] Certificate builder exception: " + e.toString());
}
// Build/sign the certificate.
X509CertificateHolder certHolder = certGen.build(signer);
try {
X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
return cert;
} catch (CertificateException e) {
System.out.println("[E] Certificate build exception: " + e.toString());
log.warn("[E] Certificate build exception: " + e.toString());
}
return null;
}
/**
* Generate a X500PrivateCredential for the root entity.
*/
public static X500PrivateCredential createRootCredential()
throws Exception {
KeyPair rootPair = generateRSAKeyPair();
X509Certificate rootCert = generateRootCert(rootPair);
return new X500PrivateCredential(rootCert, rootPair.getPrivate(), ROOT_ALIAS);
}
/**
* Generate a X500PrivateCredential for the intermediate entity.
*/
public static X500PrivateCredential createIntermediateCredential(
PrivateKey caKey,
X509Certificate caCert)
throws Exception {
KeyPair interPair = generateRSAKeyPair();
X509Certificate interCert = generateIntermediateCert(interPair.getPublic(), caKey, caCert);
return new X500PrivateCredential(interCert, interPair.getPrivate(), INTERMEDIATE_ALIAS);
}
/**
* Generate a X500PrivateCredential for the end entity.
*/
public static X500PrivateCredential createEndEntityCredential(
PrivateKey caKey,
X509Certificate caCert)
throws Exception {
KeyPair endPair = generateRSAKeyPair();
X509Certificate endCert = generateEndEntityCert(endPair.getPublic(), caKey, caCert);
return new X500PrivateCredential(endCert, endPair.getPrivate(), END_ENTITY_ALIAS);
}
Are the new procedures valid?
The code that has been modified is located in the
Utils.java file in chapter 9 (the methods have the same contract).
Many thanks in advance.