Search in sources :

Example 1 with LetsEncryptCertificateEntity

use of com.peterphi.servicemanager.service.db.entity.LetsEncryptCertificateEntity in project stdlib by petergeneric.

the class ServiceManagerHostnameRestServiceImpl method allocateHostname.

@Override
public HostnameResponseDTO allocateHostname(final HostnameRequestDTO request) {
    // Validate the IP address
    final InetAddress ip;
    try {
        ip = InetAddress.getByName(request.ip);
    } catch (Exception e) {
        throw new IllegalArgumentException("Invalid/malformed IP address: " + request.ip);
    }
    // Optionally allocate a hostname
    final String hostname;
    if (request.hostname != null)
        hostname = request.hostname;
    else
        hostname = generateHostname(request.prefix);
    // Generate an SSL cert
    final LetsEncryptCertificateEntity cert = letsEncrypt.issue(hostname);
    // Set up the hostname
    if (ip instanceof Inet6Address)
        dns.createDNSRecord(hostname, RecordType.AAAA, request.ip);
    else
        dns.createDNSRecord(hostname, RecordType.A, request.ip);
    return serialise(cert);
}
Also used : LetsEncryptCertificateEntity(com.peterphi.servicemanager.service.db.entity.LetsEncryptCertificateEntity) Inet6Address(java.net.Inet6Address) InetAddress(java.net.InetAddress)

Example 2 with LetsEncryptCertificateEntity

use of com.peterphi.servicemanager.service.db.entity.LetsEncryptCertificateEntity in project stdlib by petergeneric.

the class LetsEncryptService method generateOrRenewCertificate.

public LetsEncryptCertificateEntity generateOrRenewCertificate(final String domains) {
    LetsEncryptCertificateEntity entity = getCertificate(domains);
    // If we already have a keypair for these domains we shouldn't regenerate it, only regenerate the cert
    final KeyPair domainKeyPair;
    final boolean isNew;
    try {
        if (entity != null) {
            final ByteArrayInputStream bis = new ByteArrayInputStream(entity.getKeypair());
            final InputStreamReader isr = new InputStreamReader(bis, StandardCharsets.UTF_8);
            domainKeyPair = KeyPairUtils.readKeyPair(isr);
            isNew = false;
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            OutputStreamWriter osr = new OutputStreamWriter(bos, StandardCharsets.UTF_8);
            domainKeyPair = KeyPairUtils.createKeyPair(DOMAIN_KEY_SIZE);
            KeyPairUtils.writeKeyPair(domainKeyPair, osr);
            entity = new LetsEncryptCertificateEntity();
            entity.setId(domains);
            entity.setKeypair(bos.toByteArray());
            isNew = true;
        }
    } catch (IOException e) {
        throw new RuntimeException("Error serialising/deserialising keypair for domains " + domains, e);
    }
    final Registration registration = getRegistration();
    // Generate a CSR for the domains
    CSRBuilder csrb = new CSRBuilder();
    for (String domain : domains.split(",")) csrb.addDomain(domain);
    try {
        csrb.sign(domainKeyPair);
    } catch (IOException e) {
        throw new RuntimeException("Error signing CSR for " + domains + " with domains keypair!", e);
    }
    // Request a signed certificate
    final Certificate certificate;
    try {
        certificate = registration.requestCertificate(csrb.getEncoded());
        log.info("Success! The certificate for domains " + domains + " has been generated!");
        log.info("Certificate URI: " + certificate.getLocation());
    } catch (IOException e) {
        throw new RuntimeException("Failed to encode CSR request for " + domains, e);
    } catch (AcmeException e) {
        throw new RuntimeException("Failed to request certificate from Let's Encrypt for " + domains, e);
    }
    // Download the certificate
    final X509Certificate cert;
    final X509Certificate[] chain;
    try {
        cert = certificate.download();
        chain = certificate.downloadChain();
    } catch (AcmeException e) {
        throw new RuntimeException("Error downloading certificate information for " + domains + " " + certificate.getLocation(), e);
    }
    // Write certificate only
    final byte[] certBytes;
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        OutputStreamWriter osr = new OutputStreamWriter(bos, StandardCharsets.UTF_8);
        CertificateUtils.writeX509Certificate(cert, osr);
        certBytes = bos.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException("Error serialising Cert for " + domains, e);
    }
    // Write chain only
    byte[] chainBytes;
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        OutputStreamWriter osr = new OutputStreamWriter(bos, StandardCharsets.UTF_8);
        CertificateUtils.writeX509CertificateChain(chain, osr);
        chainBytes = bos.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException("Error serialising Cert for " + domains, e);
    }
    entity.setCert(certBytes);
    entity.setChain(chainBytes);
    entity.setExpires(new DateTime(cert.getNotAfter()));
    // Make sure a management token is assigned
    if (entity.getManagementToken() == null)
        entity.setManagementToken(SimpleId.alphanumeric(32));
    if (isNew) {
        certificateDao.save(entity);
    } else {
        certificateDao.update(entity);
    }
    return entity;
}
Also used : KeyPair(java.security.KeyPair) InputStreamReader(java.io.InputStreamReader) AcmeException(org.shredzone.acme4j.exception.AcmeException) LetsEncryptCertificateEntity(com.peterphi.servicemanager.service.db.entity.LetsEncryptCertificateEntity) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) DateTime(org.joda.time.DateTime) ByteArrayInputStream(java.io.ByteArrayInputStream) Registration(org.shredzone.acme4j.Registration) OutputStreamWriter(java.io.OutputStreamWriter) CSRBuilder(org.shredzone.acme4j.util.CSRBuilder) X509Certificate(java.security.cert.X509Certificate) Certificate(org.shredzone.acme4j.Certificate)

Aggregations

LetsEncryptCertificateEntity (com.peterphi.servicemanager.service.db.entity.LetsEncryptCertificateEntity)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 OutputStreamWriter (java.io.OutputStreamWriter)1 Inet6Address (java.net.Inet6Address)1 InetAddress (java.net.InetAddress)1 KeyPair (java.security.KeyPair)1 X509Certificate (java.security.cert.X509Certificate)1 DateTime (org.joda.time.DateTime)1 Certificate (org.shredzone.acme4j.Certificate)1 Registration (org.shredzone.acme4j.Registration)1 AcmeException (org.shredzone.acme4j.exception.AcmeException)1 CSRBuilder (org.shredzone.acme4j.util.CSRBuilder)1