package br.net.woodstock.rockframework.security.cert.impl;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.x500.X500Name;
import br.net.woodstock.rockframework.core.RockFrameworkVersion;
import br.net.woodstock.rockframework.core.util.Assert;
import br.net.woodstock.rockframework.core.util.DateBuilder;
import br.net.woodstock.rockframework.core.util.DateField;
import br.net.woodstock.rockframework.core.utils.Conditions;
import br.net.woodstock.rockframework.security.Identity;
import br.net.woodstock.rockframework.security.cert.CertificateRequest;
import br.net.woodstock.rockframework.security.cert.CertificateVersionType;
import br.net.woodstock.rockframework.security.cert.ExtendedKeyUsageType;
import br.net.woodstock.rockframework.security.cert.KeySizeType;
import br.net.woodstock.rockframework.security.cert.KeyUsageType;
import br.net.woodstock.rockframework.security.crypt.KeyPairType;
import br.net.woodstock.rockframework.security.sign.SignatureType;
import br.net.woodstock.rockframework.security.util.BouncyCastleProviderHelper;
public class BouncyCastleCertificateRequest implements Serializable {
private static final long serialVersionUID = RockFrameworkVersion.VERSION;
private static final KeySizeType DEFAULT_KEY_SIZE = KeySizeType.KEYSIZE_1K;
private long time;
private String subject;
private String email;
private KeyPair keyPair;
private SignatureType signType;
private String issuerName;
private Identity issuerIdentity;
private BigInteger serialNumber;
private Date notBefore;
private Date notAfter;
private CertificateVersionType version;
private String comment;
private String crlDistPoint;
private String ocspURL;
private String policyURL;
private boolean ca;
private String provider;
private Set<KeyUsageType> keyUsage;
private Set<ExtendedKeyUsageType> extendedKeyUsage;
private Map<String, String> otherNames;
private Map<String, String> certificatePolicies;
public BouncyCastleCertificateRequest(final CertificateRequest request) throws NoSuchAlgorithmException {
super();
Assert.notNull(request, "request");
this.time = System.currentTimeMillis();
this.subject = request.getSubject();
this.email = request.getEmail();
this.keyPair = request.getKeyPair();
this.signType = request.getSignType();
this.issuerName = request.getIssuerName();
this.issuerIdentity = request.getIssuerIdentity();
this.serialNumber = request.getSerialNumber();
this.notBefore = request.getNotBefore();
this.notAfter = request.getNotAfter();
this.version = request.getVersion();
this.comment = request.getComment();
this.crlDistPoint = request.getCrlDistPoint();
this.ocspURL = request.getOcspURL();
this.policyURL = request.getPolicyURL();
this.ca = request.isCa();
this.keyUsage = request.getKeyUsage();
this.extendedKeyUsage = request.getExtendedKeyUsage();
this.otherNames = request.getOtherNames();
this.certificatePolicies = request.getCertificatePolicies();
this.ca = request.isCa();
this.provider = request.getProvider();
if (this.keyPair == null) {
KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyPairType.RSA.getAlgorithm());
KeySizeType keySize = request.getKeySize();
if (keySize == null) {
keySize = BouncyCastleCertificateRequest.DEFAULT_KEY_SIZE;
}
generator.initialize(keySize.getSize());
this.keyPair = generator.generateKeyPair();
}
if (this.signType == null) {
this.signType = SignatureType.SHA1_RSA;
}
if (this.serialNumber == null) {
this.serialNumber = BigInteger.valueOf(this.time);
}
if (this.notBefore == null) {
DateBuilder dateBuilder = new DateBuilder(this.time);
dateBuilder.remove(DateField.DAY_OF_MONTH, 1);
this.notBefore = dateBuilder.build();
}
if (this.notAfter == null) {
DateBuilder dateBuilder = new DateBuilder(this.time);
dateBuilder.add(DateField.YEAR, 1);
this.notAfter = dateBuilder.build();
}
if (this.provider == null) {
this.provider = BouncyCastleProviderHelper.PROVIDER_NAME;
}
}
public long getTime() {
return this.time;
}
public String getSubject() {
return this.subject;
}
public String getEmail() {
return this.email;
}
public KeyPair getKeyPair() {
return this.keyPair;
}
public SignatureType getSignType() {
return this.signType;
}
public String getIssuerName() {
return this.issuerName;
}
public Identity getIssuerIdentity() {
return this.issuerIdentity;
}
public BigInteger getSerialNumber() {
return this.serialNumber;
}
public Date getNotBefore() {
return this.notBefore;
}
public Date getNotAfter() {
return this.notAfter;
}
public CertificateVersionType getVersion() {
return this.version;
}
public String getComment() {
return this.comment;
}
public String getCrlDistPoint() {
return this.crlDistPoint;
}
public String getOcspURL() {
return this.ocspURL;
}
public String getPolicyURL() {
return this.policyURL;
}
public boolean isCa() {
return this.ca;
}
public String getProvider() {
return this.provider;
}
public Set<KeyUsageType> getKeyUsage() {
return this.keyUsage;
}
public Set<ExtendedKeyUsageType> getExtendedKeyUsage() {
return this.extendedKeyUsage;
}
public Map<String, String> getOtherNames() {
return this.otherNames;
}
public Map<String, String> getCertificatePolicies() {
return this.certificatePolicies;
}
// Aux
public X500Name getIssuerAsX500Name() {
return BouncyCastleProviderHelper.toX500Name(this.getIssuerName());
}
public X500Name getSubjectAsX500Name() {
return BouncyCastleProviderHelper.toX500Name(this.getSubject());
}
public X500Principal getSubjectAsX500Principal() throws IOException {
return BouncyCastleProviderHelper.toX500Principal(this.getSubject());
}
public PublicKey getPublicKey() {
return this.getKeyPair().getPublic();
}
public PrivateKey getPrivateKey() {
return this.getKeyPair().getPrivate();
}
public String getSignAlgorithm() {
return this.getSignType().getAlgorithm();
}
public PrivateKey getIssuerPrivateKey() {
Identity identity = this.getIssuerIdentity();
if (identity != null) {
return identity.getPrivateKey();
}
return null;
}
public X509Certificate getIssuerCertificate() {
Identity identity = this.getIssuerIdentity();
if (identity != null) {
Certificate[] chain = identity.getChain();
if (Conditions.isNotEmpty(chain)) {
return (X509Certificate) chain[0];
}
}
return null;
}
}