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);
}
}
}
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"));
}
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);
}
Aggregations