Set<X509ExtensionWrapper> extensions, Set<X509ByteExtensionWrapper> byteExtensions,
Date startDate, Date endDate,
KeyPair clientKeyPair, BigInteger serialNumber, String alternateName)
throws GeneralSecurityException, IOException {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
X509Certificate caCert = reader.getCACert();
// set cert fields
certGen.setSerialNumber(serialNumber);
certGen.setIssuerDN(caCert.getSubjectX500Principal());
certGen.setNotBefore(startDate);
certGen.setNotAfter(endDate);
X500Principal subjectPrincipal = new X500Principal(dn);
certGen.setSubjectDN(subjectPrincipal);
certGen.setPublicKey(clientKeyPair.getPublic());
certGen.setSignatureAlgorithm(SIGNATURE_ALGO);
// set key usage - required for proper x509 function
KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature |
KeyUsage.keyEncipherment | KeyUsage.dataEncipherment);
// add SSL extensions - required for proper x509 function
NetscapeCertType certType = new NetscapeCertType(
NetscapeCertType.sslClient | NetscapeCertType.smime);
certGen.addExtension(MiscObjectIdentifiers.netscapeCertType.toString(),
false, certType);
certGen.addExtension(X509Extensions.KeyUsage.toString(), false,
keyUsage);
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
new AuthorityKeyIdentifierStructure(caCert));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
subjectKeyWriter.getSubjectKeyIdentifier(clientKeyPair, extensions));
certGen.addExtension(X509Extensions.ExtendedKeyUsage, false,
new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
// Add an alternate name if provided
if (alternateName != null) {
GeneralName name = new GeneralName(GeneralName.uniformResourceIdentifier,
"CN=" + alternateName);
certGen.addExtension(X509Extensions.SubjectAlternativeName, false,
new GeneralNames(name));
}
if (extensions != null) {
for (X509ExtensionWrapper wrapper : extensions) {
// Bouncycastle hates null values. So, set them to blank
// if they are null
String value = wrapper.getValue() == null ? "" : wrapper.getValue();
certGen.addExtension(wrapper.getOid(), wrapper.isCritical(),
new DERUTF8String(value));
}
}
if (byteExtensions != null) {
for (X509ByteExtensionWrapper wrapper : byteExtensions) {
// Bouncycastle hates null values. So, set them to blank
// if they are null
byte[] value = wrapper.getValue() == null ? new byte[0] :
wrapper.getValue();
certGen.addExtension(wrapper.getOid(), wrapper.isCritical(),
new DEROctetString(value));
}
}
// Generate the certificate
return certGen.generate(reader.getCaKey());
}