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 ac705fef..41c5d51f 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 @@ -17,12 +17,12 @@ package org.springframework.vault.core; import java.util.List; -import org.springframework.vault.support.VaultExportKeyTypes; +import org.springframework.vault.support.TransitKeyType; import org.springframework.vault.support.VaultTransitContext; import org.springframework.vault.support.VaultTransitKey; import org.springframework.vault.support.VaultTransitKeyConfiguration; import org.springframework.vault.support.VaultTransitKeyCreationRequest; -import org.springframework.vault.support.VaultTransitKeyExport; +import org.springframework.vault.support.RawTransitKey; /** * Interface that specifies operations using the {@code transit} backend. @@ -66,6 +66,17 @@ public interface VaultTransitOperations { */ void configureKey(String keyName, VaultTransitKeyConfiguration keyConfiguration); + /** + * Returns the value of the named encryption key. Depending on the type of key, + * different information may be returned. The key must be exportable to support this + * operation. + * + * @param keyName must not be empty or {@literal null}. + * @param type must not be {@literal null}. + * @return the {@link RawTransitKey}. + */ + RawTransitKey exportKey(String keyName, TransitKeyType type); + /** * Return information about a named encryption key. * @@ -82,18 +93,6 @@ public interface VaultTransitOperations { */ void deleteKey(String keyName); - /** - * Returns the value of the named encryption key. Depending on the type of key, - * different information may be returned. The key must be exportable to support this - * operation. - * - * @param keyName must not be empty or {@literal null}. - * @param vaultExportKeyTypes must not be {@literal null}. - * @return the {@link VaultTransitKeyExport}. - */ - VaultTransitKeyExport exportKey(String keyName, - VaultExportKeyTypes vaultExportKeyTypes); - /** * Rotates the version of the named key. After rotation, new plaintext requests will * be encrypted with the new version of the key. To upgrade ciphertext to be encrypted 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 3214e5fe..96383ae9 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 @@ -25,14 +25,14 @@ import lombok.Data; import org.springframework.util.Assert; import org.springframework.util.Base64Utils; -import org.springframework.vault.support.VaultExportKeyTypes; +import org.springframework.vault.support.TransitKeyType; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; import org.springframework.vault.support.VaultTransitContext; import org.springframework.vault.support.VaultTransitKey; import org.springframework.vault.support.VaultTransitKeyConfiguration; import org.springframework.vault.support.VaultTransitKeyCreationRequest; -import org.springframework.vault.support.VaultTransitKeyExport; +import org.springframework.vault.support.RawTransitKey; /** * Default implementation of {@link VaultTransitOperations}. @@ -64,8 +64,7 @@ public class VaultTransitTemplate implements VaultTransitOperations { } @Override - public void createKey(String keyName, - VaultTransitKeyCreationRequest createKeyRequest) { + public void createKey(String keyName, VaultTransitKeyCreationRequest createKeyRequest) { Assert.hasText(keyName, "KeyName must not be empty"); Assert.notNull(createKeyRequest, @@ -78,16 +77,15 @@ public class VaultTransitTemplate implements VaultTransitOperations { @Override public List getKeys() { - VaultResponse response = vaultOperations - .read(String.format("%s/keys?list=true", path)); + VaultResponse response = vaultOperations.read(String.format("%s/keys?list=true", + path)); return response == null ? Collections.emptyList() : (List) response.getData() .get("keys"); } @Override - public void configureKey(String keyName, - VaultTransitKeyConfiguration keyConfiguration) { + public void configureKey(String keyName, VaultTransitKeyConfiguration keyConfiguration) { Assert.hasText(keyName, "KeyName must not be empty"); Assert.notNull(keyConfiguration, "VaultKeyConfiguration must not be empty"); @@ -96,6 +94,19 @@ public class VaultTransitTemplate implements VaultTransitOperations { keyConfiguration); } + @Override + public RawTransitKey exportKey(String keyName, TransitKeyType type) { + + Assert.hasText(keyName, "KeyName must not be empty"); + Assert.notNull(type, "Key type must not be null"); + + VaultResponseSupport result = vaultOperations.read( + String.format("%s/export/%s/%s", path, type.getValue(), keyName), + RawTransitKeyImpl.class); + + return result != null ? result.getData() : null; + } + @Override public VaultTransitKey getKey(String keyName) { @@ -119,25 +130,6 @@ public class VaultTransitTemplate implements VaultTransitOperations { vaultOperations.delete(String.format("%s/keys/%s", path, keyName)); } - @Override - public VaultTransitKeyExport exportKey(String keyName, - VaultExportKeyTypes vaultExportKeyType) { - - Assert.hasText(keyName, "KeyName must not be empty"); - Assert.notNull(vaultExportKeyType, "vaultExportKeyTypes must not be null"); - - VaultResponseSupport result = vaultOperations.read( - String.format("%s/export/%s/%s", path, - vaultExportKeyType.getValue(), keyName), - VaultTransitKeyExportImpl.class); - - if (result != null) { - return result.getData(); - } - - return null; - } - @Override public void rotate(String keyName) { @@ -302,15 +294,13 @@ public class VaultTransitTemplate implements VaultTransitOperations { return this.cipherMode; } - } @Data - static class VaultTransitKeyExportImpl implements VaultTransitKeyExport { + static class RawTransitKeyImpl implements RawTransitKey { private Map keys; private String name; - } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyExport.java b/spring-vault-core/src/main/java/org/springframework/vault/support/RawTransitKey.java similarity index 90% rename from spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyExport.java rename to spring-vault-core/src/main/java/org/springframework/vault/support/RawTransitKey.java index a00980f5..a31d9d9a 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyExport.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/RawTransitKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2017 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. @@ -22,7 +22,7 @@ import java.util.Map; * * @author Sven Schürmann */ -public interface VaultTransitKeyExport { +public interface RawTransitKey { /** * @return a {@link Map} of key version to its key value. @@ -33,5 +33,4 @@ public interface VaultTransitKeyExport { * @return name of the key */ String getName(); - } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultExportKeyTypes.java b/spring-vault-core/src/main/java/org/springframework/vault/support/TransitKeyType.java similarity index 61% rename from spring-vault-core/src/main/java/org/springframework/vault/support/VaultExportKeyTypes.java rename to spring-vault-core/src/main/java/org/springframework/vault/support/TransitKeyType.java index 1fe9a1d9..dfc77e65 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultExportKeyTypes.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/TransitKeyType.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2017 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. @@ -15,21 +15,21 @@ */ package org.springframework.vault.support; -import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.RequiredArgsConstructor; /** - * Enumeration to specify the type of the key to export. Intended for use - * with {@link org.springframework.vault.core.VaultTransitTemplate} + * Enumeration to specify the type of the transit key. Intended for use with + * {@link org.springframework.vault.core.VaultTransitOperations} * * @author Sven Schürmann + * @author Mark Paluch */ -@AllArgsConstructor -public enum VaultExportKeyTypes { +@Getter +@RequiredArgsConstructor +public enum TransitKeyType { - ENCRYPTION_KEY("encryption-key"), SIGNING_KEY("signing-key"), HMAC_KEY("hmac-key"); - - @Getter - String value; + ENCRYPTION_KEY("encryption-key"), SIGNING_KEY("signing-key"), HMAC_KEY("hmac-key"); + final String value; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKey.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKey.java index 4b8d1092..0d435080 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKey.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 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. diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java index c498ffef..6ffd0018 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java @@ -21,7 +21,7 @@ import org.springframework.util.Assert; /** * Transit backend key creation request options. - * + * * @author Mark Paluch * @author Sven Schürmann */ @@ -114,7 +114,7 @@ public class VaultTransitKeyCreationRequest { /** * Configure key derivation. - * + * * @param derived {@literal true} if key derivation MUST be used. If enabled, all * encrypt/decrypt requests to this named key must provide a context which is used * for key derivation. Defaults to {@literal false}. @@ -136,6 +136,7 @@ public class VaultTransitKeyCreationRequest { */ public VaultTransitKeyCreationRequestBuilder convergentEncryption( boolean convergentEncryption) { + this.convergentEncryption = convergentEncryption; return this; } @@ -163,8 +164,8 @@ public class VaultTransitKeyCreationRequest { Assert.hasText(type, "Type must not be empty"); - return new VaultTransitKeyCreationRequest(derived, type, convergentEncryption, - exportable); + return new VaultTransitKeyCreationRequest(derived, type, + convergentEncryption, exportable); } } } diff --git a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTemplateTransitIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTemplateTransitIntegrationTests.java index f55a1465..18d79646 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTemplateTransitIntegrationTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTemplateTransitIntegrationTests.java @@ -28,17 +28,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.vault.VaultException; -import org.springframework.vault.support.VaultExportKeyTypes; +import org.springframework.vault.support.RawTransitKey; +import org.springframework.vault.support.TransitKeyType; import org.springframework.vault.support.VaultMount; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultTransitKey; import org.springframework.vault.support.VaultTransitKeyConfiguration; import org.springframework.vault.support.VaultTransitKeyCreationRequest; -import org.springframework.vault.support.VaultTransitKeyExport; import org.springframework.vault.util.IntegrationTestSupport; import org.springframework.vault.util.Version; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; /** * Integration tests for {@link VaultTemplate} using the {@code transit} backend. @@ -50,14 +51,19 @@ import static org.assertj.core.api.Assertions.assertThat; @ContextConfiguration(classes = VaultIntegrationTestConfiguration.class) public class VaultTemplateTransitIntegrationTests extends IntegrationTestSupport { + @Autowired private VaultOperations vaultOperations; + private Version vaultVersion; + @Before - public void before() throws Exception { + public void before() { VaultSysOperations adminOperations = vaultOperations.opsForSys(); + vaultVersion = prepare().getVersion(); + if (!adminOperations.getMounts().containsKey("transit/")) { adminOperations.mount("transit", VaultMount.create("transit")); } @@ -94,7 +100,7 @@ public class VaultTemplateTransitIntegrationTests extends IntegrationTestSupport private void removeKeys() { - if (prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.4"))) { + if (vaultVersion.isGreaterThanOrEqualTo(Version.parse("0.6.4"))) { List keys = vaultOperations.opsForTransit().getKeys(); for (String keyName : keys) { deleteKey(keyName); @@ -108,7 +114,7 @@ public class VaultTemplateTransitIntegrationTests extends IntegrationTestSupport } @Test - public void shouldEncrypt() throws Exception { + public void shouldEncrypt() { VaultResponse response = vaultOperations.write( "transit/encrypt/mykey", @@ -119,7 +125,7 @@ public class VaultTemplateTransitIntegrationTests extends IntegrationTestSupport } @Test - public void shouldEncryptAndDecrypt() throws Exception { + public void shouldEncryptAndDecrypt() { VaultResponse response = vaultOperations.write( "transit/encrypt/mykey", @@ -136,78 +142,74 @@ public class VaultTemplateTransitIntegrationTests extends IntegrationTestSupport } @Test - public void shouldCreateNewExportableKey() throws Exception { + public void shouldCreateNewExportableKey() { - VaultTransitOperations vaultTransitOperations = vaultOperations - .opsForTransit(); + assumeTrue(vaultVersion.isGreaterThanOrEqualTo(Version.parse("0.6.5"))); + + VaultTransitOperations vaultTransitOperations = vaultOperations.opsForTransit(); VaultTransitKeyCreationRequest vaultTransitKeyCreationRequest = VaultTransitKeyCreationRequest .builder().exportable(true).derived(true).build(); vaultTransitOperations.createKey("export-test", vaultTransitKeyCreationRequest); - VaultTransitKey vaultTransitKey = vaultTransitOperations - .getKey("export-test"); + VaultTransitKey vaultTransitKey = vaultTransitOperations.getKey("export-test"); assertThat(vaultTransitKey.getName()).isEqualTo("export-test"); assertThat(vaultTransitKey.isExportable()).isTrue(); - } @Test - public void shouldNotCreateExportableKeyPerDefault() throws Exception { + public void shouldCreateNotExportableKeyByDefault() { - VaultTransitOperations vaultTransitOperations = vaultOperations - .opsForTransit(); + assumeTrue(vaultVersion.isGreaterThanOrEqualTo(Version.parse("0.6.5"))); + + VaultTransitOperations vaultTransitOperations = vaultOperations.opsForTransit(); vaultTransitOperations.createKey("no-export"); - VaultTransitKey vaultTransitKey = vaultTransitOperations - .getKey("no-export"); + VaultTransitKey vaultTransitKey = vaultTransitOperations.getKey("no-export"); assertThat(vaultTransitKey.getName()).isEqualTo("no-export"); assertThat(vaultTransitKey.isExportable()).isFalse(); - } @Test - public void shouldExportEncryptionKey() throws Exception { + public void shouldExportEncryptionKey() { - VaultTransitOperations vaultTransitOperations = vaultOperations - .opsForTransit(); + assumeTrue(vaultVersion.isGreaterThanOrEqualTo(Version.parse("0.6.5"))); - VaultTransitKeyExport vaultTransitKeyExport = vaultTransitOperations - .exportKey("export", VaultExportKeyTypes.ENCRYPTION_KEY); + VaultTransitOperations vaultTransitOperations = vaultOperations.opsForTransit(); - assertThat(vaultTransitKeyExport.getName()).isEqualTo("export"); - assertThat(vaultTransitKeyExport.getKeys()).isNotEmpty(); - assertThat(vaultTransitKeyExport.getKeys().get("1")).isNotBlank(); + RawTransitKey rawTransitKey = vaultTransitOperations.exportKey("export", + TransitKeyType.ENCRYPTION_KEY); + assertThat(rawTransitKey.getName()).isEqualTo("export"); + assertThat(rawTransitKey.getKeys()).isNotEmpty(); + assertThat(rawTransitKey.getKeys().get("1")).isNotBlank(); } @Test(expected = VaultException.class) - public void shouldNotExportSigningKey() throws Exception { + public void shouldNotAllowExportSigningKey() { - VaultTransitOperations vaultTransitOperations = vaultOperations - .opsForTransit(); + assumeTrue(vaultVersion.isGreaterThanOrEqualTo(Version.parse("0.6.5"))); - VaultTransitKeyExport vaultTransitKeyExport = vaultTransitOperations - .exportKey("export", VaultExportKeyTypes.SIGNING_KEY); + VaultTransitOperations vaultTransitOperations = vaultOperations.opsForTransit(); + vaultTransitOperations.exportKey("export", TransitKeyType.SIGNING_KEY); } @Test - public void shouldExportHmacKey() throws Exception { + public void shouldExportHmacKey() { - VaultTransitOperations vaultTransitOperations = vaultOperations - .opsForTransit(); + assumeTrue(vaultVersion.isGreaterThanOrEqualTo(Version.parse("0.6.5"))); - VaultTransitKeyExport vaultTransitKeyExport = vaultTransitOperations - .exportKey("export", VaultExportKeyTypes.HMAC_KEY); + VaultTransitOperations vaultTransitOperations = vaultOperations.opsForTransit(); - assertThat(vaultTransitKeyExport.getName()).isEqualTo("export"); - assertThat(vaultTransitKeyExport.getKeys()).isNotEmpty(); - assertThat(vaultTransitKeyExport.getKeys().get("1")).isNotBlank(); + RawTransitKey rawTransitKey = vaultTransitOperations.exportKey("export", + TransitKeyType.HMAC_KEY); + assertThat(rawTransitKey.getName()).isEqualTo("export"); + assertThat(rawTransitKey.getKeys()).isNotEmpty(); + assertThat(rawTransitKey.getKeys().get("1")).isNotBlank(); } - }