package net.lightbody.bmp.mitm;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.List;
/**
* A {@link CertificateInfoGenerator} that uses only a hostname to populate a new {@link CertificateInfo}. The
* values in the upstream server's original X.509 certificate will be ignored.
*/
public class HostnameCertificateInfoGenerator implements CertificateInfoGenerator {
/**
* The 'O' to use for the impersonated server certificate when doing "simple" certificate impersonation (i.e.
* not copying values from actual server certificate).
*/
private static final String DEFAULT_IMPERSONATED_CERT_ORG = "Impersonated Certificate";
/**
* The 'O' to use for the impersonated server certificate when doing "simple" certificate impersonation.
*/
private static final String DEFAULT_IMPERSONATED_CERT_ORG_UNIT = "LittleProxy MITM";
@Override
public CertificateInfo generate(List<String> hostnames, X509Certificate originalCertificate) {
if (hostnames == null || hostnames.size() < 1) {
throw new IllegalArgumentException("Cannot create X.509 certificate without server hostname");
}
// take the first entry as the CN
String commonName = hostnames.get(0);
return new CertificateInfo()
.commonName(commonName)
.organization(DEFAULT_IMPERSONATED_CERT_ORG)
.organizationalUnit(DEFAULT_IMPERSONATED_CERT_ORG_UNIT)
.notBefore(getNotBefore())
.notAfter(getNotAfter())
.subjectAlternativeNames(hostnames);
}
/**
* Returns the default Not Before date for impersonated certificates. Defaults to the current date minus 1 year.
*/
protected Date getNotBefore() {
return new Date(System.currentTimeMillis() - 365L * 24L * 60L * 60L * 1000L);
}
/**
* Returns the default Not After date for impersonated certificates. Defaults to the current date plus 1 year.
*/
protected Date getNotAfter() {
return new Date(System.currentTimeMillis() + 365L * 24L * 60L * 60L * 1000L);
}
}