Search in sources :

Example 1 with KeyAndCertificateChain

use of com.emc.vipr.model.keystore.KeyAndCertificateChain in project coprhd-controller by CoprHD.

the class VirtualDataCenterService method setKeyCertificatePair.

/**
 * Rotate the VIPR key and certificate chain.
 *
 * @param rotateKeyAndCertParam
 * @return the new certificate chain being used by ViPR
 * @brief Rotate the VIPR key and certificate chain to a new system self-signed or a specified input.
 */
@Path("/keystore")
@PUT
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@CheckPermission(roles = { Role.SECURITY_ADMIN, Role.RESTRICTED_SECURITY_ADMIN }, blockProxies = true)
public CertificateChain setKeyCertificatePair(RotateKeyAndCertParam rotateKeyAndCertParam) {
    if (!coordinator.isClusterUpgradable()) {
        throw SecurityException.retryables.updatingKeystoreWhileClusterIsUnstable();
    }
    if (!drUtil.isActiveSite()) {
        SiteState state = drUtil.getLocalSite().getState();
        if (state == SiteState.STANDBY_PAUSING || state == SiteState.STANDBY_PAUSED || state == SiteState.STANDBY_RESUMING) {
            throw SecurityException.retryables.failToUpdateKeyStoreDueToStandbyPause();
        }
    }
    Boolean selfsigned = rotateKeyAndCertParam.getSystemSelfSigned();
    byte[] key = null;
    Certificate[] chain = null;
    RSAPrivateKey rsaPrivateKey = null;
    try {
        if (selfsigned != null && selfsigned) {
            KeyCertificateEntry pair = getGenerator().generateKeyCertificatePair();
            // key is needed to clear
            key = pair.getKey();
            chain = pair.getCertificateChain();
        } else {
            KeyAndCertificateChain newKey = rotateKeyAndCertParam.getKeyCertChain();
            if (newKey == null || StringUtils.isBlank(newKey.getCertificateChain()) || StringUtils.isBlank(newKey.getPrivateKey())) {
                throw APIException.badRequests.requiredParameterMissingOrEmpty("key_and_certificate");
            }
            try {
                chain = KeyCertificatePairGenerator.getCertificateChainFromString(newKey.getCertificateChain());
                if (ArrayUtils.isEmpty(chain)) {
                    throw APIException.badRequests.failedToLoadCertificateFromString(newKey.getCertificateChain());
                }
                X509Certificate cert = (X509Certificate) chain[0];
                cert.checkValidity();
                key = SecurityUtil.loadPrivateKeyFromPEMString(newKey.getPrivateKey());
                rsaPrivateKey = (RSAPrivateKey) KeyCertificatePairGenerator.loadPrivateKeyFromBytes(key);
                int keyLength = rsaPrivateKey.getModulus().bitLength();
                if (keyLength < KeyCertificateAlgorithmValuesHolder.FIPS_MINIMAL_KEY_SIZE) {
                    throw APIException.badRequests.invalidParameterBelowMinimum("private_key", keyLength, KeyCertificateAlgorithmValuesHolder.FIPS_MINIMAL_KEY_SIZE, "bits");
                }
                KeyCertificatePairGenerator.validateKeyAndCertPairing(rsaPrivateKey, chain);
                Certificate prevCert = null;
                try {
                    prevCert = getKeyStore().getCertificate(KeystoreEngine.ViPR_KEY_AND_CERTIFICATE_ALIAS);
                    if (cert.equals(prevCert)) {
                        throw APIException.badRequests.newCertificateMustBeSpecified();
                    }
                } catch (KeyStoreException e) {
                    _log.error("failed to get previous certificate", e);
                }
                selfsigned = Boolean.FALSE;
            } catch (CertificateExpiredException | CertificateNotYetValidException e) {
                throw APIException.badRequests.invalidField("key_and_certificate", chain[0].toString());
            } catch (CertificateException e) {
                throw APIException.badRequests.failedToLoadCertificateFromString(newKey.getCertificateChain(), e);
            }
        }
        Boolean selfSignedPrevious = KeyStoreUtil.isSelfGeneratedCertificate(coordConfigStoringHelper);
        // This has to be done before the set keys entry call
        KeyStoreUtil.setSelfGeneratedCertificate(coordConfigStoringHelper, selfsigned);
        try {
            getKeyStore().setKeyEntry(KeystoreEngine.ViPR_KEY_AND_CERTIFICATE_ALIAS, key, chain);
        } catch (KeyStoreException e) {
            _log.error("failed to rotate key and certificate chain.");
            KeyStoreUtil.setSelfGeneratedCertificate(coordConfigStoringHelper, selfSignedPrevious);
            throw SecurityException.fatals.failedToUpdateKeyCertificateEntry(e);
        }
        if (!certificateVersionHelper.updateCertificateVersion()) {
            _log.error("failed to update version for new key and certificate chain.");
            throw SecurityException.fatals.failedToUpdateKeyCertificateEntry();
        }
        return getCertificateChain();
    } finally {
        if (key != null) {
            // SensitiveData.clear(key);
            SecurityUtil.clearSensitiveData(key);
        }
        if (rsaPrivateKey != null) {
            // SensitiveData.clear(rsaPrivateKey);
            SecurityUtil.clearSensitiveData(rsaPrivateKey);
        }
    }
}
Also used : KeyAndCertificateChain(com.emc.vipr.model.keystore.KeyAndCertificateChain) KeyStoreException(java.security.KeyStoreException) KeyCertificateEntry(com.emc.storageos.security.keystore.impl.KeyCertificateEntry) SiteState(com.emc.storageos.coordinator.client.model.SiteState) RSAPrivateKey(java.security.interfaces.RSAPrivateKey) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) Consumes(javax.ws.rs.Consumes) PUT(javax.ws.rs.PUT) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 2 with KeyAndCertificateChain

use of com.emc.vipr.model.keystore.KeyAndCertificateChain in project coprhd-controller by CoprHD.

the class Keystores method save.

@FlashException(value = "updateCertificate", keep = true)
public static void save(KeystoreForm keystore) {
    keystore.validate("keystore");
    if (Validation.hasErrors()) {
        handleError(keystore);
    }
    if (keystore.rotate) {
        try {
            // Here we need a sync call. Else no way to catch exception
            api().regenerateKeyAndCertificate();
        } catch (Exception e) {
            flash.error(e.getMessage());
            handleError(keystore);
        }
    } else {
        String key = null;
        String cert = null;
        try {
            key = FileUtils.readFileToString(keystore.certKey);
        } catch (Exception e) {
            flash.error(MessagesUtils.get("keystore.certKey.invalid.error"));
            handleError(keystore);
        }
        try {
            cert = FileUtils.readFileToString(keystore.certChain);
        } catch (Exception e) {
            flash.error(MessagesUtils.get("keystore.certChain.invalid.error"));
            handleError(keystore);
        }
        try {
            KeyAndCertificateChain keyAndCertChain = new KeyAndCertificateChain();
            keyAndCertChain.setCertificateChain(cert);
            keyAndCertChain.setPrivateKey(key);
            api().setKeyAndCertificateChain(keyAndCertChain);
        } catch (Exception e) {
            flash.error(e.getMessage());
            handleError(keystore);
        }
    }
    flash.success(MessagesUtils.get("keystore.saved.reboot"));
    Maintenance.maintenance(Common.reverseRoute(Keystores.class, "updateCertificate"));
}
Also used : KeyAndCertificateChain(com.emc.vipr.model.keystore.KeyAndCertificateChain) FlashException(controllers.util.FlashException) FlashException(controllers.util.FlashException)

Example 3 with KeyAndCertificateChain

use of com.emc.vipr.model.keystore.KeyAndCertificateChain in project coprhd-controller by CoprHD.

the class ApiTest method testKeystore.

/**
 */
private void testKeystore() {
    /*
         * GET THE CERTIFICATE CHAIN
         */
    // test with a security admin -should succeed
    ClientResponse response = rZAdmin.path("/vdc/keystore").get(ClientResponse.class);
    Assert.assertEquals(200, response.getStatus());
    CertificateChain previousChain = rZAdmin.path("/vdc/keystore").get(CertificateChain.class);
    // test with a non-privileged user user -should succeed
    response = rRootUser2.path("/vdc/keystore").get(ClientResponse.class);
    Assert.assertEquals(200, response.getStatus());
    /*
         * REGENERATE THE KEY AND CERTIFICATE
         */
    // test with a non-privileged user -should fail
    RotateKeyAndCertParam rotateKeyAndCertParam = new RotateKeyAndCertParam();
    rotateKeyAndCertParam.setSystemSelfSigned(true);
    response = rRootUser2.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    Assert.assertEquals(403, response.getStatus());
    // test with a security admin -should succeed
    CertificateChain currChain = rZAdmin.path("/vdc/keystore").put(CertificateChain.class, rotateKeyAndCertParam);
    Assert.assertNotSame(removeNewLines(previousChain.getChain()), removeNewLines(currChain.getChain()));
    waitForClusterToBeStable();
    previousChain = currChain;
    /*
         * SET THE KEY AND CERTIFICATE
         */
    // test with a non-privileged user -should fail
    rotateKeyAndCertParam.setSystemSelfSigned(false);
    KeyAndCertificateChain keyAndCertificateChain = new KeyAndCertificateChain();
    keyAndCertificateChain.setCertificateChain(CERTIFICATE_2048);
    keyAndCertificateChain.setPrivateKey(RSA_KEY_2048);
    rotateKeyAndCertParam.setKeyCertChain(keyAndCertificateChain);
    response = rRootUser2.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    Assert.assertEquals(403, response.getStatus());
    // test with a security admin -should succeed
    currChain = rZAdmin.path("/vdc/keystore").put(CertificateChain.class, rotateKeyAndCertParam);
    Assert.assertNotSame(removeNewLines(previousChain.getChain()), removeNewLines(currChain.getChain()));
    waitForClusterToBeStable();
    // test with the same key and certificate - should fail
    String expectedError = "The specified certificate is already being used. Please specify a new key and certificate pair.";
    response = rZAdmin.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    assertExpectedError(response, 400, ServiceCode.API_BAD_REQUEST, expectedError);
    // test with a mismatched key and certificate
    keyAndCertificateChain.setPrivateKey(RSA_KEY_2048);
    keyAndCertificateChain.setCertificateChain(CERTIFICATE_1024);
    rotateKeyAndCertParam.setKeyCertChain(keyAndCertificateChain);
    response = rZAdmin.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    expectedError = "The provided key and certificate do not match";
    assertExpectedError(response, 400, ServiceCode.API_PARAMETER_INVALID, expectedError);
    // test with bad key
    keyAndCertificateChain = new KeyAndCertificateChain();
    keyAndCertificateChain.setCertificateChain(CERTIFICATE_1024);
    keyAndCertificateChain.setPrivateKey("this is a bad key");
    rotateKeyAndCertParam.setKeyCertChain(keyAndCertificateChain);
    response = rZAdmin.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    expectedError = "Failed to load the private key.";
    assertExpectedError(response, 400, ServiceCode.API_PARAMETER_INVALID, expectedError);
    // test with bad certificate
    keyAndCertificateChain = new KeyAndCertificateChain();
    String badCert = "this is a bad certificate";
    keyAndCertificateChain.setCertificateChain(badCert);
    keyAndCertificateChain.setPrivateKey(RSA_KEY_1024);
    rotateKeyAndCertParam.setKeyCertChain(keyAndCertificateChain);
    response = rZAdmin.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    expectedError = "Failed to load the following certificate(s): " + badCert;
    assertExpectedError(response, 400, ServiceCode.API_PARAMETER_INVALID, expectedError);
    // test with a key that's less than 2048 bits long
    keyAndCertificateChain = new KeyAndCertificateChain();
    keyAndCertificateChain.setCertificateChain(CERTIFICATE_1024);
    keyAndCertificateChain.setPrivateKey(RSA_KEY_1024);
    rotateKeyAndCertParam.setKeyCertChain(keyAndCertificateChain);
    response = rZAdmin.path("/vdc/keystore").put(ClientResponse.class, rotateKeyAndCertParam);
    expectedError = "Invalid parameter private_key was 1,024bits but minimum is 2,048bits";
    assertExpectedError(response, 400, ServiceCode.API_PARAMETER_INVALID_RANGE, expectedError);
}
Also used : ClientResponse(com.sun.jersey.api.client.ClientResponse) KeyAndCertificateChain(com.emc.vipr.model.keystore.KeyAndCertificateChain) CertificateChain(com.emc.vipr.model.keystore.CertificateChain) KeyAndCertificateChain(com.emc.vipr.model.keystore.KeyAndCertificateChain) RotateKeyAndCertParam(com.emc.vipr.model.keystore.RotateKeyAndCertParam)

Aggregations

KeyAndCertificateChain (com.emc.vipr.model.keystore.KeyAndCertificateChain)3 SiteState (com.emc.storageos.coordinator.client.model.SiteState)1 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)1 KeyCertificateEntry (com.emc.storageos.security.keystore.impl.KeyCertificateEntry)1 CertificateChain (com.emc.vipr.model.keystore.CertificateChain)1 RotateKeyAndCertParam (com.emc.vipr.model.keystore.RotateKeyAndCertParam)1 ClientResponse (com.sun.jersey.api.client.ClientResponse)1 FlashException (controllers.util.FlashException)1 KeyStoreException (java.security.KeyStoreException)1 RSAPrivateKey (java.security.interfaces.RSAPrivateKey)1 Consumes (javax.ws.rs.Consumes)1 PUT (javax.ws.rs.PUT)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1