diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java
index 00f769a5..ecaa5062 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java
@@ -23,6 +23,7 @@ import org.springframework.vault.support.Hmac;
import org.springframework.vault.support.Plaintext;
import org.springframework.vault.support.RawTransitKey;
import org.springframework.vault.support.Signature;
+import org.springframework.vault.support.SignatureValidation;
import org.springframework.vault.support.TransitKeyType;
import org.springframework.vault.support.VaultDecryptionResult;
import org.springframework.vault.support.VaultEncryptionResult;
@@ -40,6 +41,7 @@ import org.springframework.vault.support.VaultTransitKeyCreationRequest;
* @author Mark Paluch
* @author Sven Schürmann
* @author Praveendra Singh
+ * @author Luander Ribeiro
* @see Transit
* Secret Backend
*/
@@ -229,59 +231,77 @@ public interface VaultTransitOperations {
String rewrap(String keyName, String ciphertext, VaultTransitContext transitContext);
/**
- * Generate HMAC digest of given data.
+ * Create a HMAC using {@code keyName} of given {@link Plaintext} using the default
+ * hash algorithm. The key can be of any type supported by transit; the raw key will
+ * be marshaled into bytes to be used for the HMAC function. If the key is of a type
+ * that supports rotation, the latest (current) version will be used.
+ *
+ * @param keyName must not be empty or {@literal null}.
+ * @param plaintext must not be {@literal null}.
+ * @return the digest of given data the default hash algorithm and the named key.
+ * @since 2.0
+ */
+ Hmac getHmac(String keyName, Plaintext plaintext);
+
+ /**
+ * Create a HMAC using {@code keyName} of given {@link VaultHmacRequest} using the
+ * default hash algorithm. The key can be of any type supported by transit; the raw
+ * key will be marshaled into bytes to be used for the HMAC function. If the key is of
+ * a type that supports rotation, configured {@link VaultHmacRequest#getKeyVersion()}
+ * will be used.
+ *
+ * @param keyName must not be empty or {@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.
+ * @since 2.0
+ */
+ Hmac getHmac(String keyName, VaultHmacRequest request);
+
+ /**
+ * Create a cryptographic signature using {@code keyName} of the given
+ * {@link Plaintext} and the default hash algorithm. The key must be of a type that
+ * supports signing.
*
* @param keyName must not be empty or {@literal null}.
* @param plaintext must not be empty or {@literal null}.
- * @return the digest of given data using sha2-256 hash algorithm and the named key.
- */
- Hmac generateHmac(String keyName, Plaintext plaintext);
-
- /**
- * Generate HMAC digest of given data.
- *
- * @param keyName must not be empty or {@literal null}.
- * @param request {@link VaultHmacRequest} must not be empty or {@literal null}.
- * @return the digest of given data using the specified hash algorithm and the named key.
- */
- Hmac generateHmac(String keyName, VaultHmacRequest request);
-
- /**
- * Sign a String using a key from the vault using the SHA-256 algorithm.
- *
- * @param keyName must not be empty or {@literal null}.
- * @param plaintext must not be empty or {@literal null}.
- * @return Signature of the payload
+ * @return Signature for {@link Plaintext}.
+ * @since 2.0
*/
Signature sign(String keyName, Plaintext plaintext);
/**
- * Sign a String using a key from the vault.
+ * Create a cryptographic signature using {@code keyName} of the given
+ * {@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 request {@link VaultSignRequest}
- * must not be empty or {@literal null}.
- * @return Signature of the payload
+ * @param request {@link VaultSignRequest} must not be empty or {@literal null}.
+ * @return Signature for {@link VaultSignRequest}.
+ * @since 2.0
*/
Signature sign(String keyName, VaultSignRequest request);
/**
- * Verify the validity of a signature in the vault.
+ * Verify the cryptographic signature using {@code keyName} of the given
+ * {@link Plaintext} and {@link Signature}.
*
* @param keyName must not be empty or {@literal null}.
- * @param plaintext must not be empty or {@literal null}.
- * @param signature Signature to be verified
- * @return true if the signature is valid, false otherwise
+ * @param plaintext must not be {@literal null}.
+ * @param signature Signature to be verified, must not be {@literal null}.
+ * @return {@literal true} if the signature is valid, {@literal false} otherwise.
+ * @since 2.0
*/
boolean verify(String keyName, Plaintext plaintext, Signature signature);
/**
- * Verify the validity of a signature in the vault.
+ * Verify the cryptographic signature using {@code keyName} of the given
+ * {@link VaultSignRequest}.
*
* @param keyName must not be empty or {@literal null}.
- * @param request {@link VaultSignatureVerificationRequest}
- * must not be empty or {@literal null}.
- * @return true if the signature is valid, false otherwise
+ * @param request {@link VaultSignatureVerificationRequest} must not be
+ * {@literal null}.
+ * @return the resulting {@link SignatureValidation}.
+ * @since 2.0
*/
- boolean verify(String keyName, VaultSignatureVerificationRequest request);
+ SignatureValidation verify(String keyName, VaultSignatureVerificationRequest request);
}
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java
index c3fb36f2..e403ffb5 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java
@@ -35,6 +35,7 @@ import org.springframework.vault.support.Hmac;
import org.springframework.vault.support.Plaintext;
import org.springframework.vault.support.RawTransitKey;
import org.springframework.vault.support.Signature;
+import org.springframework.vault.support.SignatureValidation;
import org.springframework.vault.support.TransitKeyType;
import org.springframework.vault.support.VaultDecryptionResult;
import org.springframework.vault.support.VaultEncryptionResult;
@@ -62,8 +63,6 @@ public class VaultTransitTemplate implements VaultTransitOperations {
private final String path;
- private static final String DEFAULT_SIGN_ALGORITHM = "sha2-256";
-
public VaultTransitTemplate(VaultOperations vaultOperations, String path) {
Assert.notNull(vaultOperations, "VaultOperations must not be null");
@@ -349,33 +348,48 @@ public class VaultTransitTemplate implements VaultTransitOperations {
}
@Override
- public Hmac generateHmac(String keyName, Plaintext plaintext) {
+ public Hmac getHmac(String keyName, Plaintext plaintext) {
+ Assert.hasText(keyName, "KeyName must not be empty");
Assert.notNull(plaintext, "Plaintext must not be null");
- VaultHmacRequest request = VaultHmacRequest.ofInput(plaintext);
+ VaultHmacRequest request = VaultHmacRequest.create(plaintext);
- return generateHmac(keyName, request);
+ return getHmac(keyName, request);
}
@Override
- public Hmac generateHmac(String keyName, VaultHmacRequest hmacRequest) {
+ public Hmac getHmac(String keyName, VaultHmacRequest hmacRequest) {
Assert.hasText(keyName, "KeyName must not be empty");
- Assert.notNull(hmacRequest, "Request must not be null");
+ Assert.notNull(hmacRequest, "HMAC request must not be null");
- String hmac = (String) vaultOperations.
- write(String.format("%s/hmac/%s", path, keyName), hmacRequest).getData()
- .get("hmac");
- return toHmac(hmac, hmacRequest.getContext());
+ Map request = new LinkedHashMap<>();
+ request.put("input",
+ Base64Utils.encodeToString(hmacRequest.getPlaintext().getPlaintext()));
+
+ if (StringUtils.hasText(hmacRequest.getAlgorithm())) {
+ request.put("algorithm", hmacRequest.getAlgorithm());
+ }
+
+ if (hmacRequest.getKeyVersion() != null) {
+ request.put("key_version ", hmacRequest.getKeyVersion());
+ }
+
+ String hmac = (String) vaultOperations
+ .write(String.format("%s/hmac/%s", path, keyName), request)
+ .getRequiredData().get("hmac");
+
+ return Hmac.of(hmac);
}
@Override
public Signature sign(String keyName, Plaintext plaintext) {
+ Assert.hasText(keyName, "KeyName must not be empty");
Assert.notNull(plaintext, "Plaintext must not be null");
- VaultSignRequest request = VaultSignRequest.ofInput(plaintext);
+ VaultSignRequest request = VaultSignRequest.create(plaintext);
return sign(keyName, request);
}
@@ -384,36 +398,67 @@ public class VaultTransitTemplate implements VaultTransitOperations {
public Signature sign(String keyName, VaultSignRequest signRequest) {
Assert.hasText(keyName, "KeyName must not be empty");
- Assert.notNull(signRequest, "Plain text must not be null");
+ Assert.notNull(signRequest, "Sign request must not be null");
- String signature = (String) vaultOperations.
- write(String.format("%s/sign/%s", path, keyName), signRequest).getData()
- .get("signature");
- return toSignature(signature, signRequest.getContext());
+ Map request = new LinkedHashMap<>();
+ request.put("input",
+ Base64Utils.encodeToString(signRequest.getPlaintext().getPlaintext()));
+
+ if (StringUtils.hasText(signRequest.getAlgorithm())) {
+ request.put("algorithm", signRequest.getAlgorithm());
+ }
+
+ String signature = (String) vaultOperations
+ .write(String.format("%s/sign/%s", path, keyName), request)
+ .getRequiredData().get("signature");
+
+ return Signature.of(signature);
}
@Override
public boolean verify(String keyName, Plaintext plainText, Signature signature) {
+ Assert.hasText(keyName, "KeyName must not be empty");
+ Assert.notNull(plainText, "Plaintext must not be null");
Assert.notNull(signature, "Signature must not be null");
- Assert.notNull(plainText, "Input must not be null");
- VaultSignatureVerificationRequest request =
- VaultSignatureVerificationRequest.builder()
- .input(plainText)
- .signature(signature)
- .build();
- return verify(keyName, request);
+ VaultSignatureVerificationRequest request = VaultSignatureVerificationRequest
+ .create(plainText, signature);
+ return verify(keyName, request).isValid();
}
@Override
- public boolean verify(String keyName, VaultSignatureVerificationRequest request) {
+ public SignatureValidation verify(String keyName,
+ VaultSignatureVerificationRequest verificationRequest) {
- Assert.notNull(request, "Request must not be null");
+ Assert.hasText(keyName, "KeyName must not be empty");
+ Assert.notNull(verificationRequest,
+ "Signature verification request must not be null");
- return (boolean) vaultOperations.
- write(String.format("%s/verify/%s", path, keyName), request).getData()
- .get("valid");
+ Map request = new LinkedHashMap<>();
+ request.put("input", Base64Utils.encodeToString(verificationRequest
+ .getPlaintext().getPlaintext()));
+
+ if (verificationRequest.getHmac() != null) {
+ request.put("hmac", verificationRequest.getHmac().getHmac());
+ }
+
+ if (verificationRequest.getSignature() != null) {
+ request.put("signature", verificationRequest.getSignature().getSignature());
+ }
+
+ if (StringUtils.hasText(verificationRequest.getAlgorithm())) {
+ request.put("algorithm", verificationRequest.getAlgorithm());
+ }
+
+ Map response = vaultOperations.write(
+ String.format("%s/verify/%s", path, keyName), request).getRequiredData();
+
+ if (response.containsKey("valid") && Boolean.valueOf("" + response.get("valid"))) {
+ return SignatureValidation.valid();
+ }
+
+ return SignatureValidation.invalid();
}
private static void applyTransitOptions(VaultTransitContext context,
@@ -507,16 +552,6 @@ public class VaultTransitTemplate implements VaultTransitOperations {
.of(plaintext);
}
- private static Hmac toHmac(String plaintext, VaultTransitContext context) {
- return context != null ? Hmac.of(plaintext).with(context) : Hmac
- .of(plaintext);
- }
-
- private static Signature toSignature(String plaintext, VaultTransitContext context) {
- return context != null ? Signature.of(plaintext).with(context) : Signature
- .of(plaintext);
- }
-
@SuppressWarnings("unchecked")
private static List