mirror of https://github.com/apache/cloudstack.git
Apple base416 passphrase enc (#240)
* Move PassphraseVO to use String instead of byte[] to support Encrypt annotation * Check for unencrypted passphrases before migrating passphrase table --------- Co-authored-by: Marcus Sorensen <mls@apple.com> Fixes #239 This PR moves PassphraseVO passphrase to String type. Since the GenericDaoBase manipulates encrypted fields as Strings we don't improve anything by handling as byte arrays. We still use byte arrays to pass these values down to the agents and we can get some security gains there. This PR also handles cases where the passphrase field may be previously unencrypted, and upgrades them to encrypted fields using the old encryption during cloudstack-migrate-databases. Then the process can upgrade to new encryption normally.
This commit is contained in:
parent
a9fb36174d
commit
5604638b84
|
|
@ -486,6 +486,8 @@ public class EncryptionSecretKeyChanger {
|
|||
migrateImageStoreUrlForCifs(conn);
|
||||
migrateStoragePoolPathForSMB(conn);
|
||||
|
||||
preparePassphraseTableForMigration(conn);
|
||||
|
||||
// migrate columns with annotation @Encrypt
|
||||
migrateEncryptedTableColumns(conn);
|
||||
|
||||
|
|
@ -665,6 +667,56 @@ public class EncryptionSecretKeyChanger {
|
|||
System.out.println("End migrate user vm deploy_as_is details");
|
||||
}
|
||||
|
||||
// encrypt any unencrypted passphrases using old style encryptor before we migrate
|
||||
private void preparePassphraseTableForMigration(Connection conn) throws SQLException {
|
||||
System.out.println("Preparing passphrase table by checking for unencrypted passphrases");
|
||||
|
||||
try(PreparedStatement selectPstmt = conn.prepareStatement("SELECT id, passphrase FROM passphrase");
|
||||
ResultSet rs = selectPstmt.executeQuery();
|
||||
PreparedStatement updatePstmt = conn.prepareStatement("UPDATE passphrase SET passphrase=? WHERE id=?")
|
||||
) {
|
||||
while(rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
String value = rs.getString(2);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// passphrases are 64 bytes long when unencrypted, longer when encrypted
|
||||
if (value.length() == 64) {
|
||||
// just confirm it won't decrypt, to be safe, before assuming raw value and encrypting
|
||||
try {
|
||||
oldEncryptor.decrypt(value);
|
||||
System.out.printf("Passphrase table entry db id %d was already encrypted with old encryption\n", id);
|
||||
} catch(EncryptionException | CloudRuntimeException ex) {
|
||||
String message = null;
|
||||
if (ex instanceof CloudRuntimeException && ex.getCause() != null) {
|
||||
if ((ex.getCause() instanceof EncryptionException)) {
|
||||
message = ex.getCause().getMessage();
|
||||
}
|
||||
} else if (ex instanceof EncryptionException) {
|
||||
message = ex.getMessage();
|
||||
}
|
||||
|
||||
if (message != null && message.contains("Failed to decrypt")) {
|
||||
System.out.printf("Encrypting unencrypted passphrase table entry db id %d before migration using old encryption\n", id);
|
||||
String encrypted = oldEncryptor.encrypt(value);
|
||||
updatePstmt.setBytes(1, encrypted.getBytes(StandardCharsets.UTF_8));
|
||||
updatePstmt.setLong(2, id);
|
||||
updatePstmt.executeUpdate();
|
||||
} else {
|
||||
throwCloudRuntimeException("Unhandled EncryptionException", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throwCloudRuntimeException("Unable to prepare passphrase table", e);
|
||||
}
|
||||
|
||||
System.out.println("End preparing passphrase table");
|
||||
}
|
||||
|
||||
private void migrateImageStoreUrlForCifs(Connection conn) {
|
||||
System.out.println("Begin migrate image store url if protocol is cifs");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue