1
+ from itertools import islice
1
2
from ScoutSuite .core .console import print_warning , print_exception
2
3
from ScoutSuite .providers .azure .facade .base import AzureFacade
3
4
from ScoutSuite .providers .azure .resources .base import AzureResources
@@ -13,7 +14,6 @@ def __init__(self, facade: AzureFacade, subscription_id: str):
13
14
self .subscription_id = subscription_id
14
15
# Hardcoded limit of keys per key vault.
15
16
self .KEY_FETCH_LIMIT = 3
16
- self .keys_detailed_fetched = 0
17
17
18
18
async def fetch_all (self ):
19
19
for raw_vault in await self .facade .keyvault .get_key_vaults (self .subscription_id ):
@@ -25,30 +25,20 @@ async def fetch_all(self):
25
25
async def fetch_keys (self , resource_group_name , keyvault_name ):
26
26
keys = []
27
27
try :
28
- self .keys_detailed_fetched = 0
29
- for raw_key in await self .facade .keyvault .get_keys (self .subscription_id , resource_group_name , keyvault_name ):
30
- raw_key_extra = await self .fetch_key (resource_group_name , keyvault_name , raw_key .name , raw_key .attributes .enabled )
31
- key = self ._parse_key (raw_key , raw_key_extra )
28
+ raw_keys = await self .facade .keyvault .get_keys (self .subscription_id , resource_group_name , keyvault_name )
29
+ # Retrieve a list of
30
+ key_detailed_names = list (islice ((k .name for k in raw_keys if k .attributes .enabled ), self .KEY_FETCH_LIMIT ))
31
+ raw_key_details = await self .facade .keyvault .get_detailed_keys (self .subscription_id , resource_group_name , keyvault_name , key_detailed_names )
32
+ raw_key_details = dict ((k .id , k ) for k in raw_key_details )
33
+ for raw_key in raw_keys :
34
+ raw_key_detailed = raw_key_details .get (raw_key .id )
35
+ key = self ._parse_key (raw_key , raw_key_detailed )
32
36
keys .append (key )
33
37
except Exception as e :
34
38
print_exception (f'Failed to list Keys in Key Vault { keyvault_name } : { e } ' )
35
39
return []
36
40
return keys
37
41
38
- async def fetch_key (self , resource_group_name , keyvault_name , key_name , is_key_enabled ):
39
- if not is_key_enabled :
40
- return None
41
- if self .keys_detailed_fetched >= self .KEY_FETCH_LIMIT :
42
- print_warning (f'Did not fetch details for Key { keyvault_name } /{ key_name } . Some results may be incomplete.' )
43
- return None
44
- try :
45
- raw_key_extra = await self .facade .keyvault .get_key (self .subscription_id , resource_group_name , keyvault_name , key_name )
46
- self .keys_detailed_fetched = self .keys_detailed_fetched + 1
47
- except Exception as e :
48
- print_exception (f'Failed to fetch Keys { keyvault_name } /{ key_name } : { e } ' )
49
- return None
50
- return raw_key_extra
51
-
52
42
async def fetch_secrets (self , resource_group_name , keyvault_name ):
53
43
secrets = []
54
44
try :
@@ -84,7 +74,7 @@ def _parse_key_vault(self, raw_vault):
84
74
def _is_public_access_allowed (self , raw_vault ):
85
75
return raw_vault .properties .network_acls is None or raw_vault .properties .network_acls .default_action == 'Allow'
86
76
87
- def _parse_key (self , raw_key , raw_key_extra ):
77
+ def _parse_key (self , raw_key , raw_key_detailed ):
88
78
raw_attrs = raw_key .attributes
89
79
key = {}
90
80
key ['id' ] = get_non_provider_id (raw_key .id )
@@ -94,7 +84,7 @@ def _parse_key(self, raw_key, raw_key_extra):
94
84
key ['not_before' ] = datetime .fromtimestamp (raw_attrs .not_before , tz = timezone .utc ) if raw_attrs .not_before else None
95
85
key ['exportable' ] = raw_attrs .exportable
96
86
key ['recovery_level' ] = raw_attrs .recovery_level
97
- key ['auto_rotation_enabled' ] = self ._is_auto_rotation_enabled (raw_key_extra .rotation_policy ) if raw_key_extra else None
87
+ key ['auto_rotation_enabled' ] = self ._is_auto_rotation_enabled (raw_key_detailed .rotation_policy ) if raw_key_detailed else None
98
88
return key
99
89
100
90
def _parse_secret (self , raw_secret ):
0 commit comments