4545import com .cloud .utils .db .SearchCriteria ;
4646import com .cloud .utils .db .Transaction ;
4747import com .cloud .utils .db .TransactionCallbackWithException ;
48- import com .cloud .utils .db .TransactionStatus ;
4948import com .cloud .utils .exception .CloudRuntimeException ;
5049import org .apache .cloudstack .api .ApiCommandResourceType ;
5150import org .apache .cloudstack .api .command .admin .kms .MigrateVolumesToKMSCmd ;
@@ -453,8 +452,7 @@ KMSKey createUserKMSKey(Long accountId, Long domainId, Long zoneId,
453452 kmsKey .setHsmProfileId (finalProfileId );
454453 kmsKey = kmsKeyDao .persist (kmsKey );
455454
456- KMSKekVersionVO initialVersion = new KMSKekVersionVO (kmsKey .getId (), 1 , providerKekLabel ,
457- KMSKekVersionVO .Status .Active );
455+ KMSKekVersionVO initialVersion = new KMSKekVersionVO (kmsKey .getId (), 1 , providerKekLabel );
458456 initialVersion .setHsmProfileId (finalProfileId );
459457 initialVersion = kmsKekVersionDao .persist (initialVersion );
460458
@@ -578,22 +576,39 @@ public SuccessResponse deleteKMSKey(DeleteKMSKeyCmd cmd) throws KMSException {
578576
579577 KMSKeyVO key = findKMSKeyAndCheckAccess (cmd .getId (), caller );
580578
581- deleteUserKMSKey (key , caller );
579+ deleteUserKMSKey (key );
582580 return new SuccessResponse ();
583581 }
584582
585- private void deleteUserKMSKey (KMSKeyVO key , Account caller ) throws KMSException {
583+ private void deleteUserKMSKey (KMSKeyVO key ) throws KMSException {
586584 long wrappedKeyCount = kmsWrappedKeyDao .countByKmsKeyId (key .getId ());
587585 if (wrappedKeyCount > 0 ) {
588586 throw new InvalidParameterValueException ("Cannot delete KMS key: " + key + ". " + wrappedKeyCount +
589587 " wrapped key(s) still reference this key" );
590588 }
591589
592- kmsKeyDao .remove (key .getId ());
593590 if (volumeDao .existsWithKmsKey (key .getId ())) {
594591 throw new InvalidParameterValueException ("Cannot delete KMS key: " + key + ". " +
595592 "There are Volumes which still reference this key" );
596593 }
594+
595+ List <KMSKekVersionVO > kekVersions = kmsKekVersionDao .listByKmsKeyId (key .getId ());
596+ for (KMSKekVersionVO kekVersion : kekVersions ) {
597+ try {
598+ HSMProfileVO hsmProfile = hsmProfileDao .findById (kekVersion .getHsmProfileId ());
599+ if (hsmProfile != null ) {
600+ KMSProvider provider = getKMSProvider (hsmProfile .getProtocol ());
601+ provider .deleteKek (kekVersion .getKekLabel ());
602+ logger .info ("Deleted KEK {} (v{}) from provider {}" ,
603+ kekVersion .getKekLabel (), kekVersion .getVersionNumber (), provider .getProviderName ());
604+ }
605+ } catch (Exception e ) {
606+ logger .warn ("Failed to delete KEK {} (v{}) from provider during KMS key deletion: {}" ,
607+ kekVersion .getKekLabel (), kekVersion .getVersionNumber (), e .getMessage ());
608+ }
609+ }
610+
611+ kmsKeyDao .remove (key .getId ());
597612 logger .info ("Deleted KMS key {}" , key );
598613 }
599614
@@ -663,13 +678,13 @@ String rotateKek(KMSKeyVO kmsKey, String oldKekLabel, String newKekLabel, int ke
663678 try {
664679 logger .info ("Starting KEK rotation from {} to {} for kms key {}" , oldKekLabel , newKekLabel , kmsKey );
665680
666- final KMSKekVersionVO newVersionEntity = new KMSKekVersionVO ();
667681 if (StringUtils .isEmpty (newKekLabel )) {
668682 List <KMSKekVersionVO > existingVersions = kmsKekVersionDao .listByKmsKeyId (kmsKey .getId ());
669683 int nextVersion = existingVersions .stream ().mapToInt (KMSKekVersionVO ::getVersionNumber ).max ().orElse (0 ) + 1 ;
670684 newKekLabel = kmsKey .getPurpose ().generateKekLabel (kmsKey .getDomainId (), kmsKey .getAccountId (),
671685 kmsKey .getUuid (), nextVersion );
672686 }
687+ final KMSKekVersionVO newVersionEntity = new KMSKekVersionVO (kmsKey .getId (), newKekLabel );
673688
674689 String finalNewKekLabel = newKekLabel ;
675690 Long newProfileId = newHSMProfile .getId ();
@@ -679,20 +694,19 @@ String rotateKek(KMSKeyVO kmsKey, String oldKekLabel, String newKekLabel, int ke
679694
680695 try {
681696 KMSKekVersionVO newVersion = Transaction
682- .execute (new TransactionCallbackWithException <KMSKekVersionVO , KMSException >() {
683- @ Override
684- public KMSKekVersionVO doInTransaction (TransactionStatus status ) throws KMSException {
685- newVersionEntity .setKmsKeyId (kmsKey .getId ());
686- newVersionEntity .setHsmProfileId (newProfileId );
687- KMSKekVersionVO version = createKekVersion (newVersionEntity );
688-
689- if (!newProfileId .equals (kmsKey .getHsmProfileId ())) {
690- kmsKey .setHsmProfileId (newProfileId );
691- kmsKeyDao .update (kmsKey .getId (), kmsKey );
692- logger .info ("Updated KMS key {} to use HSM profile {}" , kmsKey , finalHSMProfile );
693- }
694- return version ;
697+ .execute ((TransactionCallbackWithException <KMSKekVersionVO , KMSException >) status -> {
698+ newVersionEntity .setKmsKeyId (kmsKey .getId ());
699+ newVersionEntity .setHsmProfileId (newProfileId );
700+ newVersionEntity .setKekLabel (finalNewKekLabel );
701+ KMSKekVersionVO version = createKekVersion (newVersionEntity );
702+
703+ if (!newProfileId .equals (kmsKey .getHsmProfileId ())) {
704+ kmsKey .setHsmProfileId (newProfileId );
705+ logger .info ("Updated KMS key {} to use HSM profile {}" , kmsKey , finalHSMProfile );
695706 }
707+ kmsKey .setKekLabel (finalNewKekLabel );
708+ kmsKeyDao .update (kmsKey .getId (), kmsKey );
709+ return version ;
696710 });
697711
698712 logger .info ("KEK rotation: KMS key {} now has {} versions (active: v{}, previous: v{})" ,
0 commit comments