go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/windows/bitlocker.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package windows 5 6 import ( 7 "encoding/json" 8 "io" 9 10 "go.mondoo.com/cnquery/providers/os/connection/shared" 11 "go.mondoo.com/cnquery/providers/os/resources/powershell" 12 ) 13 14 // https://docs.microsoft.com/en-us/windows/win32/secprov/getconversionstatus-win32-encryptablevolume 15 var conversionStatusValues = map[int64]string{ 16 0: "FullyDecrypted", 17 1: "FullyEncrypted", 18 2: "EncryptionInProgress", 19 3: "DecryptionInProgress", 20 4: "EncryptionPaused", 21 5: "DecryptionPaused", 22 } 23 24 // https://docs.microsoft.com/en-us/windows/win32/secprov/getconversionstatus-win32-encryptablevolume 25 var wipingStatusValues = map[int64]string{ 26 0: "FreeSpaceNotWiped", 27 1: "FreeSpaceWiped", 28 2: "FreeSpaceWipingInProgress", 29 3: "FreeSpaceWipingPaused", 30 } 31 32 // https://docs.microsoft.com/en-us/windows/win32/secprov/getencryptionmethod-win32-encryptablevolume 33 var encryptionMethodValues = map[int64]string{ 34 0: "NONE", 35 1: "AES_128_WITH_DIFFUSER", 36 2: "AES_256_WITH_DIFFUSER", 37 3: "AES_128", 38 4: "AES_256", 39 5: "HARDWARE_ENCRYPTION", 40 6: "XTS_AES_128", 41 7: "XTS_AES_256", 42 } 43 44 var fveVersionValues = map[int64]string{ 45 0: "Unknown", 46 1: "Vista", 47 2: "Win7", 48 } 49 50 // https://docs.microsoft.com/en-us/windows/win32/secprov/getprotectionstatus-win32-encryptablevolume 51 var protectionStatusValues = map[int64]string{ 52 0: "Unprotected", 53 1: "Protected", 54 2: "Unknown", 55 } 56 57 const bitlockerStatusScript = ` 58 $encryptedVolumes = Get-WmiObject -namespace "Root\cimv2\security\MicrosoftVolumeEncryption" -ClassName "Win32_Encryptablevolume" 59 60 $bitlockerStatus = @() 61 62 foreach ($volume in $encryptedVolumes) { 63 64 $wmiVersion = $volume.GetVersion() 65 $version = New-Object psobject -Property @{ 66 "Version" = $wmiVersion.Version; 67 } 68 69 $wmiConversionStatus = $volume.GetConversionStatus() 70 $conversionStatus = New-Object psobject -Property @{ 71 "ConversionStatus" = $wmiConversionStatus.ConversionStatus; 72 "EncryptionFlags" = $wmiConversionStatus.EncryptionFlags; 73 "EncryptionPercentage" = $wmiConversionStatus.EncryptionPercentage; 74 "WipingPercentage" = $wmiConversionStatus.WipingPercentage; 75 "WipingStatus" = $wmiConversionStatus.WipingStatus; 76 } 77 78 $wmilockStatus = $volume.GetLockStatus() 79 $lockStatus = New-Object psobject -Property @{ 80 "LockStatus" = $wmilockStatus.LockStatus; 81 } 82 83 $volumeStatus = New-Object PSObject 84 Add-Member -InputObject $volumeStatus -MemberType NoteProperty -Name volume -Value $volume 85 Add-Member -InputObject $volumeStatus -MemberType NoteProperty -Name version -Value $version 86 Add-Member -InputObject $volumeStatus -MemberType NoteProperty -Name conversionStatus -Value $conversionStatus 87 Add-Member -InputObject $volumeStatus -MemberType NoteProperty -Name lockStatus -Value $lockStatus 88 $bitlockerStatus = $bitlockerStatus + $volumeStatus 89 } 90 ConvertTo-Json -Depth 3 -Compress $bitlockerStatus 91 ` 92 93 // powershellBitlockerVolumeStatus is the struct to parse the powershell result 94 type powershellBitlockerVolumeStatus struct { 95 Volume struct { 96 ConversionStatus int64 97 DeviceID string 98 DriveLetter string 99 EncryptionMethod int64 100 IsVolumeInitializedForProtection bool 101 PersistentVolumeID string 102 ProtectionStatus int64 103 VolumeType int64 104 } 105 Version struct { 106 Version int64 107 } 108 ConversionStatus struct { 109 ConversionStatus int64 110 WipingStatus int64 111 WipingPercentage int64 112 EncryptionFlags int64 113 EncryptionPercentage int64 114 } 115 LockStatus struct { 116 LockStatus int64 117 } 118 } 119 120 // bitlockerVolumeStatus returns the status for one individual volume 121 type bitlockerVolumeStatus struct { 122 DeviceID string 123 DriveLetter string 124 ConversionStatus conversionStatus 125 EncryptionMethod statusCode 126 LockStatus int64 127 PersistentVolumeID string 128 ProtectionStatus statusCode 129 Version statusCode 130 } 131 132 type conversionStatus struct { 133 ConversionStatus statusCode 134 WipingStatus statusCode 135 WipingPercentage int64 136 EncryptionPercentage int64 137 } 138 139 type statusCode struct { 140 Code int64 `json:"code"` 141 Text string `json:"text"` 142 } 143 144 func GetBitLockerVolumes(p shared.Connection) ([]bitlockerVolumeStatus, error) { 145 c, err := p.RunCommand(powershell.Encode(bitlockerStatusScript)) 146 if err != nil { 147 return nil, err 148 } 149 150 return ParseWindowsBitlockerStatus(c.Stdout) 151 } 152 153 func ParseWindowsBitlockerStatus(r io.Reader) ([]bitlockerVolumeStatus, error) { 154 var volumeStatus []powershellBitlockerVolumeStatus 155 data, err := io.ReadAll(r) 156 if err != nil { 157 return nil, err 158 } 159 160 err = json.Unmarshal(data, &volumeStatus) 161 if err != nil { 162 return nil, err 163 } 164 165 res := []bitlockerVolumeStatus{} 166 for i := range volumeStatus { 167 v := volumeStatus[i] 168 169 bvs := bitlockerVolumeStatus{ 170 DeviceID: v.Volume.DeviceID, 171 DriveLetter: v.Volume.DriveLetter, 172 ConversionStatus: conversionStatus{ 173 ConversionStatus: statusCode{ 174 Code: v.ConversionStatus.ConversionStatus, 175 Text: conversionStatusValues[v.ConversionStatus.ConversionStatus], 176 }, 177 EncryptionPercentage: v.ConversionStatus.EncryptionPercentage, 178 WipingStatus: statusCode{ 179 Code: v.ConversionStatus.WipingStatus, 180 Text: wipingStatusValues[v.ConversionStatus.WipingStatus], 181 }, 182 WipingPercentage: v.ConversionStatus.WipingPercentage, 183 }, 184 EncryptionMethod: statusCode{ 185 Code: v.Volume.EncryptionMethod, 186 Text: encryptionMethodValues[v.Volume.EncryptionMethod], 187 }, 188 LockStatus: v.LockStatus.LockStatus, 189 PersistentVolumeID: v.Volume.PersistentVolumeID, 190 ProtectionStatus: statusCode{ 191 Code: v.Volume.ProtectionStatus, 192 Text: protectionStatusValues[v.Volume.ProtectionStatus], 193 }, 194 Version: statusCode{ 195 Code: v.Version.Version, 196 Text: fveVersionValues[v.Version.Version], 197 }, 198 } 199 res = append(res, bvs) 200 } 201 return res, nil 202 }