Polishing.
Reformat code. Rollback Jackson customizations on request objects in favor of explicit request body creaction. Reduce method visibility to avoid unintended exposure. See gh-620 Original pull request: gh-778
This commit is contained in:
@@ -38,6 +38,7 @@ import java.util.function.Function;
|
||||
* {@link #doWithVault(Function) without a session}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author James Luke
|
||||
* @since 2.0
|
||||
* @see #doWithSession(Function)
|
||||
* @see #doWithVault(Function)
|
||||
@@ -48,6 +49,21 @@ import java.util.function.Function;
|
||||
*/
|
||||
public interface ReactiveVaultOperations {
|
||||
|
||||
/**
|
||||
* @return the operations interface to interact with the Vault transit backend.
|
||||
* @since 3.1
|
||||
*/
|
||||
ReactiveVaultTransitOperations opsForTransit();
|
||||
|
||||
/**
|
||||
* Return {@link ReactiveVaultTransitOperations} if the transit backend is mounted on
|
||||
* a different path than {@code transit}.
|
||||
* @param path the mount path
|
||||
* @return the operations interface to interact with the Vault transit backend.
|
||||
* @since 3.1
|
||||
*/
|
||||
ReactiveVaultTransitOperations opsForTransit(String path);
|
||||
|
||||
/**
|
||||
* Read from a Vault path. Reading data using this method is suitable for API
|
||||
* calls/secret backends that do not require a request body.
|
||||
@@ -122,17 +138,4 @@ public interface ReactiveVaultOperations {
|
||||
<V, T extends Publisher<V>> T doWithSession(Function<WebClient, ? extends T> sessionCallback)
|
||||
throws VaultException, WebClientException;
|
||||
|
||||
/**
|
||||
* @return the operations interface to interact with the Vault transit backend.
|
||||
*/
|
||||
ReactiveVaultTransitOperations opsForTransit();
|
||||
|
||||
/**
|
||||
* Return {@link ReactiveVaultTransitOperations} if the transit backend is mounted on
|
||||
* a different path than {@code transit}.
|
||||
* @param path the mount path
|
||||
* @return the operations interface to interact with the Vault transit backend.
|
||||
*/
|
||||
ReactiveVaultTransitOperations opsForTransit(String path);
|
||||
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import static org.springframework.web.reactive.function.client.ExchangeFilterFun
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Raoof Mohammed
|
||||
* @author James Luke
|
||||
* @see SessionManager
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -226,6 +227,16 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactiveVaultTransitOperations opsForTransit() {
|
||||
return opsForTransit("transit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactiveVaultTransitOperations opsForTransit(String path) {
|
||||
return new ReactiveVaultTransitTemplate(this, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<VaultResponse> read(String path) {
|
||||
|
||||
@@ -365,14 +376,4 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactiveVaultTransitOperations opsForTransit() {
|
||||
return opsForTransit("transit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactiveVaultTransitOperations opsForTransit(String path) {
|
||||
return new ReactiveVaultTransitTemplate(this, path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,17 +37,18 @@ import reactor.core.publisher.Mono;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface that specifies a set of {@code transit} operations executed on a reactive
|
||||
* infrastructure, implemented by
|
||||
* {@link org.springframework.vault.core.ReactiveVaultTransitTemplate}.
|
||||
* * Interface that specifies operations using the {@code transit} backend.
|
||||
*
|
||||
* @author James Luke
|
||||
* @since 3.1
|
||||
* @see <a href="https://www.vaultproject.io/docs/secrets/transit/index.html">Transit
|
||||
* Secret Backend</a>
|
||||
*/
|
||||
public interface ReactiveVaultTransitOperations {
|
||||
|
||||
/**
|
||||
* Create a new named encryption key given a {@code name}
|
||||
* @param keyName must not be empty or {@literal null}
|
||||
* Create a new named encryption key given a {@code name}.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
*/
|
||||
Mono<Void> createKey(String keyName);
|
||||
|
||||
@@ -61,7 +62,8 @@ public interface ReactiveVaultTransitOperations {
|
||||
Mono<Void> createKey(String keyName, VaultTransitKeyCreationRequest createKeyRequest);
|
||||
|
||||
/**
|
||||
* @return stream of transit key names.
|
||||
* Get a {@link Flux} of transit key names.
|
||||
* @return {@link Flux} of transit key names.
|
||||
*/
|
||||
Flux<String> getKeys();
|
||||
|
||||
@@ -78,14 +80,14 @@ public interface ReactiveVaultTransitOperations {
|
||||
* operation.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
* @return the {@link RawTransitKey}. May be empty if key does not exist
|
||||
* @return the {@link RawTransitKey}. Empty if key does not exist
|
||||
*/
|
||||
Mono<RawTransitKey> exportKey(String keyName, TransitKeyType type);
|
||||
|
||||
/**
|
||||
* Return information about a named encryption key.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @return the {@link VaultTransitKey}. May be empty if key does not exist
|
||||
* @return the {@link VaultTransitKey}. Empty if key does not exist.
|
||||
*/
|
||||
Mono<VaultTransitKey> getKey(String keyName);
|
||||
|
||||
@@ -230,10 +232,10 @@ public interface ReactiveVaultTransitOperations {
|
||||
* a type that supports rotation, configured {@link VaultHmacRequest#getKeyVersion()}
|
||||
* will be used.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param hmacRequest the {@link VaultHmacRequest}, must not be {@literal null}.
|
||||
* @param request the {@link VaultHmacRequest}, must not be {@literal null}.
|
||||
* @return the digest of given data the default hash algorithm and the named key.
|
||||
*/
|
||||
Mono<Hmac> getHmac(String keyName, VaultHmacRequest hmacRequest);
|
||||
Mono<Hmac> getHmac(String keyName, VaultHmacRequest request);
|
||||
|
||||
/**
|
||||
* Create a cryptographic signature using {@code keyName} of the given
|
||||
@@ -250,10 +252,10 @@ public interface ReactiveVaultTransitOperations {
|
||||
* {@link VaultSignRequest} and the specified hash algorithm. The key must be of a
|
||||
* type that supports signing.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param signRequest {@link VaultSignRequest} must not be empty or {@literal null}.
|
||||
* @param request {@link VaultSignRequest} must not be empty or {@literal null}.
|
||||
* @return Signature for {@link VaultSignRequest}.
|
||||
*/
|
||||
Mono<Signature> sign(String keyName, VaultSignRequest signRequest);
|
||||
Mono<Signature> sign(String keyName, VaultSignRequest request);
|
||||
|
||||
/**
|
||||
* Verify the cryptographic signature using {@code keyName} of the given
|
||||
@@ -269,10 +271,10 @@ public interface ReactiveVaultTransitOperations {
|
||||
* Verify the cryptographic signature using {@code keyName} of the given
|
||||
* {@link VaultSignRequest}.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param verificationRequest {@link VaultSignatureVerificationRequest} must not be
|
||||
* @param request {@link VaultSignatureVerificationRequest} must not be
|
||||
* {@literal null}.
|
||||
* @return the resulting {@link SignatureValidation}.
|
||||
*/
|
||||
Mono<SignatureValidation> verify(String keyName, VaultSignatureVerificationRequest verificationRequest);
|
||||
Mono<SignatureValidation> verify(String keyName, VaultSignatureVerificationRequest request);
|
||||
|
||||
}
|
||||
|
||||
@@ -47,9 +47,10 @@ import java.util.Map;
|
||||
import static org.springframework.vault.core.VaultTransitTemplate.*;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ReactiveVaultTransitOperations}
|
||||
* Default implementation of {@link ReactiveVaultTransitOperations}.
|
||||
*
|
||||
* @author James Luke
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperations {
|
||||
|
||||
@@ -58,6 +59,7 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
private final String path;
|
||||
|
||||
public ReactiveVaultTransitTemplate(ReactiveVaultOperations reactiveVaultOperations, String path) {
|
||||
|
||||
Assert.notNull(reactiveVaultOperations, "ReactiveVaultOperations must not be null");
|
||||
Assert.hasText(path, "Path must not be empty");
|
||||
|
||||
@@ -67,6 +69,7 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
|
||||
@Override
|
||||
public Mono<Void> createKey(String keyName) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/keys/%s", this.path, keyName), null).then();
|
||||
@@ -74,15 +77,17 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
|
||||
@Override
|
||||
public Mono<Void> createKey(String keyName, VaultTransitKeyCreationRequest createKeyRequest) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(createKeyRequest, "VaultTransitKeyCreationRequest must not be empty");
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/keys/%s", this.path, keyName), createKeyRequest)
|
||||
.then();
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> rotate(String keyName) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/keys/%s/rotate", this.path, keyName), null).then();
|
||||
@@ -90,6 +95,7 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
|
||||
@Override
|
||||
public Mono<String> encrypt(String keyName, String plaintext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(plaintext, "Plaintext must not be null");
|
||||
|
||||
@@ -98,20 +104,23 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
request.put("plaintext", Base64.getEncoder().encodeToString(plaintext.getBytes()));
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/encrypt/%s", this.path, keyName), request)
|
||||
.map(it -> (String) it.getRequiredData().get("ciphertext"));
|
||||
.map(it -> (String) it.getRequiredData().get("ciphertext"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> configureKey(String keyName, VaultTransitKeyConfiguration keyConfiguration) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(keyConfiguration, "VaultKeyConfiguration must not be empty");
|
||||
|
||||
return this.reactiveVaultOperations
|
||||
.write(String.format("%s/keys/%s/config", this.path, keyName), keyConfiguration).then();
|
||||
.write(String.format("%s/keys/%s/config", this.path, keyName), keyConfiguration)
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteKey(String keyName) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
|
||||
return this.reactiveVaultOperations.delete(String.format("%s/keys/%s", this.path, keyName));
|
||||
@@ -121,11 +130,12 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
@SuppressWarnings("unchecked")
|
||||
public Flux<String> getKeys() {
|
||||
return this.reactiveVaultOperations.read(String.format("%s/keys?list=true", this.path))
|
||||
.flatMapIterable(it -> (List<String>) it.getRequiredData().get("keys"));
|
||||
.flatMapIterable(it -> (List<String>) it.getRequiredData().get("keys"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> encrypt(String keyName, byte[] plaintext, VaultTransitContext transitContext) {
|
||||
|
||||
Assert.notNull(plaintext, "Plaintext must not be null");
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(transitContext, "VaultTransitContext must not be null");
|
||||
@@ -137,20 +147,22 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
applyTransitOptions(transitContext, request);
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/encrypt/%s", this.path, keyName), request)
|
||||
.map(it -> (String) it.getRequiredData().get("ciphertext"));
|
||||
.map(it -> (String) it.getRequiredData().get("ciphertext"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Ciphertext> encrypt(String keyName, Plaintext plaintext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(plaintext, "Plaintext must not be null");
|
||||
|
||||
return encrypt(keyName, plaintext.getPlaintext(), plaintext.getContext())
|
||||
.map(ciphertext -> toCiphertext(ciphertext, plaintext.getContext()));
|
||||
.map(ciphertext -> toCiphertext(ciphertext, plaintext.getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> decrypt(String keyName, String ciphertext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.hasText(ciphertext, "Ciphertext must not be empty");
|
||||
|
||||
@@ -159,21 +171,23 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
request.put("ciphertext", ciphertext);
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/decrypt/%s", this.path, keyName), request)
|
||||
.map(it -> (String) it.getRequiredData().get("plaintext"))
|
||||
.map(plaintext -> new String(Base64.getDecoder().decode(plaintext)));
|
||||
.map(it -> (String) it.getRequiredData().get("plaintext"))
|
||||
.map(plaintext -> new String(Base64.getDecoder().decode(plaintext)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Plaintext> decrypt(String keyName, Ciphertext ciphertext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be null");
|
||||
Assert.notNull(ciphertext, "Ciphertext must not be null");
|
||||
|
||||
return decrypt(keyName, ciphertext.getCiphertext(), ciphertext.getContext())
|
||||
.map(plaintext -> Plaintext.of(plaintext).with(ciphertext.getContext()));
|
||||
.map(plaintext -> Plaintext.of(plaintext).with(ciphertext.getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<byte[]> decrypt(String keyName, String ciphertext, VaultTransitContext transitContext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.hasText(ciphertext, "Ciphertext must not be empty");
|
||||
Assert.notNull(transitContext, "VaultTransitContext must not be null");
|
||||
@@ -185,11 +199,13 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
applyTransitOptions(transitContext, request);
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/decrypt/%s", this.path, keyName), request)
|
||||
.map(it -> (String) it.getRequiredData().get("plaintext")).map(Base64.getDecoder()::decode);
|
||||
.map(it -> (String) it.getRequiredData().get("plaintext"))
|
||||
.map(Base64.getDecoder()::decode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> rewrap(String keyName, String ciphertext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.hasText(ciphertext, "Ciphertext must not be empty");
|
||||
|
||||
@@ -197,11 +213,12 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
request.put("ciphertext", ciphertext);
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/rewrap/%s", this.path, keyName), request)
|
||||
.map(response -> (String) response.getRequiredData().get("ciphertext"));
|
||||
.map(response -> (String) response.getRequiredData().get("ciphertext"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> rewrap(String keyName, String ciphertext, VaultTransitContext transitContext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.hasText(ciphertext, "Ciphertext must not be empty");
|
||||
Assert.notNull(transitContext, "VaultTransitContext must not be null");
|
||||
@@ -213,7 +230,7 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
applyTransitOptions(transitContext, request);
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/rewrap/%s", this.path, keyName), request)
|
||||
.map(response -> (String) response.getRequiredData().get("ciphertext"));
|
||||
.map(response -> (String) response.getRequiredData().get("ciphertext"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,14 +243,16 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
vaultRequest.put("plaintext", Base64.getEncoder().encodeToString(request.getPlaintext()));
|
||||
applyTransitOptions(request.getContext(), vaultRequest);
|
||||
return vaultRequest;
|
||||
}).collectList()
|
||||
.flatMap(batch -> this.reactiveVaultOperations.write(String.format("%s/encrypt/%s", this.path, keyName),
|
||||
Collections.singletonMap("batch_input", batch)))
|
||||
.flatMapIterable(vaultResponse -> toEncryptionResults(vaultResponse, batchRequest));
|
||||
})
|
||||
.collectList()
|
||||
.flatMap(batch -> this.reactiveVaultOperations.write(String.format("%s/encrypt/%s", this.path, keyName),
|
||||
Collections.singletonMap("batch_input", batch)))
|
||||
.flatMapIterable(vaultResponse -> toEncryptionResults(vaultResponse, batchRequest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<VaultDecryptionResult> decrypt(String keyName, List<Ciphertext> batchRequest) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notEmpty(batchRequest, "BatchRequest must not be null and must have at least one entry");
|
||||
|
||||
@@ -242,14 +261,16 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
vaultRequest.put("ciphertext", request.getCiphertext());
|
||||
applyTransitOptions(request.getContext(), vaultRequest);
|
||||
return vaultRequest;
|
||||
}).collectList()
|
||||
.flatMap(batch -> this.reactiveVaultOperations.write(String.format("%s/decrypt/%s", this.path, keyName),
|
||||
Collections.singletonMap("batch_input", batch)))
|
||||
.flatMapIterable(vaultResponse -> toDecryptionResults(vaultResponse, batchRequest));
|
||||
})
|
||||
.collectList()
|
||||
.flatMap(batch -> this.reactiveVaultOperations.write(String.format("%s/decrypt/%s", this.path, keyName),
|
||||
Collections.singletonMap("batch_input", batch)))
|
||||
.flatMapIterable(vaultResponse -> toDecryptionResults(vaultResponse, batchRequest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Hmac> getHmac(String keyName, Plaintext plaintext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(plaintext, "Plaintext must not be null");
|
||||
|
||||
@@ -260,15 +281,19 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
|
||||
@Override
|
||||
public Mono<Hmac> getHmac(String keyName, VaultHmacRequest hmacRequest) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(hmacRequest, "HMAC request must not be null");
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/hmac/%s", this.path, keyName), hmacRequest)
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData().get("hmac")).map(Hmac::of);
|
||||
return this.reactiveVaultOperations
|
||||
.write(String.format("%s/hmac/%s", this.path, keyName), toRequestBody(hmacRequest))
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData().get("hmac"))
|
||||
.map(Hmac::of);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Signature> sign(String keyName, Plaintext plaintext) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(plaintext, "Plaintext must not be null");
|
||||
|
||||
@@ -279,15 +304,19 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
|
||||
@Override
|
||||
public Mono<Signature> sign(String keyName, VaultSignRequest signRequest) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(signRequest, "Sign request must not be null");
|
||||
|
||||
return this.reactiveVaultOperations.write(String.format("%s/sign/%s", this.path, keyName), signRequest)
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData().get("signature")).map(Signature::of);
|
||||
return this.reactiveVaultOperations
|
||||
.write(String.format("%s/sign/%s", this.path, keyName), toRequestBody(signRequest))
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData().get("signature"))
|
||||
.map(Signature::of);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> verify(String keyName, Plaintext plaintext, Signature signature) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(plaintext, "Plaintext must not be null");
|
||||
Assert.notNull(signature, "Signature must not be null");
|
||||
@@ -299,36 +328,41 @@ public class ReactiveVaultTransitTemplate implements ReactiveVaultTransitOperati
|
||||
|
||||
@Override
|
||||
public Mono<SignatureValidation> verify(String keyName, VaultSignatureVerificationRequest verificationRequest) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(verificationRequest, "Signature verification request must not be null");
|
||||
|
||||
return this.reactiveVaultOperations
|
||||
.write(String.format("%s/verify/%s", this.path, keyName), verificationRequest)
|
||||
.map(VaultResponse::getRequiredData).map(vaultResponse -> {
|
||||
if (vaultResponse.containsKey("valid") && (Boolean) vaultResponse.get("valid")) {
|
||||
return SignatureValidation.valid();
|
||||
}
|
||||
return SignatureValidation.invalid();
|
||||
});
|
||||
.write(String.format("%s/verify/%s", this.path, keyName), toRequestBody(verificationRequest))
|
||||
.map(VaultResponse::getRequiredData)
|
||||
.map(vaultResponse -> {
|
||||
if (vaultResponse.containsKey("valid") && (Boolean) vaultResponse.get("valid")) {
|
||||
return SignatureValidation.valid();
|
||||
}
|
||||
return SignatureValidation.invalid();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<RawTransitKey> exportKey(String keyName, TransitKeyType type) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(type, "Key type must not be null");
|
||||
|
||||
return this.reactiveVaultOperations
|
||||
.read(String.format("%s/export/%s/%s", this.path, type.getValue(), keyName),
|
||||
VaultTransitTemplate.RawTransitKeyImpl.class)
|
||||
.flatMap(vaultResponse -> Mono.justOrEmpty(vaultResponse.getRequiredData()));
|
||||
.read(String.format("%s/export/%s/%s", this.path, type.getValue(), keyName),
|
||||
VaultTransitTemplate.RawTransitKeyImpl.class)
|
||||
.flatMap(vaultResponse -> Mono.justOrEmpty(vaultResponse.getRequiredData()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<VaultTransitKey> getKey(String keyName) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
|
||||
return this.reactiveVaultOperations
|
||||
.read(String.format("%s/keys/%s", this.path, keyName), VaultTransitKeyImpl.class)
|
||||
.map(VaultResponseSupport::getRequiredData);
|
||||
.read(String.format("%s/keys/%s", this.path, keyName), VaultTransitKeyImpl.class)
|
||||
.map(VaultResponseSupport::getRequiredData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ public interface VaultTransitOperations {
|
||||
byte[] decrypt(String keyName, String ciphertext, VaultTransitContext transitContext);
|
||||
|
||||
/**
|
||||
* Decrypts the provided barch of cipher text using the named key and context. The*
|
||||
* Decrypts the provided batch of cipher text using the named key and context. The*
|
||||
* decryption is done using transit backend's batch operation.
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param batchRequest a list of {@link Ciphertext} which includes plain text and an
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
package org.springframework.vault.core;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.vault.VaultException;
|
||||
@@ -42,6 +43,7 @@ import org.springframework.vault.support.VaultTransitKeyConfiguration;
|
||||
import org.springframework.vault.support.VaultTransitKeyCreationRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -166,7 +168,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
Map<String, String> request = new LinkedHashMap<>();
|
||||
|
||||
request.put("plaintext", Base64Utils.encodeToString(plaintext.getBytes()));
|
||||
request.put("plaintext", Base64.getEncoder().encodeToString(plaintext.getBytes()));
|
||||
|
||||
return (String) this.vaultOperations.write(String.format("%s/encrypt/%s", this.path, keyName), request)
|
||||
.getRequiredData()
|
||||
@@ -193,7 +195,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
Map<String, String> request = new LinkedHashMap<>();
|
||||
|
||||
request.put("plaintext", Base64Utils.encodeToString(plaintext));
|
||||
request.put("plaintext", Base64.getEncoder().encodeToString(plaintext));
|
||||
|
||||
applyTransitOptions(transitContext, request);
|
||||
|
||||
@@ -214,7 +216,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
Map<String, String> vaultRequest = new LinkedHashMap<>(2);
|
||||
|
||||
vaultRequest.put("plaintext", Base64Utils.encodeToString(request.getPlaintext()));
|
||||
vaultRequest.put("plaintext", Base64.getEncoder().encodeToString(request.getPlaintext()));
|
||||
|
||||
if (request.getContext() != null) {
|
||||
applyTransitOptions(request.getContext(), vaultRequest);
|
||||
@@ -244,7 +246,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
.getRequiredData()
|
||||
.get("plaintext");
|
||||
|
||||
return new String(Base64Utils.decodeFromString(plaintext));
|
||||
return new String(Base64.getDecoder().decode(plaintext));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,7 +278,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
.getRequiredData()
|
||||
.get("plaintext");
|
||||
|
||||
return Base64Utils.decodeFromString(plaintext);
|
||||
return Base64.getDecoder().decode(plaintext);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -355,12 +357,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(hmacRequest, "HMAC request must not be null");
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(3);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(hmacRequest.getPlaintext()::getPlaintext).as(Base64Utils::encodeToString).to("input", request);
|
||||
mapper.from(hmacRequest::getAlgorithm).whenHasText().to("algorithm", request);
|
||||
mapper.from(hmacRequest::getKeyVersion).whenNonNull().to("key_version", request);
|
||||
Map<String, Object> request = toRequestBody(hmacRequest);
|
||||
|
||||
String hmac = (String) this.vaultOperations.write(String.format("%s/hmac/%s", this.path, keyName), request)
|
||||
.getRequiredData()
|
||||
@@ -369,6 +366,20 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
return Hmac.of(hmac);
|
||||
}
|
||||
|
||||
static Map<String, Object> toRequestBody(VaultHmacRequest hmacRequest) {
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(3);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(hmacRequest.getPlaintext()::getPlaintext)
|
||||
.as(Base64.getEncoder()::encodeToString)
|
||||
.to("input", request);
|
||||
mapper.from(hmacRequest::getAlgorithm).whenHasText().to("algorithm", request);
|
||||
mapper.from(hmacRequest::getKeyVersion).whenNonNull().to("key_version", request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signature sign(String keyName, Plaintext plaintext) {
|
||||
|
||||
@@ -382,15 +393,11 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
@Override
|
||||
public Signature sign(String keyName, VaultSignRequest signRequest) {
|
||||
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(signRequest, "Sign request must not be null");
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(3);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(signRequest.getPlaintext()::getPlaintext).as(Base64Utils::encodeToString).to("input", request);
|
||||
mapper.from(signRequest::getHashAlgorithm).whenHasText().to("hash_algorithm", request);
|
||||
mapper.from(signRequest::getSignatureAlgorithm).whenHasText().to("signature_algorithm", request);
|
||||
Map<String, Object> request = toRequestBody(signRequest);
|
||||
|
||||
String signature = (String) this.vaultOperations.write(String.format("%s/sign/%s", this.path, keyName), request)
|
||||
.getRequiredData()
|
||||
@@ -399,6 +406,20 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
return Signature.of(signature);
|
||||
}
|
||||
|
||||
static Map<String, Object> toRequestBody(VaultSignRequest signRequest) {
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(3);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(signRequest.getPlaintext()::getPlaintext)
|
||||
.as(Base64.getEncoder()::encodeToString)
|
||||
.to("input", request);
|
||||
mapper.from(signRequest::getHashAlgorithm).whenHasText().to("hash_algorithm", request);
|
||||
mapper.from(signRequest::getSignatureAlgorithm).whenHasText().to("signature_algorithm", request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(String keyName, Plaintext plainText, Signature signature) {
|
||||
|
||||
@@ -416,19 +437,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
Assert.hasText(keyName, "Key name must not be empty");
|
||||
Assert.notNull(verificationRequest, "Signature verification request must not be null");
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(5);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(verificationRequest.getPlaintext()::getPlaintext)
|
||||
.as(Base64Utils::encodeToString)
|
||||
.to("input", request);
|
||||
mapper.from(verificationRequest::getHmac).whenNonNull().as(Hmac::getHmac).to("hmac", request);
|
||||
mapper.from(verificationRequest::getSignature)
|
||||
.whenNonNull()
|
||||
.as(Signature::getSignature)
|
||||
.to("signature", request);
|
||||
mapper.from(verificationRequest::getHashAlgorithm).whenHasText().to("hash_algorithm", request);
|
||||
mapper.from(verificationRequest::getSignatureAlgorithm).whenHasText().to("signature_algorithm", request);
|
||||
Map<String, Object> request = toRequestBody(verificationRequest);
|
||||
|
||||
Map<String, Object> response = this.vaultOperations
|
||||
.write(String.format("%s/verify/%s", this.path, keyName), request)
|
||||
@@ -441,19 +450,37 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
return SignatureValidation.invalid();
|
||||
}
|
||||
|
||||
public static void applyTransitOptions(VaultTransitContext context, Map<String, String> request) {
|
||||
static Map<String, Object> toRequestBody(VaultSignatureVerificationRequest verificationRequest) {
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(5);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(verificationRequest.getPlaintext()::getPlaintext)
|
||||
.as(Base64.getEncoder()::encodeToString)
|
||||
.to("input", request);
|
||||
mapper.from(verificationRequest::getHmac).whenNonNull().as(Hmac::getHmac).to("hmac", request);
|
||||
mapper.from(verificationRequest::getSignature)
|
||||
.whenNonNull()
|
||||
.as(Signature::getSignature)
|
||||
.to("signature", request);
|
||||
mapper.from(verificationRequest::getHashAlgorithm).whenHasText().to("hash_algorithm", request);
|
||||
mapper.from(verificationRequest::getSignatureAlgorithm).whenHasText().to("signature_algorithm", request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
static void applyTransitOptions(VaultTransitContext context, Map<String, String> request) {
|
||||
|
||||
if (!ObjectUtils.isEmpty(context.getContext())) {
|
||||
request.put("context", Base64Utils.encodeToString(context.getContext()));
|
||||
request.put("context", Base64.getEncoder().encodeToString(context.getContext()));
|
||||
}
|
||||
|
||||
if (!ObjectUtils.isEmpty(context.getNonce())) {
|
||||
request.put("nonce", Base64Utils.encodeToString(context.getNonce()));
|
||||
request.put("nonce", Base64.getEncoder().encodeToString(context.getNonce()));
|
||||
}
|
||||
}
|
||||
|
||||
public static List<VaultEncryptionResult> toEncryptionResults(VaultResponse vaultResponse,
|
||||
List<Plaintext> batchRequest) {
|
||||
static List<VaultEncryptionResult> toEncryptionResults(VaultResponse vaultResponse, List<Plaintext> batchRequest) {
|
||||
|
||||
List<VaultEncryptionResult> result = new ArrayList<>(batchRequest.size());
|
||||
List<Map<String, String>> batchData = getBatchData(vaultResponse);
|
||||
@@ -482,8 +509,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<VaultDecryptionResult> toDecryptionResults(VaultResponse vaultResponse,
|
||||
List<Ciphertext> batchRequest) {
|
||||
static List<VaultDecryptionResult> toDecryptionResults(VaultResponse vaultResponse, List<Ciphertext> batchRequest) {
|
||||
|
||||
List<VaultDecryptionResult> result = new ArrayList<>(batchRequest.size());
|
||||
List<Map<String, String>> batchData = getBatchData(vaultResponse);
|
||||
@@ -514,19 +540,19 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
if (StringUtils.hasText(data.get("plaintext"))) {
|
||||
|
||||
byte[] plaintext = Base64Utils.decodeFromString(data.get("plaintext"));
|
||||
byte[] plaintext = Base64.getDecoder().decode(data.get("plaintext"));
|
||||
return new VaultDecryptionResult(Plaintext.of(plaintext).with(ciphertext.getContext()));
|
||||
}
|
||||
|
||||
return new VaultDecryptionResult(Plaintext.empty().with(ciphertext.getContext()));
|
||||
}
|
||||
|
||||
public static Ciphertext toCiphertext(String ciphertext, @Nullable VaultTransitContext context) {
|
||||
static Ciphertext toCiphertext(String ciphertext, @Nullable VaultTransitContext context) {
|
||||
return context != null ? Ciphertext.of(ciphertext).with(context) : Ciphertext.of(ciphertext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Map<String, String>> getBatchData(VaultResponse vaultResponse) {
|
||||
static List<Map<String, String>> getBatchData(VaultResponse vaultResponse) {
|
||||
return (List<Map<String, String>>) vaultResponse.getRequiredData().get("batch_results");
|
||||
}
|
||||
|
||||
|
||||
@@ -31,14 +31,10 @@ import org.springframework.util.Assert;
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class VaultHmacRequest {
|
||||
|
||||
@JsonProperty("input")
|
||||
@JsonSerialize(converter = PlaintextToBase64StringConverter.class)
|
||||
private final Plaintext plaintext;
|
||||
|
||||
@JsonProperty("algorithm")
|
||||
private final @Nullable String algorithm;
|
||||
|
||||
@JsonProperty("key_version")
|
||||
private final @Nullable Integer keyVersion;
|
||||
|
||||
private VaultHmacRequest(Plaintext plaintext, @Nullable String algorithm, @Nullable Integer keyVersion) {
|
||||
|
||||
@@ -30,8 +30,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class VaultSignRequest {
|
||||
|
||||
@JsonProperty("input")
|
||||
@JsonSerialize(converter = PlaintextToBase64StringConverter.class)
|
||||
private final Plaintext plaintext;
|
||||
|
||||
private final @Nullable String hashAlgorithm;
|
||||
|
||||
@@ -15,16 +15,8 @@
|
||||
*/
|
||||
package org.springframework.vault.support;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.vault.support.VaultSignatureVerificationRequest.VaultSignatureVerificationRequestSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Request for a signature verification.
|
||||
@@ -35,7 +27,6 @@ import java.io.IOException;
|
||||
* @author James Luke
|
||||
* @since 2.0
|
||||
*/
|
||||
@JsonSerialize(using = VaultSignatureVerificationRequestSerializer.class)
|
||||
public class VaultSignatureVerificationRequest {
|
||||
|
||||
private final Plaintext plaintext;
|
||||
@@ -145,31 +136,6 @@ public class VaultSignatureVerificationRequest {
|
||||
return getSignatureAlgorithm();
|
||||
}
|
||||
|
||||
static class VaultSignatureVerificationRequestSerializer extends JsonSerializer<VaultSignatureVerificationRequest> {
|
||||
|
||||
static PlaintextToBase64StringConverter plaintextConverter = new PlaintextToBase64StringConverter();
|
||||
|
||||
@Override
|
||||
public void serialize(VaultSignatureVerificationRequest request, JsonGenerator gen,
|
||||
SerializerProvider serializers) throws IOException {
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("input", plaintextConverter.convert(request.plaintext));
|
||||
if (request.getHmac() != null) {
|
||||
gen.writeStringField("hmac", request.getHmac().getHmac());
|
||||
}
|
||||
|
||||
if (request.getSignature() != null) {
|
||||
gen.writeStringField("signature", request.getSignature().getSignature());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getAlgorithm())) {
|
||||
gen.writeStringField("algorithm", request.getAlgorithm());
|
||||
}
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder to build a {@link VaultSignatureVerificationRequest}.
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user