Support prehashed for the Transit engine.
Closes gh-745 Original pull request: gh-791
This commit is contained in:
@@ -425,7 +425,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
static Map<String, Object> toRequestBody(VaultSignRequest signRequest) {
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>(3);
|
||||
Map<String, Object> request = new LinkedHashMap<>(4);
|
||||
PropertyMapper mapper = PropertyMapper.get();
|
||||
|
||||
mapper.from(signRequest.getPlaintext()::getPlaintext)
|
||||
@@ -433,6 +433,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
.to("input", request);
|
||||
mapper.from(signRequest::getHashAlgorithm).whenHasText().to("hash_algorithm", request);
|
||||
mapper.from(signRequest::getSignatureAlgorithm).whenHasText().to("signature_algorithm", request);
|
||||
mapper.from(signRequest::isPrehashed).to("prehashed", request);
|
||||
|
||||
return request;
|
||||
}
|
||||
@@ -482,6 +483,7 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
.to("signature", request);
|
||||
mapper.from(verificationRequest::getHashAlgorithm).whenHasText().to("hash_algorithm", request);
|
||||
mapper.from(verificationRequest::getSignatureAlgorithm).whenHasText().to("signature_algorithm", request);
|
||||
mapper.from(verificationRequest::isPrehashed).to("prehashed", request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.springframework.vault.support;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.vault.support;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -36,11 +34,15 @@ public class VaultSignRequest {
|
||||
|
||||
private final @Nullable String signatureAlgorithm;
|
||||
|
||||
private VaultSignRequest(Plaintext plaintext, @Nullable String hashAlgorithm, @Nullable String signatureAlgorithm) {
|
||||
private final boolean prehashed;
|
||||
|
||||
private VaultSignRequest(Plaintext plaintext, @Nullable String hashAlgorithm, @Nullable String signatureAlgorithm,
|
||||
boolean prehashed) {
|
||||
|
||||
this.plaintext = plaintext;
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
this.prehashed = prehashed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +99,13 @@ public class VaultSignRequest {
|
||||
return getSignatureAlgorithm();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the input is already hashed.
|
||||
*/
|
||||
public boolean isPrehashed() {
|
||||
return this.prehashed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder to build a {@link VaultSignRequest}.
|
||||
*/
|
||||
@@ -108,6 +117,8 @@ public class VaultSignRequest {
|
||||
|
||||
private @Nullable String signatureAlgorithm;
|
||||
|
||||
private boolean prehashed;
|
||||
|
||||
/**
|
||||
* Configure the input to be used to create the signature.
|
||||
* @param input base input to create the signature, must not be {@literal null}.
|
||||
@@ -166,16 +177,27 @@ public class VaultSignRequest {
|
||||
return signatureAlgorithm(algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true when the input is already hashed. If the key type is rsa-2048,
|
||||
* rsa-3072 or rsa-4096, then the algorithm used to hash the input should be
|
||||
* indicated by the hash_algorithm parameter.
|
||||
* @param prehashed whether the input is already hashed
|
||||
* @return {@code this} {@link VaultSignRequestBuilder}.
|
||||
*/
|
||||
public VaultSignRequestBuilder prehashed(boolean prehashed) {
|
||||
this.prehashed = prehashed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a new {@link VaultSignRequest} instance. Requires
|
||||
* {@link #plaintext(Plaintext)} to be configured.
|
||||
* @return a new {@link VaultSignRequest}.
|
||||
*/
|
||||
public VaultSignRequest build() {
|
||||
|
||||
Assert.notNull(this.plaintext, "Plaintext input must not be null");
|
||||
|
||||
return new VaultSignRequest(this.plaintext, this.hashAlgorithm, this.signatureAlgorithm);
|
||||
return new VaultSignRequest(this.plaintext, this.hashAlgorithm, this.signatureAlgorithm, this.prehashed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.vault.support;
|
||||
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -39,14 +40,17 @@ public class VaultSignatureVerificationRequest {
|
||||
|
||||
private final @Nullable String signatureAlgorithm;
|
||||
|
||||
private final boolean prehashed;
|
||||
|
||||
private VaultSignatureVerificationRequest(Plaintext plaintext, @Nullable Signature signature, @Nullable Hmac hmac,
|
||||
@Nullable String hashAlgorithm, @Nullable String signatureAlgorithm) {
|
||||
@Nullable String hashAlgorithm, @Nullable String signatureAlgorithm, boolean prehashed) {
|
||||
|
||||
this.plaintext = plaintext;
|
||||
this.signature = signature;
|
||||
this.hmac = hmac;
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
this.prehashed = prehashed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,6 +140,13 @@ public class VaultSignatureVerificationRequest {
|
||||
return getSignatureAlgorithm();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the input is already hashed.
|
||||
*/
|
||||
public boolean isPrehashed() {
|
||||
return this.prehashed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder to build a {@link VaultSignatureVerificationRequest}.
|
||||
*/
|
||||
@@ -151,6 +162,8 @@ public class VaultSignatureVerificationRequest {
|
||||
|
||||
private @Nullable String signatureAlgorithm;
|
||||
|
||||
private boolean prehashed;
|
||||
|
||||
/**
|
||||
* Configure the {@link Plaintext} input to be used to verify the signature.
|
||||
* @param input base input, must not be {@literal null}.
|
||||
@@ -230,6 +243,11 @@ public class VaultSignatureVerificationRequest {
|
||||
return this;
|
||||
}
|
||||
|
||||
public VaultSignatureVerificationRequestBuilder prehashed(boolean prehashed) {
|
||||
this.prehashed = prehashed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the algorithm to be used for the operation.
|
||||
* @param algorithm Specify the algorithm to be used for the operation. Supported
|
||||
@@ -255,7 +273,7 @@ public class VaultSignatureVerificationRequest {
|
||||
Assert.isTrue(this.hmac != null || this.signature != null, "Either Signature or Hmac must not be null");
|
||||
|
||||
return new VaultSignatureVerificationRequest(this.input, this.signature, this.hmac, this.hashAlgorithm,
|
||||
this.signatureAlgorithm);
|
||||
this.signatureAlgorithm, this.prehashed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package org.springframework.vault.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -29,7 +32,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
@@ -807,6 +809,54 @@ class VaultTransitTemplateIntegrationTests extends IntegrationTestSupport {
|
||||
assertThat(signature.getSignature()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresVaultVersion(SIGN_VERIFY_INTRODUCED_IN_VERSION)
|
||||
void signAndVerifyWithPrehashedInput() {
|
||||
String keyName = createEcdsaP256Key();
|
||||
Plaintext plaintext = Plaintext.of("P8m2iUWdc4+MiKOkiqnjNUIBa3pAUuABqqU2/KdIE8s=");
|
||||
VaultSignRequest signRequest = VaultSignRequest.builder()
|
||||
.plaintext(plaintext)
|
||||
.signatureAlgorithm("pkcs1v15")
|
||||
.prehashed(true)
|
||||
.build();
|
||||
|
||||
Signature signature = this.transitOperations.sign(keyName, signRequest);
|
||||
assertThat(signature.getSignature()).isNotEmpty();
|
||||
|
||||
VaultSignatureVerificationRequest verifyRequest = VaultSignatureVerificationRequest.builder()
|
||||
.prehashed(true)
|
||||
.plaintext(plaintext)
|
||||
.signature(signature)
|
||||
.signatureAlgorithm("pkcs1v15")
|
||||
.build();
|
||||
SignatureValidation validation = this.transitOperations.verify(keyName, verifyRequest);
|
||||
assertThat(validation.isValid()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresVaultVersion(SIGN_VERIFY_INTRODUCED_IN_VERSION)
|
||||
void signWithPrehashedAndVerifyWithoutShouldFail() {
|
||||
String keyName = createEcdsaP256Key();
|
||||
Plaintext plaintext = Plaintext.of("P8m2iUWdc4+MiKOkiqnjNUIBa3pAUuABqqU2/KdIE8s=");
|
||||
VaultSignRequest signRequest = VaultSignRequest.builder()
|
||||
.plaintext(plaintext)
|
||||
.signatureAlgorithm("pkcs1v15")
|
||||
.prehashed(true)
|
||||
.build();
|
||||
|
||||
Signature signature = this.transitOperations.sign(keyName, signRequest);
|
||||
assertThat(signature.getSignature()).isNotEmpty();
|
||||
|
||||
VaultSignatureVerificationRequest verifyRequest = VaultSignatureVerificationRequest.builder()
|
||||
.prehashed(false)
|
||||
.plaintext(plaintext)
|
||||
.signature(signature)
|
||||
.signatureAlgorithm("pkcs1v15")
|
||||
.build();
|
||||
SignatureValidation validation = this.transitOperations.verify(keyName, verifyRequest);
|
||||
assertThat(validation.isValid()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresVaultVersion(SIGN_VERIFY_INTRODUCED_IN_VERSION)
|
||||
void shouldVerifyValidSignature() {
|
||||
|
||||
Reference in New Issue
Block a user