diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiOperations.java
index a7d99f2a..e66fd516 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiOperations.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiOperations.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ import org.springframework.vault.support.VaultSignCertificateRequestResponse;
* provide the verification functionality.
*
* @author Mark Paluch
+ * @author Nanne Baars
* @see https://www.vaultproject.io/docs/secrets/pki/index.html
*/
@@ -66,10 +67,10 @@ public interface VaultPkiOperations {
* @param certificateRequest must not be {@literal null}.
* @return the {@link VaultCertificateResponse} containing a
* {@link org.springframework.vault.support.Certificate} .
- * @since 2.0
* @see POST
* /pki/sign/[role name]
+ * @since 2.0
*/
VaultSignCertificateRequestResponse signCertificateRequest(String roleName, String csr,
VaultCertificateRequest certificateRequest) throws VaultException;
@@ -79,10 +80,10 @@ public interface VaultPkiOperations {
* standard method of revoking using Vault lease IDs. A successful revocation will
* rotate the CRL
* @param serialNumber must not be empty or {@literal null}.
- * @since 2.0
* @see POST
* /pki/revoke
+ * @since 2.0
*/
void revoke(String serialNumber) throws VaultException;
@@ -96,43 +97,56 @@ public interface VaultPkiOperations {
* is {@literal null}.
* @return {@link java.io.InputStream} containing the encoded CRL or {@literal null}
* if Vault responds with 204 No Content.
- * @since 2.0
* @see GET
* /pki/crl
+ * @since 2.0
*/
@Nullable
InputStream getCrl(Encoding encoding) throws VaultException;
- enum Encoding {
-
- DER, PEM,
-
- }
-
/**
- * Retrieves the specified issuer's certificate. Includes the full ca_chain of the
- * issuer.
+ * Retrieves the specified issuer's certificate. Includes the full {@code ca_chain} of
+ * the issuer.
* @param issuer reference to an existing issuer, either by Vault-generated
- * identifier, or the name assigned to an issuer. Pass the literal string 'default' to
- * refer to the currently configured issuer.
+ * identifier, or the name assigned to an issuer. Pass the literal string
+ * {@code default} to refer to the currently configured issuer.
* @return the {@link VaultIssuerCertificateRequestResponse} containing a
* {@link org.springframework.vault.support.Certificate}
* @see GET *
* /pki/issuer/:issuer_ref/json
- *
+ * @since 3.1
*/
VaultIssuerCertificateRequestResponse getIssuerCertificate(String issuer) throws VaultException;
/**
- * Retrieves the specified issuer's certificate. Includes the full ca_chain of the
- * issuer.
- * @return {@link java.io.InputStream} containing the encoded certificate or
- * {@literal null}
+ * Retrieves the specified issuer's certificate. Includes the full {@code ca_chain} of
+ * the issuer.
+ * @param issuer reference to an existing issuer, either by Vault-generated
+ * identifier, or the name assigned to an issuer. Pass the literal string
+ * {@code default} to refer to the currently configured issuer.
+ * @param encoding encoding to use.
+ * @return {@link java.io.InputStream} containing the encoded certificate.
* @see GET
* /pki/issuer/:issuer_ref/{der, pem}
+ * @since 3.1
*/
InputStream getIssuerCertificate(String issuer, Encoding encoding) throws VaultException;
+ enum Encoding {
+
+ /**
+ * DER (Distinguished Encoding Rules) format in its binary representation, see
+ * X.690.
+ */
+ DER,
+
+ /**
+ * Privacy-Enhanced Mail (PEM) format in base64.
+ */
+ PEM;
+
+ }
+
}
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java
index 2c2fde2f..7ddfb2ed 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,11 @@ package org.springframework.vault.core;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
@@ -165,12 +167,14 @@ public class VaultPkiTemplate implements VaultPkiOperations {
@Override
public InputStream getIssuerCertificate(String issuer, Encoding encoding) throws VaultException {
+
Assert.hasText(issuer, "Issuer must not be empty");
Assert.notNull(encoding, "Encoding must not be null");
return this.vaultOperations.doWithSession(restOperations -> {
- String requestPath = encoding == Encoding.DER ? "{path}/issuer/{issuer}/der" : "{path}/issuer/{issuer}/pem";
+ String requestPath = String.format("{path}/issuer/{issuer}/%s", encoding.name().toLowerCase(Locale.ROOT));
+
try {
ResponseEntity response = restOperations.getForEntity(requestPath, byte[].class, this.path,
issuer);
@@ -224,7 +228,7 @@ public class VaultPkiTemplate implements VaultPkiOperations {
.to("exclude_cn_from_sans", request);
mapper.from(certificateRequest::getFormat).whenHasText().to("format", request);
mapper.from(certificateRequest::getPrivateKeyFormat).whenHasText().to("private_key_format", request);
- mapper.from(certificateRequest::getNotAfter).whenHasText().as(i -> i.toString()).to("not_after", request);
+ mapper.from(certificateRequest::getNotAfter).whenHasText().as(Instant::toString).to("not_after", request);
mapper.from(certificateRequest::getUserIds).whenHasText().to("user_ids", request);
return request;
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/Certificate.java b/spring-vault-core/src/main/java/org/springframework/vault/support/Certificate.java
index 8f27276e..7ed8e9e8 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/support/Certificate.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/support/Certificate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
@@ -36,9 +37,9 @@ import org.springframework.vault.VaultException;
* encoded. Certificates can be obtained as {@link X509Certificate}.
*
* @author Mark Paluch
- * @since 2.0
* @see #getX509Certificate()
* @see #getIssuingCaCertificate()
+ * @since 2.0
*/
public class Certificate {
@@ -50,17 +51,18 @@ public class Certificate {
private final List caChain;
- private final Long revocationTime;
+ @Nullable
+ private final Instant revocationTime;
Certificate(@JsonProperty("serial_number") String serialNumber, @JsonProperty("certificate") String certificate,
@JsonProperty("issuing_ca") String issuingCaCertificate, @JsonProperty("ca_chain") List caChain,
- @JsonProperty("revocation_time") Long revocationTime) {
+ @Nullable @JsonProperty("revocation_time") Long revocationTime) {
this.serialNumber = serialNumber;
this.certificate = certificate;
this.issuingCaCertificate = issuingCaCertificate;
this.caChain = caChain;
- this.revocationTime = revocationTime;
+ this.revocationTime = revocationTime != null ? Instant.ofEpochMilli(revocationTime * 1000) : null;
}
/**
@@ -87,7 +89,8 @@ public class Certificate {
* @param certificate must not be empty or {@literal null}.
* @param issuingCaCertificate must not be empty or {@literal null}.
* @param caChain empty list allowed
- * @return the {@link Certificate}
+ * @return the {@link Certificate}.
+ * @since 3.1
*/
public static Certificate of(String serialNumber, String certificate, String issuingCaCertificate,
List caChain) {
@@ -107,8 +110,9 @@ public class Certificate {
* @param certificate must not be empty or {@literal null}.
* @param issuingCaCertificate must not be empty or {@literal null}.
* @param caChain empty list allowed
- * @param revocationTime revocation time, must not be {@literal null}
- * @return the {@link Certificate}
+ * @param revocationTime revocation time, must not be {@literal null}.
+ * @return the {@link Certificate}.
+ * @since 3.1
*/
public static Certificate of(String serialNumber, String certificate, String issuingCaCertificate,
List caChain, Long revocationTime) {
@@ -250,8 +254,13 @@ public class Certificate {
return certificates;
}
- public @Nullable Long getRevocationTime() {
+ @Nullable
+ public Instant getRevocationTime() {
return this.revocationTime;
}
+ public boolean isRevoked() {
+ return this.revocationTime != null;
+ }
+
}
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java
index bd533215..91e4a4b8 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,14 @@ import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
+import java.util.Locale;
import java.util.concurrent.TimeUnit;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
/**
* Request for a Certificate.
@@ -40,6 +43,13 @@ public class VaultCertificateRequest {
*/
private final String commonName;
+ /**
+ * If {@literal true}, the given common name will not be included in DNS or Email
+ * Subject Alternate Names (as appropriate). Useful if the CN is not a hostname or
+ * email address, but is instead some human-readable identifier.
+ */
+ private final boolean excludeCommonNameFromSubjectAltNames;
+
/**
* Alternate CN names for additional host names.
*/
@@ -59,6 +69,7 @@ public class VaultCertificateRequest {
* Specifies custom OID/UTF8-string Subject Alternative Names. These must match values
* specified on the role in {@literal allowed_other_sans}. The format is the same as
* OpenSSL: {@literal ;:} where the only current valid type is UTF8.
+ *
* @since 2.4
*/
private final List otherSans;
@@ -69,6 +80,14 @@ public class VaultCertificateRequest {
@Nullable
private final Duration ttl;
+ /**
+ * Set the Not After field of the certificate with specified date value. The value
+ * format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ. Supports the Y10K end
+ * date for IEEE 802.1AR-2018 standard devices, 9999-12-31T23:59:59Z.
+ */
+ @Nullable
+ private final Instant notAfter;
+
/**
* Specifies the format for returned data. Can be {@literal pem}, {@literal der}, or
* {@literal pem_bundle}; defaults to {@literal der} (in vault api the default is
@@ -76,6 +95,7 @@ public class VaultCertificateRequest {
* the certificate field will contain the private key and certificate, concatenated;
* if the issuing CA is not a Vault-derived self-signed root, this will be included as
* well.
+ *
* @since 2.4
*/
private final String format;
@@ -85,49 +105,35 @@ public class VaultCertificateRequest {
* which will return either base64-encoded DER or PEM-encoded DER, depending on the
* value of {@literal format}. The other option is {@literal pkcs8} which will return
* the key marshalled as PEM-encoded PKCS8.
+ *
* @since 2.4
*/
@Nullable
private final String privateKeyFormat;
- /**
- * Set the Not After field of the certificate with specified date value. The value
- * format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ. Supports the Y10K end
- * date for IEEE 802.1AR-2018 standard devices, 9999-12-31T23:59:59Z.
- */
- @Nullable
- private Instant notAfter;
-
/**
* Specifies the comma-separated list of requested User ID (OID
* 0.9.2342.19200300.100.1.1) Subject values to be placed on the signed certificate.
* This field is validated against allowed_user_ids on the role.
*/
@Nullable
- private String userIds;
+ private final String userIds;
- /**
- * If {@literal true}, the given common name will not be included in DNS or Email
- * Subject Alternate Names (as appropriate). Useful if the CN is not a hostname or
- * email address, but is instead some human-readable identifier.
- */
- private final boolean excludeCommonNameFromSubjectAltNames;
-
- private VaultCertificateRequest(String commonName, List altNames, List ipSubjectAltNames,
- List uriSubjectAltNames, List otherSans, @Nullable Duration ttl, String format,
- @Nullable String privateKeyFormat, boolean excludeCommonNameFromSubjectAltNames, @Nullable Instant notAfter,
- @Nullable String userIds) {
+ private VaultCertificateRequest(String commonName, boolean excludeCommonNameFromSubjectAltNames,
+ List altNames, List ipSubjectAltNames, List uriSubjectAltNames,
+ List otherSans, @Nullable Duration ttl, @Nullable Instant notAfter, String format,
+ @Nullable String privateKeyFormat, @Nullable String userIds) {
this.commonName = commonName;
+ this.excludeCommonNameFromSubjectAltNames = excludeCommonNameFromSubjectAltNames;
this.altNames = altNames;
this.ipSubjectAltNames = ipSubjectAltNames;
this.uriSubjectAltNames = uriSubjectAltNames;
this.otherSans = otherSans;
this.ttl = ttl;
- this.excludeCommonNameFromSubjectAltNames = excludeCommonNameFromSubjectAltNames;
+ this.notAfter = notAfter;
this.format = format;
this.privateKeyFormat = privateKeyFormat;
- this.notAfter = notAfter;
this.userIds = userIds;
}
@@ -240,6 +246,18 @@ public class VaultCertificateRequest {
return this;
}
+ /**
+ * Exclude the given common name from DNS or Email Subject Alternate Names (as
+ * appropriate). Useful if the CN is not a hostname or email address, but is
+ * instead some human-readable identifier.
+ * @return {@code this} {@link VaultCertificateRequestBuilder}.
+ */
+ public VaultCertificateRequestBuilder excludeCommonNameFromSubjectAltNames() {
+
+ this.excludeCommonNameFromSubjectAltNames = true;
+ return this;
+ }
+
/**
* Configure alternative names. Replaces previously configured alt names.
* @param altNames must not be {@literal null}.
@@ -381,6 +399,21 @@ public class VaultCertificateRequest {
return this;
}
+ /**
+ * Set the {@code Not After} field of the certificate with specified date value.
+ * Supports the Y10K end date for IEEE 802.1AR-2018 standard devices,
+ * 9999-12-31T23:59:59Z.
+ * @return {@code this} {@link VaultCertificateRequestBuilder}.
+ * @since 3.1
+ */
+ public VaultCertificateRequestBuilder notAfter(Instant notAfter) {
+
+ Assert.notNull(notAfter, "Not after must not be null");
+
+ this.notAfter = Instant.from(notAfter).truncatedTo(ChronoUnit.SECONDS);
+ return this;
+ }
+
/**
* Configure the certificate format.
* @param format the certificate format to use. Can be {@code pem}, {@code der},
@@ -412,28 +445,17 @@ public class VaultCertificateRequest {
}
/**
- * Exclude the given common name from DNS or Email Subject Alternate Names (as
- * appropriate). Useful if the CN is not a hostname or email address, but is
- * instead some human-readable identifier.
+ * Specifies the comma-separated list of requested User ID (OID
+ * 0.9.2342.19200300.100.1.1) Subject values to be placed on the signed
+ * certificate. This field is validated against allowed_user_ids on the role.
* @return {@code this} {@link VaultCertificateRequestBuilder}.
+ * @since 3.1
*/
- public VaultCertificateRequestBuilder excludeCommonNameFromSubjectAltNames() {
+ public VaultCertificateRequestBuilder userId(String userId) {
- this.excludeCommonNameFromSubjectAltNames = true;
- return this;
- }
+ Assert.hasText(userId, "User ID must not be empty or null");
- /**
- * Set the Not After field of the certificate with specified date value. The value
- * format should be given in UTC format YYYY-MM-ddTHH:MM:SSZ. Supports the Y10K
- * end date for IEEE 802.1AR-2018 standard devices, 9999-12-31T23:59:59Z.
- * @return {@code this} {@link VaultCertificateRequestBuilder}.
- */
- public VaultCertificateRequestBuilder notAfter(Instant notAfter) {
-
- Assert.notNull(notAfter, "Not after must not be null");
-
- this.notAfter = Instant.from(notAfter).truncatedTo(ChronoUnit.SECONDS);
+ this.userIds = userId;
return this;
}
@@ -442,12 +464,13 @@ public class VaultCertificateRequest {
* 0.9.2342.19200300.100.1.1) Subject values to be placed on the signed
* certificate. This field is validated against allowed_user_ids on the role.
* @return {@code this} {@link VaultCertificateRequestBuilder}.
+ * @since 3.1
*/
- public VaultCertificateRequestBuilder userIds(String userIds) {
+ public VaultCertificateRequestBuilder userIds(Collection userIds) {
- Assert.hasText(userIds, "User IDs must not be empty or null");
+ Assert.notNull(userIds, "User IDs must not be null");
- this.userIds = userIds;
+ this.userIds = StringUtils.collectionToCommaDelimitedString(userIds);
return this;
}
@@ -510,9 +533,9 @@ public class VaultCertificateRequest {
otherSans = java.util.Collections.unmodifiableList(new ArrayList<>(this.otherSans));
}
- return new VaultCertificateRequest(this.commonName, altNames, ipSubjectAltNames, uriSubjectAltNames,
- otherSans, this.ttl, this.format, this.privateKeyFormat, this.excludeCommonNameFromSubjectAltNames,
- notAfter, userIds);
+ return new VaultCertificateRequest(this.commonName, this.excludeCommonNameFromSubjectAltNames, altNames,
+ ipSubjectAltNames, uriSubjectAltNames, otherSans, this.ttl, notAfter, this.format,
+ this.privateKeyFormat, userIds);
}
private static List toList(Iterable iter) {
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultIssuerCertificateRequestResponse.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultIssuerCertificateRequestResponse.java
index 05782636..c3b2cb4a 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultIssuerCertificateRequestResponse.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultIssuerCertificateRequestResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.vault.support;
* Value object to bind Vault HTTP PKI issue certificate API responses.
*
* @author Nanne Baars
+ * @since 3.1
*/
public class VaultIssuerCertificateRequestResponse extends VaultResponseSupport {
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultPkiTemplateIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultPkiTemplateIntegrationTests.java
index f26f5055..c14c7aa0 100644
--- a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultPkiTemplateIntegrationTests.java
+++ b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultPkiTemplateIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,8 +59,10 @@ import org.springframework.vault.util.RequiresVaultVersion;
import org.springframework.vault.util.Version;
import org.springframework.web.client.HttpClientErrorException;
-import static org.assertj.core.api.Assertions.*;
-import static org.springframework.vault.util.Settings.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.springframework.vault.util.Settings.findWorkDir;
/**
* Integration tests for {@link VaultPkiTemplate} through {@link VaultPkiOperations}.
@@ -268,24 +270,27 @@ class VaultPkiTemplateIntegrationTests extends IntegrationTestSupport {
@Test
void signShouldSignCsrWithNotAfter() {
+
Instant notAfter = Instant.now().plus(50, ChronoUnit.DAYS);
- String csr = "-----BEGIN CERTIFICATE REQUEST-----\n"
- + "MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl\n"
- + "MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY\n"
- + "MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA\n"
- + "dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4\n"
- + "GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m\n"
- + "Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To\n"
- + "A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY\n"
- + "2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz\n"
- + "vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP\n"
- + "m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp\n"
- + "ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh\n"
- + "Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs\n"
- + "+/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN\n"
- + "cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy\n"
- + "qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+\n" + "cQ==\n"
- + "-----END CERTIFICATE REQUEST-----";
+ String csr = """
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl
+ MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY
+ MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA
+ dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4
+ GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m
+ Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To
+ A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY
+ 2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz
+ vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP
+ m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp
+ ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh
+ Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs
+ +/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN
+ cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy
+ qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+
+ cQ==
+ -----END CERTIFICATE REQUEST-----""";
VaultCertificateRequest request = VaultCertificateRequest.builder()
.commonName("hello.example.com")
@@ -302,27 +307,30 @@ class VaultPkiTemplateIntegrationTests extends IntegrationTestSupport {
@Test
@RequiresVaultVersion("1.14.2")
void signShouldFailWithUnknownUserIds() {
- String csr = "-----BEGIN CERTIFICATE REQUEST-----\n"
- + "MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl\n"
- + "MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY\n"
- + "MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA\n"
- + "dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4\n"
- + "GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m\n"
- + "Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To\n"
- + "A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY\n"
- + "2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz\n"
- + "vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP\n"
- + "m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp\n"
- + "ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh\n"
- + "Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs\n"
- + "+/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN\n"
- + "cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy\n"
- + "qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+\n" + "cQ==\n"
- + "-----END CERTIFICATE REQUEST-----";
+
+ String csr = """
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl
+ MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY
+ MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA
+ dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4
+ GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m
+ Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To
+ A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY
+ 2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz
+ vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP
+ m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp
+ ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh
+ Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs
+ +/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN
+ cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy
+ qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+
+ cQ==
+ -----END CERTIFICATE REQUEST-----""";
VaultCertificateRequest request = VaultCertificateRequest.builder()
.commonName("hello.example.com")
- .userIds("test1,test2")
+ .userIds(List.of("test1", "test2"))
.build();
assertThatThrownBy(() -> this.pkiOperations.signCertificateRequest("testrole", csr, request))
@@ -333,27 +341,29 @@ class VaultPkiTemplateIntegrationTests extends IntegrationTestSupport {
@Test
@RequiresVaultVersion("1.14.2")
void signShouldSignWithKnownUserIds() {
- String csr = "-----BEGIN CERTIFICATE REQUEST-----\n"
- + "MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl\n"
- + "MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY\n"
- + "MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA\n"
- + "dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4\n"
- + "GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m\n"
- + "Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To\n"
- + "A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY\n"
- + "2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz\n"
- + "vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP\n"
- + "m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp\n"
- + "ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh\n"
- + "Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs\n"
- + "+/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN\n"
- + "cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy\n"
- + "qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+\n" + "cQ==\n"
- + "-----END CERTIFICATE REQUEST-----";
+ String csr = """
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl
+ MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY
+ MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA
+ dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4
+ GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m
+ Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To
+ A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY
+ 2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz
+ vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP
+ m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp
+ ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh
+ Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs
+ +/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN
+ cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy
+ qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+
+ cQ==
+ -----END CERTIFICATE REQUEST-----""";
VaultCertificateRequest request = VaultCertificateRequest.builder()
.commonName("hello.example.com")
- .userIds("robot,humanoid")
+ .userIds(Arrays.asList("robot", "humanoid"))
.build();
VaultSignCertificateRequestResponse certificateResponse = this.pkiOperations.signCertificateRequest("testrole",
@@ -369,23 +379,25 @@ class VaultPkiTemplateIntegrationTests extends IntegrationTestSupport {
@Test
void signShouldSignCsr() {
- String csr = "-----BEGIN CERTIFICATE REQUEST-----\n"
- + "MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl\n"
- + "MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY\n"
- + "MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA\n"
- + "dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4\n"
- + "GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m\n"
- + "Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To\n"
- + "A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY\n"
- + "2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz\n"
- + "vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP\n"
- + "m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp\n"
- + "ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh\n"
- + "Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs\n"
- + "+/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN\n"
- + "cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy\n"
- + "qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+\n" + "cQ==\n"
- + "-----END CERTIFICATE REQUEST-----";
+ String csr = """
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRl
+ MRUwEwYDVQQHEwxTYW4gVmF1bHRpbm8xFTATBgNVBAoTDFNwcmluZyBWYXVsdDEY
+ MBYGA1UEAxMPY3NyLmV4YW1wbGUuY29tMRswGQYJKoZIhvcNAQkBFgxzcHJpbmdA
+ dmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVlDBT1gAONIp4
+ GQQ7BWDeqNzlscWqu5oQyfvw6oNFZzYWGVTgX/n72biv8d1Wx30MWpVYhbL0mk9m
+ Uu15elMZHPb4F4bk8VDSiB9527SwAd/QpkNC1RsPp2h6g2LvGPJ2eidHSlLtF2To
+ A4i6z0K0++nvYKSf9Af0sod2Z51xc9uPj/oN5z/8BQuGoCBpxJqgl7N/csMICixY
+ 2fQcCUbdPPqE9INIInUHe3mPE/yvxko9aYGZ5jnrdZyiQaRRKBdWpvbRLKXQ78Fz
+ vXR3G33yn9JAN6wl1A916DiXzy2xHT19vyAn1hBUj2M6KFXChQ30oxTyTOqHCMLP
+ m/BSEOsPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAYFssueiUh3YGxnXcQ4dp
+ ZqVWeVyOuGGaFJ4BA0drwJ9Mt/iNmPUTGE2oBNnh2R7e7HwGcNysFHZZOZBEQ0Hh
+ Vn93GO7cfaTOetK0VtDqis1VFQD0eVPWf5s6UqT/+XGrFRhwJ9hM+2FQSrUDFecs
+ +/605n1rD7qOj3vkGrtwvEUrxyRaQaKpPLHmVHENqV6F1NsO3Z27f2FWWAZF2VKN
+ cCQQJNc//DbIN3J3JSElpIDBDHctoBoQVnMiwpCbSA+CaAtlWYJKnAfhTKeqnNMy
+ qf3ACZ+1sBIuqSP7dEJ2KfIezaCPQ88+PAloRB52LFa+iq3yI7F5VzkwAvQFnTi+
+ cQ==
+ -----END CERTIFICATE REQUEST-----""";
VaultCertificateRequest request = VaultCertificateRequest.create("hello.example.com");
@@ -450,6 +462,7 @@ class VaultPkiTemplateIntegrationTests extends IntegrationTestSupport {
@Test
void shouldReturnCA() throws Exception {
+
VaultIssuerCertificateRequestResponse certificateResponse = this.pkiOperations.getIssuerCertificate("default");
Certificate data = certificateResponse.getRequiredData();