diff --git a/.gitignore b/.gitignore
index faac27b..edb6e81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,4 +24,5 @@ hs_err_pid*
replay_pid*
/.idea
-*.iml
\ No newline at end of file
+*.iml
+/jzlint-server/target/
diff --git a/jzlint-ca/src/main/java/de/mtg/jzlint/ca/CreateCertificate008.java b/jzlint-ca/src/main/java/de/mtg/jzlint/ca/CreateCertificate008.java
index a59c231..73b86a9 100644
--- a/jzlint-ca/src/main/java/de/mtg/jzlint/ca/CreateCertificate008.java
+++ b/jzlint-ca/src/main/java/de/mtg/jzlint/ca/CreateCertificate008.java
@@ -1,11 +1,33 @@
package de.mtg.jzlint.ca;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.DERPrintableString;
-import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.*;
+import org.bouncycastle.asn1.x509.AccessDescription;
+import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
+import org.bouncycastle.asn1.x509.CertificatePolicies;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.PolicyInformation;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
@@ -14,17 +36,6 @@
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.*;
-import java.security.cert.X509Certificate;
-import java.security.spec.AlgorithmParameterSpec;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.*;
-
/**
* Certificates for lint: e_aia_ca_issuers_must_have_http_only
diff --git a/jzlint-server/pom.xml b/jzlint-server/pom.xml
new file mode 100644
index 0000000..763222f
--- /dev/null
+++ b/jzlint-server/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ de.mtg
+ jzlint-server
+ 1.0.1
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.3.4
+
+
+
+
+
+
+ de.mtg
+ jzlint
+ ${project.version}
+
+
+
+ org.bouncycastle
+ bcprov-jdk18on
+ 1.78.1
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/CliUtils.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/CliUtils.java
new file mode 100644
index 0000000..a7acef0
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/CliUtils.java
@@ -0,0 +1,88 @@
+package de.mtg.jzlint.server;
+
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import de.mtg.jzlint.Source;
+
+public class CliUtils {
+
+ public static final String CHECK_APPLIES = "checkApplies";
+ public static final String EXECUTE = "execute";
+
+ private CliUtils() {
+ // empty
+ }
+
+ public static boolean isCertificateIssuerLint(Class> lintClass) {
+ try {
+ lintClass.getMethod(CHECK_APPLIES, X509Certificate.class, X509Certificate.class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public static boolean isCRLIssuerLint(Class> lintClass) {
+ try {
+ lintClass.getMethod(CHECK_APPLIES, X509CRL.class, X509Certificate.class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public static boolean isOCSPResponseIssuerLint(Class> lintClass) {
+ try {
+ lintClass.getMethod(CHECK_APPLIES, byte[].class, X509Certificate.class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public static boolean isCertificateLint(Class> lintClass) {
+ try {
+ lintClass.getMethod(CHECK_APPLIES, X509Certificate.class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public static boolean isCRLLint(Class> lintClass) {
+ try {
+ lintClass.getMethod(CHECK_APPLIES, X509CRL.class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public static boolean isOCSPResponseLint(Class> lintClass) {
+ try {
+ lintClass.getMethod(CHECK_APPLIES, byte[].class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public static boolean includeLint(Source lintSource, List includeSources, List excludeSources) {
+
+ boolean includeIsEmpty = includeSources == null || includeSources.isEmpty();
+ boolean excludeIsEmpty = excludeSources == null || excludeSources.isEmpty();
+
+ if (!includeIsEmpty) {
+ return includeSources.contains(lintSource.getSourceName());
+ }
+
+ if (!excludeIsEmpty) {
+ return !excludeSources.contains(lintSource.getSourceName());
+ }
+
+ return true;
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/JZLintServer.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/JZLintServer.java
new file mode 100644
index 0000000..fc31a33
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/JZLintServer.java
@@ -0,0 +1,17 @@
+package de.mtg.jzlint.server;
+
+import java.security.Security;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class JZLintServer {
+
+ public static void main(String[] args) {
+ Security.addProvider(new BouncyCastleProvider());
+ SpringApplication.run(JZLintServer.class, args);
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/LintController.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/LintController.java
new file mode 100644
index 0000000..332c632
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/LintController.java
@@ -0,0 +1,78 @@
+package de.mtg.jzlint.server;
+
+import java.nio.charset.StandardCharsets;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.ForkJoinPool;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.context.request.async.DeferredResult;
+
+import de.mtg.jzlint.LintJSONResults;
+import de.mtg.jzlint.utils.ParsedDomainNameUtils;
+
+@RestController
+public class LintController {
+
+ @Value("${request.timeout:15000}")
+ private long requestTimeout;
+
+ @PostMapping(value = "/certificate/lint", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+ public DeferredResult> lintCertificate(@RequestBody TBLCertificate tblCertificate) {
+ DeferredResult> response = new DeferredResult<>(requestTimeout, new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+
+ ForkJoinPool.commonPool().submit(() -> {
+ try {
+ byte[] rawPKIObject = tblCertificate.getCertificate().getBytes(StandardCharsets.US_ASCII);
+ LintJSONResults lint = ServerUtils.lint(rawPKIObject, null, tblCertificate.getIncludeNames(), tblCertificate.getIncludeSources(), tblCertificate.getExcludeNames(), tblCertificate.getExcludeSources());
+ X509Certificate certificate = ServerUtils.getCertificate(rawPKIObject);
+ ParsedDomainNameUtils.cleanCacheEntry(certificate);
+ response.setResult(new ResponseEntity<>(ServerUtils.convertResultToResponse(lint), HttpStatus.OK));
+ } catch (Exception ex) {
+ response.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+ });
+
+ return response;
+ }
+
+ @PostMapping("/crl/lint")
+ DeferredResult> lintCRL(@RequestBody TBLCRL tblCrl) {
+ DeferredResult> response = new DeferredResult<>(requestTimeout, new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+
+ ForkJoinPool.commonPool().submit(() -> {
+ try {
+ byte[] rawPKIObject = tblCrl.getCrl().getBytes(StandardCharsets.US_ASCII);
+ LintJSONResults lint = ServerUtils.lint(rawPKIObject, null, tblCrl.getIncludeNames(), tblCrl.getIncludeSources(), tblCrl.getExcludeNames(), tblCrl.getExcludeSources());
+ response.setResult(new ResponseEntity<>(ServerUtils.convertResultToResponse(lint), HttpStatus.OK));
+ } catch (Exception ex) {
+ response.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+ });
+
+ return response;
+ }
+
+ @PostMapping("/ocspresponse/lint")
+ DeferredResult> lintOCSP(@RequestBody TBLOCPResponse tblocpResponse) {
+ DeferredResult> response = new DeferredResult<>(requestTimeout, new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+
+ ForkJoinPool.commonPool().submit(() -> {
+ try {
+ byte[] rawPKIObject = tblocpResponse.getOcspResponse().getBytes(StandardCharsets.US_ASCII);
+ LintJSONResults lint = ServerUtils.lint(rawPKIObject, null, tblocpResponse.getIncludeNames(), tblocpResponse.getIncludeSources(), tblocpResponse.getExcludeNames(), tblocpResponse.getExcludeSources());
+ response.setResult(new ResponseEntity<>(ServerUtils.convertResultToResponse(lint), HttpStatus.OK));
+ } catch (Exception ex) {
+ response.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
+ }
+ });
+
+ return response;
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/LintResponse.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/LintResponse.java
new file mode 100644
index 0000000..3df3d77
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/LintResponse.java
@@ -0,0 +1,34 @@
+package de.mtg.jzlint.server;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LintResponse {
+
+ private List warnings;
+
+ private List errors;
+
+ public LintResponse() {
+ // empty
+ }
+
+ public List getWarnings() {
+ return warnings;
+ }
+
+ public void setWarnings(List warnings) {
+ this.warnings = warnings;
+ }
+
+ public List getErrors() {
+ return errors;
+ }
+
+ public void setErrors(List errors) {
+ this.errors = errors;
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/ServerUtils.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/ServerUtils.java
new file mode 100644
index 0000000..25881e0
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/ServerUtils.java
@@ -0,0 +1,215 @@
+package de.mtg.jzlint.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.NoSuchProviderException;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.bouncycastle.asn1.ocsp.OCSPResponse;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import de.mtg.jzlint.IneffectiveDate;
+import de.mtg.jzlint.Lint;
+import de.mtg.jzlint.LintClassesContainer;
+import de.mtg.jzlint.LintJSONResult;
+import de.mtg.jzlint.LintJSONResults;
+import de.mtg.jzlint.LintResult;
+import de.mtg.jzlint.Source;
+import de.mtg.jzlint.Status;
+import de.mtg.jzlint.utils.DateUtils;
+
+public final class ServerUtils {
+
+ public static LintResponse convertResultToResponse(final LintJSONResults results) {
+ Set keySet = results.getResult().keySet();
+ List errors = new ArrayList<>();
+ List warnings = new ArrayList<>();
+ LintResponse lintResponse = new LintResponse();
+ for (String key : keySet) {
+ String result = results.getResult().get(key).get("result");
+ if ("error".equalsIgnoreCase(result)) {
+ errors.add(key);
+ }
+ if ("warning".equalsIgnoreCase(result)) {
+ warnings.add(key);
+ }
+ }
+ lintResponse.setErrors(errors);
+ lintResponse.setWarnings(warnings);
+ return lintResponse;
+ }
+
+
+ public static X509Certificate getCertificate(byte[] input) {
+ try (InputStream inputStream = new ByteArrayInputStream(input)) {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
+ return (X509Certificate) certificateFactory.generateCertificate(inputStream);
+ } catch (IOException | CertificateException | NoSuchProviderException ex) {
+ return null;
+ }
+ }
+
+ public static X509CRL getCRL(byte[] input) {
+ try (InputStream inputStream = new ByteArrayInputStream(input)) {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
+ return (X509CRL) certificateFactory.generateCRL(inputStream);
+ } catch (IOException | CertificateException | NoSuchProviderException | CRLException ex) {
+ return null;
+ }
+ }
+
+ public static OCSPResponse getOCSPResponse(byte[] input) {
+ try {
+ return OCSPResponse.getInstance(input);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public static LintJSONResults lint(
+ byte[] pkiObject,
+ byte[] issuer,
+ List includeNames,
+ List includeSources,
+ List excludeSources,
+ List excludeNames) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
+
+ LintClassesContainer lintClassesContainer = LintClassesContainer.getInstance();
+ List> lintClasses = lintClassesContainer.getLintClasses();
+
+ List result = new ArrayList<>();
+
+ boolean hasIssuer = (issuer != null && issuer.length > 0);
+ X509Certificate certificate = getCertificate(pkiObject);
+ X509CRL crl = getCRL(pkiObject);
+ boolean isCertificate = certificate != null;
+ boolean isCRL = crl != null;
+ OCSPResponse ocspResponse = getOCSPResponse(pkiObject);
+ boolean isOCSP = ocspResponse != null;
+ X509Certificate issuerCertificate = null;
+ if (hasIssuer) {
+ issuerCertificate = getCertificate(issuer);
+ }
+
+ for (Class> lintClass : lintClasses) {
+
+ if (!lintClass.isAnnotationPresent(Lint.class)) {
+ continue;
+ }
+
+ Lint lintAnnotation = lintClass.getAnnotation(Lint.class);
+
+ String lintName = lintAnnotation.name();
+
+ if (includeNames != null && !includeNames.isEmpty() && !includeNames.contains(lintName)) {
+ continue;
+ }
+
+ if (excludeNames != null && !excludeNames.isEmpty() && excludeNames.contains(lintName)) {
+ continue;
+ }
+
+ Source source = lintAnnotation.source();
+ if (!CliUtils.includeLint(source, includeSources, excludeSources)) {
+ continue;
+ }
+
+ boolean isCertificateIssuerLint = CliUtils.isCertificateIssuerLint(lintClass);
+ boolean isCRLIssuerLint = CliUtils.isCRLIssuerLint(lintClass);
+ boolean isOCSPResponseIssuerLint = CliUtils.isOCSPResponseIssuerLint(lintClass);
+
+ if (isCertificate) {
+ ZonedDateTime time = DateUtils.getNotBefore(certificate);
+ if (hasIssuer && isCertificateIssuerLint) {
+ result.add(getLintResult(certificate, issuerCertificate, time, X509Certificate.class, lintClass, lintAnnotation));
+ } else if (CliUtils.isCertificateLint(lintClass)) {
+ result.add(getLintResult(certificate, null, time, X509Certificate.class, lintClass, lintAnnotation));
+ }
+ }
+
+ if (isCRL) {
+ ZonedDateTime time = DateUtils.getThisUpdate(crl);
+ if (hasIssuer && isCRLIssuerLint) {
+ result.add(getLintResult(crl, issuerCertificate, time, X509CRL.class, lintClass, lintAnnotation));
+ } else if (CliUtils.isCRLLint(lintClass)) {
+ result.add(getLintResult(crl, null, time, X509CRL.class, lintClass, lintAnnotation));
+ }
+ }
+
+ if (isOCSP) {
+ ZonedDateTime time = DateUtils.getProducedAt(ocspResponse);
+ if (hasIssuer && isOCSPResponseIssuerLint) {
+ result.add(getLintResult(pkiObject, issuerCertificate, time, byte[].class, lintClass, lintAnnotation));
+ } else if (CliUtils.isOCSPResponseLint(lintClass)) {
+ result.add(getLintResult(pkiObject, null, time, byte[].class, lintClass, lintAnnotation));
+ }
+ }
+ }
+
+ return new LintJSONResults(result);
+ }
+
+
+ public static LintJSONResult getLintResult(
+ Object pkiObject,
+ X509Certificate issuer,
+ ZonedDateTime time,
+ Class> pkiObjectClass,
+ Class> lintClass,
+ Lint lintAnnotation) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
+
+ Method checkAppliesMethod;
+ Method executeMethod;
+ if (issuer == null) {
+ checkAppliesMethod = lintClass.getMethod(CliUtils.CHECK_APPLIES, pkiObjectClass);
+ executeMethod = lintClass.getMethod(CliUtils.EXECUTE, pkiObjectClass);
+ } else {
+ checkAppliesMethod = lintClass.getMethod(CliUtils.CHECK_APPLIES, pkiObjectClass, issuer.getClass());
+ executeMethod = lintClass.getMethod(CliUtils.EXECUTE, pkiObjectClass, issuer.getClass());
+ }
+
+ Object object = lintClass.getDeclaredConstructor().newInstance();
+
+ boolean checkApplies;
+ if (issuer == null) {
+ checkApplies = (boolean) checkAppliesMethod.invoke(object, pkiObject);
+ } else {
+ checkApplies = (boolean) checkAppliesMethod.invoke(object, pkiObject, issuer);
+ }
+
+ if (!checkApplies) {
+ return new LintJSONResult(lintAnnotation.name(), Status.NA);
+ }
+
+ if (!DateUtils.isIssuedOnOrAfter(time, lintAnnotation.effectiveDate().getZonedDateTime())) {
+ return new LintJSONResult(lintAnnotation.name(), Status.NE);
+ }
+
+ if (IneffectiveDate.EMPTY != lintAnnotation.ineffectiveDate() &&
+ DateUtils.isIssuedOnOrAfter(time, lintAnnotation.ineffectiveDate().getZonedDateTime())) {
+ return new LintJSONResult(lintAnnotation.name(), Status.NE);
+ }
+
+ LintResult lintResult;
+ if (issuer == null) {
+ lintResult = (LintResult) executeMethod.invoke(object, pkiObject);
+ } else {
+ lintResult = (LintResult) executeMethod.invoke(object, pkiObject, issuer);
+ }
+
+ return new LintJSONResult(lintAnnotation.name(), lintResult.getStatus());
+
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLCRL.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLCRL.java
new file mode 100644
index 0000000..b0afd19
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLCRL.java
@@ -0,0 +1,62 @@
+package de.mtg.jzlint.server;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TBLCRL {
+
+ private String crl;
+
+ private List includeNames;
+ private List includeSources;
+ private List excludeSources;
+ private List excludeNames;
+
+
+ public TBLCRL() {
+ // empty
+ }
+
+ public String getCrl() {
+ return crl;
+ }
+
+ public void setCrl(String crl) {
+ this.crl = crl;
+ }
+
+ public List getIncludeNames() {
+ return includeNames;
+ }
+
+ public void setIncludeNames(List includeNames) {
+ this.includeNames = includeNames;
+ }
+
+ public List getIncludeSources() {
+ return includeSources;
+ }
+
+ public void setIncludeSources(List includeSources) {
+ this.includeSources = includeSources;
+ }
+
+ public List getExcludeSources() {
+ return excludeSources;
+ }
+
+ public void setExcludeSources(List excludeSources) {
+ this.excludeSources = excludeSources;
+ }
+
+ public List getExcludeNames() {
+ return excludeNames;
+ }
+
+ public void setExcludeNames(List excludeNames) {
+ this.excludeNames = excludeNames;
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLCertificate.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLCertificate.java
new file mode 100644
index 0000000..e9b9a50
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLCertificate.java
@@ -0,0 +1,61 @@
+package de.mtg.jzlint.server;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TBLCertificate {
+
+ private String certificate;
+
+ private List includeNames;
+ private List includeSources;
+ private List excludeSources;
+ private List excludeNames;
+
+ public TBLCertificate() {
+ // empty
+ }
+
+ public String getCertificate() {
+ return certificate;
+ }
+
+ public void setCertificate(String certificate) {
+ this.certificate = certificate;
+ }
+
+ public List getIncludeNames() {
+ return includeNames;
+ }
+
+ public void setIncludeNames(List includeNames) {
+ this.includeNames = includeNames;
+ }
+
+ public List getIncludeSources() {
+ return includeSources;
+ }
+
+ public void setIncludeSources(List includeSources) {
+ this.includeSources = includeSources;
+ }
+
+ public List getExcludeSources() {
+ return excludeSources;
+ }
+
+ public void setExcludeSources(List excludeSources) {
+ this.excludeSources = excludeSources;
+ }
+
+ public List getExcludeNames() {
+ return excludeNames;
+ }
+
+ public void setExcludeNames(List excludeNames) {
+ this.excludeNames = excludeNames;
+ }
+
+}
diff --git a/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLOCPResponse.java b/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLOCPResponse.java
new file mode 100644
index 0000000..3a2b550
--- /dev/null
+++ b/jzlint-server/src/main/java/de/mtg/jzlint/server/TBLOCPResponse.java
@@ -0,0 +1,62 @@
+package de.mtg.jzlint.server;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TBLOCPResponse {
+
+ private String ocspResponse;
+
+ private List includeNames;
+ private List includeSources;
+ private List excludeSources;
+ private List excludeNames;
+
+
+ public TBLOCPResponse() {
+ // empty
+ }
+
+ public String getOcspResponse() {
+ return ocspResponse;
+ }
+
+ public void setOcspResponse(String ocspResponse) {
+ this.ocspResponse = ocspResponse;
+ }
+
+ public List getIncludeNames() {
+ return includeNames;
+ }
+
+ public void setIncludeNames(List includeNames) {
+ this.includeNames = includeNames;
+ }
+
+ public List getIncludeSources() {
+ return includeSources;
+ }
+
+ public void setIncludeSources(List includeSources) {
+ this.includeSources = includeSources;
+ }
+
+ public List getExcludeSources() {
+ return excludeSources;
+ }
+
+ public void setExcludeSources(List excludeSources) {
+ this.excludeSources = excludeSources;
+ }
+
+ public List getExcludeNames() {
+ return excludeNames;
+ }
+
+ public void setExcludeNames(List excludeNames) {
+ this.excludeNames = excludeNames;
+ }
+
+}
diff --git a/jzlint-server/src/main/resources/application.properties b/jzlint-server/src/main/resources/application.properties
new file mode 100644
index 0000000..f5365fb
--- /dev/null
+++ b/jzlint-server/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+server.servlet.encoding.enabled=false
+server.servlet.encoding.force=false
+server.servlet.encoding.force-request=false
+server.servlet.encoding.force-response=false
\ No newline at end of file