Skip to content

Commit

Permalink
Certificate > sync certificates locally #324
Browse files Browse the repository at this point in the history
  • Loading branch information
Paolo Venturi - Diennea committed Oct 19, 2022
1 parent be083fc commit 246fccf
Show file tree
Hide file tree
Showing 19 changed files with 933 additions and 402 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.carapaceproxy.api;

import org.carapaceproxy.configstore.CertificateData;
import org.carapaceproxy.configstore.ConfigurationStoreUtils;
import org.carapaceproxy.core.HttpProxyServer;
import org.carapaceproxy.core.RuntimeServerConfiguration;
import org.carapaceproxy.server.certificates.DynamicCertificateState;
Expand All @@ -29,7 +28,6 @@
import org.carapaceproxy.server.config.SSLCertificateConfiguration.CertificateMode;
import org.carapaceproxy.utils.CertificatesUtils;

import javax.servlet.ServletContext;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
Expand All @@ -55,6 +53,11 @@
import static org.carapaceproxy.utils.APIUtils.*;
import static org.carapaceproxy.utils.CertificatesUtils.createKeystore;
import static org.carapaceproxy.utils.CertificatesUtils.loadKeyStoreFromFile;
import java.util.Collection;
import java.util.List;
import javax.servlet.ServletContext;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
* Access to certificates
Expand All @@ -71,6 +74,21 @@ public class CertificatesResource {
@javax.ws.rs.core.Context
ServletContext context;

@Data
@AllArgsConstructor
public static final class CertificatesResponse {

private final Collection<CertificateBean> certificates;
private final String localStorePath;

public CertificatesResponse(Collection<CertificateBean> certificates, HttpProxyServer server) {
this.certificates = certificates;
this.localStorePath = server.getCurrentConfiguration().getLocalCertificatesStorePath();
}

}

@Data
public static final class CertificateBean {

private final String id;
Expand All @@ -91,63 +109,11 @@ public CertificateBean(String id, String hostname, String mode, boolean dynamic,
this.sslCertificateFile = sslCertificateFile;
}

public String getId() {
return id;
}

public String getHostname() {
return hostname;
}

public String getMode() {
return mode;
}

public boolean isDynamic() {
return dynamic;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getSslCertificateFile() {
return sslCertificateFile;
}

public String getExpiringDate() {
return expiringDate;
}

public void setExpiringDate(String expiringDate) {
this.expiringDate = expiringDate;
}

public String getDaysBeforeRenewal() {
return daysBeforeRenewal;
}

public void setDaysBeforeRenewal(String daysBeforeRenewal) {
this.daysBeforeRenewal = daysBeforeRenewal;
}

public String getSerialNumber() {
return serialNumber;
}

public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}

}

@GET
@Path("/")
public Map<String, CertificateBean> getAllCertificates() {
public CertificatesResponse getAllCertificates() {
HttpProxyServer server = (HttpProxyServer) context.getAttribute("server");
RuntimeServerConfiguration conf = server.getCurrentConfiguration();
DynamicCertificatesManager dCManager = server.getDynamicCertificatesManager();
Expand All @@ -165,7 +131,7 @@ public Map<String, CertificateBean> getAllCertificates() {
res.put(certificateEntry.getKey(), certBean);
}

return res;
return new CertificatesResponse(res.values(), server);
}

private static void fillCertificateBean(CertificateBean bean, SSLCertificateConfiguration certificate, DynamicCertificatesManager dCManager, HttpProxyServer server) {
Expand Down Expand Up @@ -207,8 +173,11 @@ private static void fillCertificateBean(CertificateBean bean, SSLCertificateConf

@GET
@Path("{certId}")
public CertificateBean getCertificateById(@PathParam("certId") String certId) {
return findCertificateById(certId);
public CertificatesResponse getCertificateById(@PathParam("certId") String certId) {
return new CertificatesResponse(
List.of(findCertificateById(certId)),
(HttpProxyServer) context.getAttribute("server")
);
}

@GET
Expand Down Expand Up @@ -289,7 +258,7 @@ public Response uploadCertificate(
state = AVAILABLE;
}

CertificateData cert = new CertificateData(domain, "", encodedData, state, "", "");
CertificateData cert = new CertificateData(domain, encodedData, state, "", "");
cert.setManual(MANUAL.equals(certType));

cert.setDaysBeforeRenewal(daysbeforerenewal != null ? daysbeforerenewal : DEFAULT_DAYS_BEFORE_RENEWAL);
Expand All @@ -300,4 +269,20 @@ public Response uploadCertificate(
}
}

@POST
@Path("{domain}/store")
public SimpleResponse storeLocalCertificate(@PathParam("domain") String domain) throws Exception {
var server = ((HttpProxyServer) context.getAttribute("server"));
server.getDynamicCertificatesManager().forceStoreLocalCertificates(domain);
return SimpleResponse.success();
}

@POST
@Path("/storeall")
public SimpleResponse storeAllCertificates() throws Exception {
var server = ((HttpProxyServer) context.getAttribute("server"));
server.getDynamicCertificatesManager().forceStoreLocalCertificates();
return SimpleResponse.success();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.carapaceproxy.configstore.ConfigurationStore;
import org.carapaceproxy.configstore.PropertiesConfigurationStore;
import org.carapaceproxy.core.HttpProxyServer;
import org.carapaceproxy.core.RuntimeServerConfiguration;
import org.carapaceproxy.server.config.ConfigurationChangeInProgressException;
import org.carapaceproxy.server.config.ConfigurationNotValidException;

Expand Down Expand Up @@ -71,7 +70,7 @@ public String dump() {
@Path("/validate")
@Consumes(value = "text/plain")
@POST
public ConfigurationValidationResult validate(String newConfiguration) {
public SimpleResponse validate(String newConfiguration) {
LOG.info("Validating configuration from API:");
LOG.info(newConfiguration);

Expand All @@ -80,9 +79,9 @@ public ConfigurationValidationResult validate(String newConfiguration) {
PropertiesConfigurationStore simpleStore = buildStore(newConfiguration);
dumpAndValidateInputConfiguration(simpleStore);
server.buildValidConfiguration(simpleStore);
return ConfigurationValidationResult.OK;
return SimpleResponse.success();
} catch (ConfigurationNotValidException | RuntimeException err) {
return ConfigurationValidationResult.error(err);
return SimpleResponse.error(err);
}
}

Expand All @@ -103,7 +102,7 @@ public static PropertiesConfigurationStore buildStore(String newConfiguration) t
@Path("/apply")
@Consumes(value = "text/plain")
@POST
public ConfigurationChangeResult apply(String newConfiguration) {
public SimpleResponse apply(String newConfiguration) {
LOG.info("Apply configuration from API:");
LOG.info(newConfiguration);
LOG.info("**");
Expand All @@ -112,14 +111,14 @@ public ConfigurationChangeResult apply(String newConfiguration) {
PropertiesConfigurationStore simpleStore = buildStore(newConfiguration);
dumpAndValidateInputConfiguration(simpleStore);
server.applyDynamicConfigurationFromAPI(simpleStore);
return ConfigurationChangeResult.OK;
return SimpleResponse.success();
} catch (ConfigurationNotValidException
| ConfigurationChangeInProgressException
| RuntimeException err) {
return ConfigurationChangeResult.error(err);
return SimpleResponse.error(err);
} catch (InterruptedException err) {
Thread.currentThread().interrupt();
return ConfigurationChangeResult.error(err);
return SimpleResponse.error(err);
}
}

Expand Down Expand Up @@ -158,34 +157,6 @@ private void dumpAndValidateInputConfiguration(PropertiesConfigurationStore simp
}
}

public static final class ConfigurationValidationResult {

private final boolean ok;
private final String error;

public static final ConfigurationValidationResult OK = new ConfigurationValidationResult(true, "");

public static final ConfigurationValidationResult error(Throwable error) {
StringWriter w = new StringWriter();
error.printStackTrace(new PrintWriter(w));
return new ConfigurationValidationResult(false, w.toString());
}

private ConfigurationValidationResult(boolean ok, String error) {
this.ok = ok;
this.error = error;
}

public boolean isOk() {
return ok;
}

public String getError() {
return error;
}

}

public static final class ConfigurationChangeResult {

private final boolean ok;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to Diennea S.r.l. under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Diennea S.r.l. licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.carapaceproxy.api;

import java.io.PrintWriter;
import java.io.StringWriter;
import lombok.Data;

/**
* Simple REST response
*
* @author paolo.venturi
*/
@Data
public class SimpleResponse {

private final boolean ok;
private final String error;

private SimpleResponse(boolean ok, String error) {
this.ok = ok;
this.error = error;
}

public static final SimpleResponse success() {
return new SimpleResponse(true, "");
}

public static final SimpleResponse error(Throwable error) {
StringWriter w = new StringWriter();
error.printStackTrace(new PrintWriter(w));
return new SimpleResponse(false, w.toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
public class CertificateData {

private String domain;
private String privateKey; // base64 encoded string.
private String chain; // base64 encoded string of the KeyStore.
private volatile DynamicCertificateState state;
private String pendingOrderLocation;
Expand All @@ -48,10 +47,9 @@ public class CertificateData {
private String serialNumber; // hex
private byte[] keystoreData; // decoded chain

public CertificateData(String domain, String privateKey, String chain, DynamicCertificateState state,
public CertificateData(String domain, String chain, DynamicCertificateState state,
String orderLocation, String challengeData) {
this.domain = domain;
this.privateKey = privateKey;
this.chain = chain;
this.state = state;
this.pendingOrderLocation = orderLocation;
Expand All @@ -62,10 +60,6 @@ public String getDomain() {
return domain;
}

public String getPrivateKey() {
return privateKey;
}

public String getChain() {
return chain;
}
Expand All @@ -86,10 +80,6 @@ public void setDomain(String domain) {
this.domain = domain;
}

public void setPrivateKey(String keypair) {
this.privateKey = keypair;
}

public void setChain(String chain) {
this.chain = chain;
}
Expand Down Expand Up @@ -166,7 +156,6 @@ public void setKeystoreData(byte[] keystoreData) {
public int hashCode() {
int hash = 7;
hash = 89 * hash + Objects.hashCode(this.domain);
hash = 89 * hash + Objects.hashCode(this.privateKey);
hash = 89 * hash + Objects.hashCode(this.chain);
hash = 89 * hash + Objects.hashCode(this.state);
hash = 89 * hash + Objects.hashCode(this.pendingOrderLocation);
Expand Down Expand Up @@ -197,9 +186,6 @@ public boolean equals(Object obj) {
if (!Objects.equals(this.domain, other.domain)) {
return false;
}
if (!Objects.equals(this.privateKey, other.privateKey)) {
return false;
}
if (!Objects.equals(this.chain, other.chain)) {
return false;
}
Expand All @@ -218,7 +204,7 @@ public boolean equals(Object obj) {
@Override
public String toString() {
return "CertificateData{" + "domain=" + domain + ","
+" state=" + state + ", manual=" + manual
+ " state=" + state + ", manual=" + manual
+ ",expiringDate=" + expiringDate + ",serialNumber " + serialNumber + '}';
}

Expand Down
Loading

0 comments on commit 246fccf

Please sign in to comment.