use of org.apache.hadoop.crypto.key.KeyProvider.KeyVersion in project hadoop by apache.
the class TestKeyProviderCryptoExtension method testGenerateEncryptedKey.
@Test
public void testGenerateEncryptedKey() throws Exception {
// Generate a new EEK and check it
KeyProviderCryptoExtension.EncryptedKeyVersion ek1 = kpExt.generateEncryptedKey(encryptionKey.getName());
assertEquals("Version name of EEK should be EEK", KeyProviderCryptoExtension.EEK, ek1.getEncryptedKeyVersion().getVersionName());
assertEquals("Name of EEK should be encryption key name", ENCRYPTION_KEY_NAME, ek1.getEncryptionKeyName());
assertNotNull("Expected encrypted key material", ek1.getEncryptedKeyVersion().getMaterial());
assertEquals("Length of encryption key material and EEK material should " + "be the same", encryptionKey.getMaterial().length, ek1.getEncryptedKeyVersion().getMaterial().length);
// Decrypt EEK into an EK and check it
KeyVersion k1 = kpExt.decryptEncryptedKey(ek1);
assertEquals(KeyProviderCryptoExtension.EK, k1.getVersionName());
assertEquals(encryptionKey.getMaterial().length, k1.getMaterial().length);
if (Arrays.equals(k1.getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal encryption key material");
}
if (Arrays.equals(ek1.getEncryptedKeyVersion().getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal decrypted key material");
}
// Decrypt it again and it should be the same
KeyVersion k1a = kpExt.decryptEncryptedKey(ek1);
assertArrayEquals(k1.getMaterial(), k1a.getMaterial());
// Generate another EEK and make sure it's different from the first
KeyProviderCryptoExtension.EncryptedKeyVersion ek2 = kpExt.generateEncryptedKey(encryptionKey.getName());
KeyVersion k2 = kpExt.decryptEncryptedKey(ek2);
if (Arrays.equals(k1.getMaterial(), k2.getMaterial())) {
fail("Generated EEKs should have different material!");
}
if (Arrays.equals(ek1.getEncryptedKeyIv(), ek2.getEncryptedKeyIv())) {
fail("Generated EEKs should have different IVs!");
}
}
use of org.apache.hadoop.crypto.key.KeyProvider.KeyVersion in project hadoop by apache.
the class TestKeyProviderCryptoExtension method testReencryptEncryptedKey.
@Test
public void testReencryptEncryptedKey() throws Exception {
// Generate a new EEK
final KeyProviderCryptoExtension.EncryptedKeyVersion ek1 = kpExt.generateEncryptedKey(encryptionKey.getName());
// Decrypt EEK into an EK and check it
final KeyVersion k1 = kpExt.decryptEncryptedKey(ek1);
assertEquals(KeyProviderCryptoExtension.EK, k1.getVersionName());
assertEquals(encryptionKey.getMaterial().length, k1.getMaterial().length);
if (Arrays.equals(k1.getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal encryption key material");
}
// Roll the EK
kpExt.rollNewVersion(ek1.getEncryptionKeyName());
// Reencrypt ek1
final KeyProviderCryptoExtension.EncryptedKeyVersion ek2 = kpExt.reencryptEncryptedKey(ek1);
assertEquals("Version name of EEK should be EEK", KeyProviderCryptoExtension.EEK, ek2.getEncryptedKeyVersion().getVersionName());
assertEquals("Name of EEK should be encryption key name", ENCRYPTION_KEY_NAME, ek2.getEncryptionKeyName());
assertNotNull("Expected encrypted key material", ek2.getEncryptedKeyVersion().getMaterial());
assertEquals("Length of encryption key material and EEK material should " + "be the same", encryptionKey.getMaterial().length, ek2.getEncryptedKeyVersion().getMaterial().length);
if (Arrays.equals(ek2.getEncryptedKeyVersion().getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal decrypted key material");
}
if (Arrays.equals(ek2.getEncryptedKeyVersion().getMaterial(), ek1.getEncryptedKeyVersion().getMaterial())) {
fail("Re-encrypted EEK should have different material");
}
// Decrypt the new EEK into an EK and check it
final KeyVersion k2 = kpExt.decryptEncryptedKey(ek2);
assertEquals(KeyProviderCryptoExtension.EK, k2.getVersionName());
assertEquals(encryptionKey.getMaterial().length, k2.getMaterial().length);
if (Arrays.equals(k2.getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal encryption key material");
}
// Re-encrypting the same EEK with the same EK should be deterministic
final KeyProviderCryptoExtension.EncryptedKeyVersion ek2a = kpExt.reencryptEncryptedKey(ek1);
assertEquals("Version name of EEK should be EEK", KeyProviderCryptoExtension.EEK, ek2a.getEncryptedKeyVersion().getVersionName());
assertEquals("Name of EEK should be encryption key name", ENCRYPTION_KEY_NAME, ek2a.getEncryptionKeyName());
assertNotNull("Expected encrypted key material", ek2a.getEncryptedKeyVersion().getMaterial());
assertEquals("Length of encryption key material and EEK material should " + "be the same", encryptionKey.getMaterial().length, ek2a.getEncryptedKeyVersion().getMaterial().length);
if (Arrays.equals(ek2a.getEncryptedKeyVersion().getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal decrypted key material");
}
if (Arrays.equals(ek2a.getEncryptedKeyVersion().getMaterial(), ek1.getEncryptedKeyVersion().getMaterial())) {
fail("Re-encrypted EEK should have different material");
}
assertArrayEquals(ek2.getEncryptedKeyVersion().getMaterial(), ek2a.getEncryptedKeyVersion().getMaterial());
// Re-encrypting an EEK with the same version EK should be no-op
final KeyProviderCryptoExtension.EncryptedKeyVersion ek3 = kpExt.reencryptEncryptedKey(ek2);
assertEquals("Version name of EEK should be EEK", KeyProviderCryptoExtension.EEK, ek3.getEncryptedKeyVersion().getVersionName());
assertEquals("Name of EEK should be encryption key name", ENCRYPTION_KEY_NAME, ek3.getEncryptionKeyName());
assertNotNull("Expected encrypted key material", ek3.getEncryptedKeyVersion().getMaterial());
assertEquals("Length of encryption key material and EEK material should " + "be the same", encryptionKey.getMaterial().length, ek3.getEncryptedKeyVersion().getMaterial().length);
if (Arrays.equals(ek3.getEncryptedKeyVersion().getMaterial(), encryptionKey.getMaterial())) {
fail("Encrypted key material should not equal decrypted key material");
}
if (Arrays.equals(ek3.getEncryptedKeyVersion().getMaterial(), ek1.getEncryptedKeyVersion().getMaterial())) {
fail("Re-encrypted EEK should have different material");
}
assertArrayEquals(ek2.getEncryptedKeyVersion().getMaterial(), ek3.getEncryptedKeyVersion().getMaterial());
}
use of org.apache.hadoop.crypto.key.KeyProvider.KeyVersion in project hadoop by apache.
the class TestKeyAuthorizationKeyProvider method testDecryptWithKeyVersionNameKeyMismatch.
@Test(expected = IllegalArgumentException.class)
public void testDecryptWithKeyVersionNameKeyMismatch() throws Exception {
final Configuration conf = new Configuration();
KeyProvider kp = new UserProvider.Factory().createProvider(new URI("user:///"), conf);
KeyACLs mock = mock(KeyACLs.class);
when(mock.isACLPresent("testKey", KeyOpType.MANAGEMENT)).thenReturn(true);
when(mock.isACLPresent("testKey", KeyOpType.GENERATE_EEK)).thenReturn(true);
when(mock.isACLPresent("testKey", KeyOpType.DECRYPT_EEK)).thenReturn(true);
when(mock.isACLPresent("testKey", KeyOpType.ALL)).thenReturn(true);
UserGroupInformation u1 = UserGroupInformation.createRemoteUser("u1");
UserGroupInformation u2 = UserGroupInformation.createRemoteUser("u2");
UserGroupInformation u3 = UserGroupInformation.createRemoteUser("u3");
UserGroupInformation sudo = UserGroupInformation.createRemoteUser("sudo");
when(mock.hasAccessToKey("testKey", u1, KeyOpType.MANAGEMENT)).thenReturn(true);
when(mock.hasAccessToKey("testKey", u2, KeyOpType.GENERATE_EEK)).thenReturn(true);
when(mock.hasAccessToKey("testKey", u3, KeyOpType.DECRYPT_EEK)).thenReturn(true);
when(mock.hasAccessToKey("testKey", sudo, KeyOpType.ALL)).thenReturn(true);
final KeyProviderCryptoExtension kpExt = new KeyAuthorizationKeyProvider(KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp), mock);
sudo.doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
Options opt = newOptions(conf);
Map<String, String> m = new HashMap<String, String>();
m.put("key.acl.name", "testKey");
opt.setAttributes(m);
KeyVersion kv = kpExt.createKey("foo", SecureRandom.getSeed(16), opt);
kpExt.rollNewVersion(kv.getName());
kpExt.rollNewVersion(kv.getName(), SecureRandom.getSeed(16));
EncryptedKeyVersion ekv = kpExt.generateEncryptedKey(kv.getName());
ekv = EncryptedKeyVersion.createForDecryption(ekv.getEncryptionKeyName() + "x", ekv.getEncryptionKeyVersionName(), ekv.getEncryptedKeyIv(), ekv.getEncryptedKeyVersion().getMaterial());
kpExt.decryptEncryptedKey(ekv);
return null;
}
});
}
use of org.apache.hadoop.crypto.key.KeyProvider.KeyVersion in project hadoop by apache.
the class TestKMS method testKeyACLs.
@Test
@SuppressWarnings("checkstyle:methodlength")
public void testKeyACLs() throws Exception {
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication", "kerberos");
final File testDir = getTestDir();
conf = createBaseKMSConf(testDir, conf);
conf.set("hadoop.kms.authentication.type", "kerberos");
conf.set("hadoop.kms.authentication.kerberos.keytab", keytab.getAbsolutePath());
conf.set("hadoop.kms.authentication.kerberos.principal", "HTTP/localhost");
conf.set("hadoop.kms.authentication.kerberos.name.rules", "DEFAULT");
for (KMSACLs.Type type : KMSACLs.Type.values()) {
conf.set(type.getAclConfigKey(), type.toString());
}
conf.set(KMSACLs.Type.CREATE.getAclConfigKey(), "CREATE,ROLLOVER,GET,SET_KEY_MATERIAL,GENERATE_EEK,DECRYPT_EEK");
conf.set(KMSACLs.Type.ROLLOVER.getAclConfigKey(), "CREATE,ROLLOVER,GET,SET_KEY_MATERIAL,GENERATE_EEK,DECRYPT_EEK");
conf.set(KMSACLs.Type.GENERATE_EEK.getAclConfigKey(), "CREATE,ROLLOVER,GET,SET_KEY_MATERIAL,GENERATE_EEK,DECRYPT_EEK");
conf.set(KMSACLs.Type.DECRYPT_EEK.getAclConfigKey(), "CREATE,ROLLOVER,GET,SET_KEY_MATERIAL,GENERATE_EEK");
conf.set(KeyAuthorizationKeyProvider.KEY_ACL + "test_key.MANAGEMENT", "CREATE");
conf.set(KeyAuthorizationKeyProvider.KEY_ACL + "some_key.MANAGEMENT", "ROLLOVER");
conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", "DECRYPT_EEK");
conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "ALL", "DECRYPT_EEK");
conf.set(KeyAuthorizationKeyProvider.KEY_ACL + "all_access.ALL", "GENERATE_EEK");
conf.set(KeyAuthorizationKeyProvider.KEY_ACL + "all_access.DECRYPT_EEK", "ROLLOVER");
conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "MANAGEMENT", "ROLLOVER");
conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "GENERATE_EEK", "SOMEBODY");
conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "ALL", "ROLLOVER");
writeConf(testDir, conf);
runServer(null, null, testDir, new KMSCallable<Void>() {
@Override
public Void call() throws Exception {
final Configuration conf = new Configuration();
conf.setInt(KeyProvider.DEFAULT_BITLENGTH_NAME, 128);
final URI uri = createKMSUri(getKMSUrl());
doAs("CREATE", new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
try {
Options options = new KeyProvider.Options(conf);
Map<String, String> attributes = options.getAttributes();
HashMap<String, String> newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "test_key");
options.setAttributes(newAttribs);
KeyProvider.KeyVersion kv = kp.createKey("k0", options);
Assert.assertNull(kv.getMaterial());
KeyVersion rollVersion = kp.rollNewVersion("k0");
Assert.assertNull(rollVersion.getMaterial());
KeyProviderCryptoExtension kpce = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp);
try {
kpce.generateEncryptedKey("k0");
Assert.fail("User [CREATE] should not be allowed to generate_eek on k0");
} catch (Exception e) {
// Ignore
}
newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "all_access");
options.setAttributes(newAttribs);
try {
kp.createKey("kx", options);
Assert.fail("User [CREATE] should not be allowed to create kx");
} catch (Exception e) {
// Ignore
}
} catch (Exception ex) {
Assert.fail(ex.getMessage());
}
return null;
}
});
// Test whitelist key access..
// DECRYPT_EEK is whitelisted for MANAGEMENT operations only
doAs("DECRYPT_EEK", new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
try {
Options options = new KeyProvider.Options(conf);
Map<String, String> attributes = options.getAttributes();
HashMap<String, String> newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "some_key");
options.setAttributes(newAttribs);
KeyProvider.KeyVersion kv = kp.createKey("kk0", options);
Assert.assertNull(kv.getMaterial());
KeyVersion rollVersion = kp.rollNewVersion("kk0");
Assert.assertNull(rollVersion.getMaterial());
KeyProviderCryptoExtension kpce = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp);
try {
kpce.generateEncryptedKey("kk0");
Assert.fail("User [DECRYPT_EEK] should not be allowed to generate_eek on kk0");
} catch (Exception e) {
// Ignore
}
newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "all_access");
options.setAttributes(newAttribs);
kp.createKey("kkx", options);
} catch (Exception ex) {
Assert.fail(ex.getMessage());
}
return null;
}
});
doAs("ROLLOVER", new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
try {
Options options = new KeyProvider.Options(conf);
Map<String, String> attributes = options.getAttributes();
HashMap<String, String> newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "test_key2");
options.setAttributes(newAttribs);
KeyProvider.KeyVersion kv = kp.createKey("k1", options);
Assert.assertNull(kv.getMaterial());
KeyVersion rollVersion = kp.rollNewVersion("k1");
Assert.assertNull(rollVersion.getMaterial());
try {
kp.rollNewVersion("k0");
Assert.fail("User [ROLLOVER] should not be allowed to rollover k0");
} catch (Exception e) {
// Ignore
}
KeyProviderCryptoExtension kpce = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp);
try {
kpce.generateEncryptedKey("k1");
Assert.fail("User [ROLLOVER] should not be allowed to generate_eek on k1");
} catch (Exception e) {
// Ignore
}
newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "all_access");
options.setAttributes(newAttribs);
try {
kp.createKey("kx", options);
Assert.fail("User [ROLLOVER] should not be allowed to create kx");
} catch (Exception e) {
// Ignore
}
} catch (Exception ex) {
Assert.fail(ex.getMessage());
}
return null;
}
});
doAs("GET", new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
try {
Options options = new KeyProvider.Options(conf);
Map<String, String> attributes = options.getAttributes();
HashMap<String, String> newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "test_key");
options.setAttributes(newAttribs);
try {
kp.createKey("k2", options);
Assert.fail("User [GET] should not be allowed to create key..");
} catch (Exception e) {
// Ignore
}
newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "all_access");
options.setAttributes(newAttribs);
try {
kp.createKey("kx", options);
Assert.fail("User [GET] should not be allowed to create kx");
} catch (Exception e) {
// Ignore
}
} catch (Exception ex) {
Assert.fail(ex.getMessage());
}
return null;
}
});
final EncryptedKeyVersion ekv = doAs("GENERATE_EEK", new PrivilegedExceptionAction<EncryptedKeyVersion>() {
@Override
public EncryptedKeyVersion run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
try {
Options options = new KeyProvider.Options(conf);
Map<String, String> attributes = options.getAttributes();
HashMap<String, String> newAttribs = new HashMap<String, String>(attributes);
newAttribs.put("key.acl.name", "all_access");
options.setAttributes(newAttribs);
kp.createKey("kx", options);
KeyProviderCryptoExtension kpce = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp);
try {
return kpce.generateEncryptedKey("kx");
} catch (Exception e) {
Assert.fail("User [GENERATE_EEK] should be allowed to generate_eek on kx");
}
} catch (Exception ex) {
Assert.fail(ex.getMessage());
}
return null;
}
});
doAs("ROLLOVER", new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
try {
KeyProviderCryptoExtension kpce = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp);
kpce.decryptEncryptedKey(ekv);
} catch (Exception ex) {
Assert.fail(ex.getMessage());
}
return null;
}
});
return null;
}
});
conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "MANAGEMENT", "");
conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "GENERATE_EEK", "*");
writeConf(testDir, conf);
runServer(null, null, testDir, new KMSCallable<Void>() {
@Override
public Void call() throws Exception {
final Configuration conf = new Configuration();
conf.setInt(KeyProvider.DEFAULT_BITLENGTH_NAME, 128);
final URI uri = createKMSUri(getKMSUrl());
doAs("GENERATE_EEK", new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
KeyProvider kp = createProvider(uri, conf);
KeyProviderCryptoExtension kpce = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(kp);
EncryptedKeyVersion ekv = kpce.generateEncryptedKey("k1");
kpce.reencryptEncryptedKey(ekv);
return null;
}
});
return null;
}
});
}
use of org.apache.hadoop.crypto.key.KeyProvider.KeyVersion in project hadoop by apache.
the class KMS method rolloverKey.
@POST
@Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
public Response rolloverKey(@PathParam("name") final String name, Map jsonMaterial) throws Exception {
try {
LOG.trace("Entering rolloverKey Method.");
KMSWebApp.getAdminCallsMeter().mark();
UserGroupInformation user = HttpUserGroupInformation.get();
assertAccess(KMSACLs.Type.ROLLOVER, user, KMSOp.ROLL_NEW_VERSION, name);
KMSClientProvider.checkNotEmpty(name, "name");
LOG.debug("Rolling key with name {}.", name);
final String material = (String) jsonMaterial.get(KMSRESTConstants.MATERIAL_FIELD);
if (material != null) {
assertAccess(KMSACLs.Type.SET_KEY_MATERIAL, user, KMSOp.ROLL_NEW_VERSION, name);
}
KeyProvider.KeyVersion keyVersion = user.doAs(new PrivilegedExceptionAction<KeyVersion>() {
@Override
public KeyVersion run() throws Exception {
KeyVersion keyVersion = (material != null) ? provider.rollNewVersion(name, Base64.decodeBase64(material)) : provider.rollNewVersion(name);
provider.flush();
return keyVersion;
}
});
kmsAudit.ok(user, KMSOp.ROLL_NEW_VERSION, name, "UserProvidedMaterial:" + (material != null) + " NewVersion:" + keyVersion.getVersionName());
if (!KMSWebApp.getACLs().hasAccess(KMSACLs.Type.GET, user)) {
keyVersion = removeKeyMaterial(keyVersion);
}
Map json = KMSServerJSONUtils.toJSON(keyVersion);
LOG.trace("Exiting rolloverKey Method.");
return Response.ok().type(MediaType.APPLICATION_JSON).entity(json).build();
} catch (Exception e) {
LOG.debug("Exception in rolloverKey.", e);
throw e;
}
}
Aggregations