Search in sources :

Example 1 with EncryptedKeyVersion

use of org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion in project hadoop by apache.

the class FSDirEncryptionZoneOp method generateEncryptedDataEncryptionKey.

/**
   * Invoke KeyProvider APIs to generate an encrypted data encryption key for
   * an encryption zone. Should not be called with any locks held.
   *
   * @param fsd fsdirectory
   * @param ezKeyName key name of an encryption zone
   * @return New EDEK, or null if ezKeyName is null
   * @throws IOException
   */
private static EncryptedKeyVersion generateEncryptedDataEncryptionKey(final FSDirectory fsd, final String ezKeyName) throws IOException {
    // must not be holding lock during this operation
    assert !fsd.getFSNamesystem().hasReadLock();
    assert !fsd.getFSNamesystem().hasWriteLock();
    if (ezKeyName == null) {
        return null;
    }
    long generateEDEKStartTime = monotonicNow();
    // Generate EDEK with login user (hdfs) so that KMS does not need
    // an extra proxy configuration allowing hdfs to proxy its clients and
    // KMS does not need configuration to allow non-hdfs user GENERATE_EEK
    // operation.
    EncryptedKeyVersion edek = SecurityUtil.doAsLoginUser(new PrivilegedExceptionAction<EncryptedKeyVersion>() {

        @Override
        public EncryptedKeyVersion run() throws IOException {
            try {
                return fsd.getProvider().generateEncryptedKey(ezKeyName);
            } catch (GeneralSecurityException e) {
                throw new IOException(e);
            }
        }
    });
    long generateEDEKTime = monotonicNow() - generateEDEKStartTime;
    NameNode.getNameNodeMetrics().addGenerateEDEKTime(generateEDEKTime);
    Preconditions.checkNotNull(edek);
    return edek;
}
Also used : EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException)

Example 2 with EncryptedKeyVersion

use of org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion in project hadoop by apache.

the class DFSClient method decryptEncryptedDataEncryptionKey.

/**
   * Decrypts a EDEK by consulting the KeyProvider.
   */
private KeyVersion decryptEncryptedDataEncryptionKey(FileEncryptionInfo feInfo) throws IOException {
    try (TraceScope ignored = tracer.newScope("decryptEDEK")) {
        KeyProvider provider = getKeyProvider();
        if (provider == null) {
            throw new IOException("No KeyProvider is configured, cannot access" + " an encrypted file");
        }
        EncryptedKeyVersion ekv = EncryptedKeyVersion.createForDecryption(feInfo.getKeyName(), feInfo.getEzKeyVersionName(), feInfo.getIV(), feInfo.getEncryptedDataEncryptionKey());
        try {
            KeyProviderCryptoExtension cryptoProvider = KeyProviderCryptoExtension.createKeyProviderCryptoExtension(provider);
            return cryptoProvider.decryptEncryptedKey(ekv);
        } catch (GeneralSecurityException e) {
            throw new IOException(e);
        }
    }
}
Also used : KeyProvider(org.apache.hadoop.crypto.key.KeyProvider) EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) GeneralSecurityException(java.security.GeneralSecurityException) TraceScope(org.apache.htrace.core.TraceScope) IOException(java.io.IOException) KeyProviderCryptoExtension(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension)

Example 3 with EncryptedKeyVersion

use of org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion in project hadoop by apache.

the class KMS method handleEncryptedKeyOp.

@SuppressWarnings("rawtypes")
@POST
@Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}/" + KMSRESTConstants.EEK_SUB_RESOURCE)
@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
public Response handleEncryptedKeyOp(@PathParam("versionName") final String versionName, @QueryParam(KMSRESTConstants.EEK_OP) String eekOp, Map jsonPayload) throws Exception {
    try {
        LOG.trace("Entering decryptEncryptedKey method.");
        UserGroupInformation user = HttpUserGroupInformation.get();
        KMSClientProvider.checkNotEmpty(versionName, "versionName");
        KMSClientProvider.checkNotNull(eekOp, "eekOp");
        LOG.debug("Decrypting key for {}, the edek Operation is {}.", versionName, eekOp);
        final String keyName = (String) jsonPayload.get(KMSRESTConstants.NAME_FIELD);
        String ivStr = (String) jsonPayload.get(KMSRESTConstants.IV_FIELD);
        String encMaterialStr = (String) jsonPayload.get(KMSRESTConstants.MATERIAL_FIELD);
        KMSClientProvider.checkNotNull(ivStr, KMSRESTConstants.IV_FIELD);
        final byte[] iv = Base64.decodeBase64(ivStr);
        KMSClientProvider.checkNotNull(encMaterialStr, KMSRESTConstants.MATERIAL_FIELD);
        final byte[] encMaterial = Base64.decodeBase64(encMaterialStr);
        Object retJSON;
        if (eekOp.equals(KMSRESTConstants.EEK_DECRYPT)) {
            assertAccess(KMSACLs.Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, keyName);
            KeyProvider.KeyVersion retKeyVersion = user.doAs(new PrivilegedExceptionAction<KeyVersion>() {

                @Override
                public KeyVersion run() throws Exception {
                    return provider.decryptEncryptedKey(new KMSClientProvider.KMSEncryptedKeyVersion(keyName, versionName, iv, KeyProviderCryptoExtension.EEK, encMaterial));
                }
            });
            retJSON = KMSServerJSONUtils.toJSON(retKeyVersion);
            kmsAudit.ok(user, KMSOp.DECRYPT_EEK, keyName, "");
        } else if (eekOp.equals(KMSRESTConstants.EEK_REENCRYPT)) {
            assertAccess(KMSACLs.Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK, keyName);
            EncryptedKeyVersion retEncryptedKeyVersion = user.doAs(new PrivilegedExceptionAction<EncryptedKeyVersion>() {

                @Override
                public EncryptedKeyVersion run() throws Exception {
                    return provider.reencryptEncryptedKey(new KMSClientProvider.KMSEncryptedKeyVersion(keyName, versionName, iv, KeyProviderCryptoExtension.EEK, encMaterial));
                }
            });
            retJSON = KMSServerJSONUtils.toJSON(retEncryptedKeyVersion);
            kmsAudit.ok(user, KMSOp.REENCRYPT_EEK, keyName, "");
        } else {
            StringBuilder error;
            error = new StringBuilder("IllegalArgumentException Wrong ");
            error.append(KMSRESTConstants.EEK_OP);
            error.append(" value, it must be ");
            error.append(KMSRESTConstants.EEK_GENERATE);
            error.append(" or ");
            error.append(KMSRESTConstants.EEK_DECRYPT);
            LOG.error(error.toString());
            throw new IllegalArgumentException(error.toString());
        }
        KMSWebApp.getDecryptEEKCallsMeter().mark();
        LOG.trace("Exiting handleEncryptedKeyOp method.");
        return Response.ok().type(MediaType.APPLICATION_JSON).entity(retJSON).build();
    } catch (Exception e) {
        LOG.debug("Exception in handleEncryptedKeyOp.", e);
        throw e;
    }
}
Also used : KeyProvider(org.apache.hadoop.crypto.key.KeyProvider) KeyVersion(org.apache.hadoop.crypto.key.KeyProvider.KeyVersion) EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) PrivilegedExceptionAction(java.security.PrivilegedExceptionAction) KMSClientProvider(org.apache.hadoop.crypto.key.kms.KMSClientProvider) IOException(java.io.IOException) AccessControlException(org.apache.hadoop.security.AccessControlException) KeyVersion(org.apache.hadoop.crypto.key.KeyProvider.KeyVersion) EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) HttpUserGroupInformation(org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces)

Example 4 with EncryptedKeyVersion

use of org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion in project hadoop by apache.

the class KMS method generateEncryptedKeys.

@SuppressWarnings({ "rawtypes", "unchecked" })
@GET
@Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.EEK_SUB_RESOURCE)
@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
public Response generateEncryptedKeys(@PathParam("name") final String name, @QueryParam(KMSRESTConstants.EEK_OP) String edekOp, @DefaultValue("1") @QueryParam(KMSRESTConstants.EEK_NUM_KEYS) final int numKeys) throws Exception {
    try {
        LOG.trace("Entering generateEncryptedKeys method.");
        UserGroupInformation user = HttpUserGroupInformation.get();
        KMSClientProvider.checkNotEmpty(name, "name");
        KMSClientProvider.checkNotNull(edekOp, "eekOp");
        LOG.debug("Generating encrypted key with name {}," + " the edek Operation is {}.", name, edekOp);
        Object retJSON;
        if (edekOp.equals(KMSRESTConstants.EEK_GENERATE)) {
            LOG.debug("edek Operation is Generate.");
            assertAccess(KMSACLs.Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK, name);
            final List<EncryptedKeyVersion> retEdeks = new LinkedList<EncryptedKeyVersion>();
            try {
                user.doAs(new PrivilegedExceptionAction<Void>() {

                    @Override
                    public Void run() throws Exception {
                        LOG.debug("Generated Encrypted key for {} number of " + "keys.", numKeys);
                        for (int i = 0; i < numKeys; i++) {
                            retEdeks.add(provider.generateEncryptedKey(name));
                        }
                        return null;
                    }
                });
            } catch (Exception e) {
                LOG.error("Exception in generateEncryptedKeys:", e);
                throw new IOException(e);
            }
            kmsAudit.ok(user, KMSOp.GENERATE_EEK, name, "");
            retJSON = new ArrayList();
            for (EncryptedKeyVersion edek : retEdeks) {
                ((ArrayList) retJSON).add(KMSServerJSONUtils.toJSON(edek));
            }
        } else {
            StringBuilder error;
            error = new StringBuilder("IllegalArgumentException Wrong ");
            error.append(KMSRESTConstants.EEK_OP);
            error.append(" value, it must be ");
            error.append(KMSRESTConstants.EEK_GENERATE);
            error.append(" or ");
            error.append(KMSRESTConstants.EEK_DECRYPT);
            LOG.error(error.toString());
            throw new IllegalArgumentException(error.toString());
        }
        KMSWebApp.getGenerateEEKCallsMeter().mark();
        LOG.trace("Exiting generateEncryptedKeys method.");
        return Response.ok().type(MediaType.APPLICATION_JSON).entity(retJSON).build();
    } catch (Exception e) {
        LOG.debug("Exception in generateEncryptedKeys.", e);
        throw e;
    }
}
Also used : ArrayList(java.util.ArrayList) IOException(java.io.IOException) LinkedList(java.util.LinkedList) IOException(java.io.IOException) AccessControlException(org.apache.hadoop.security.AccessControlException) EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) HttpUserGroupInformation(org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 5 with EncryptedKeyVersion

use of org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion 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;
        }
    });
}
Also used : KeyProvider(org.apache.hadoop.crypto.key.KeyProvider) Options(org.apache.hadoop.crypto.key.KeyProvider.Options) Configuration(org.apache.hadoop.conf.Configuration) KeyVersion(org.apache.hadoop.crypto.key.KeyProvider.KeyVersion) EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) KeyProviderCryptoExtension(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension) URI(java.net.URI) IOException(java.io.IOException) EncryptedKeyVersion(org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion) UserProvider(org.apache.hadoop.crypto.key.UserProvider) KeyACLs(org.apache.hadoop.crypto.key.kms.server.KeyAuthorizationKeyProvider.KeyACLs) HashMap(java.util.HashMap) Map(java.util.Map) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Aggregations

EncryptedKeyVersion (org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion)23 IOException (java.io.IOException)17 Test (org.junit.Test)14 Configuration (org.apache.hadoop.conf.Configuration)13 KeyProvider (org.apache.hadoop.crypto.key.KeyProvider)13 KeyVersion (org.apache.hadoop.crypto.key.KeyProvider.KeyVersion)13 URI (java.net.URI)12 Options (org.apache.hadoop.crypto.key.KeyProvider.Options)10 KeyProviderCryptoExtension (org.apache.hadoop.crypto.key.KeyProviderCryptoExtension)10 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)9 HashMap (java.util.HashMap)7 Map (java.util.Map)6 File (java.io.File)5 SocketTimeoutException (java.net.SocketTimeoutException)5 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)5 Path (javax.ws.rs.Path)5 Produces (javax.ws.rs.Produces)5 AccessControlException (org.apache.hadoop.security.AccessControlException)5 AuthorizationException (org.apache.hadoop.security.authorize.AuthorizationException)5 HttpUserGroupInformation (org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation)5