func decryptDataWithCert()

in pkg/decrypt/decypt_windows.go [115:173]


func decryptDataWithCert(decoded []byte, cert *syscall.CertContext, storeHandle uintptr) ([]byte, error) {
	var cryptDecryptMessagePara cryptDecryptMessagePara
	cryptDecryptMessagePara.cbSize = uint32(len(decoded))
	cryptDecryptMessagePara.dwMsgAndCertEncodingType = uint32(windows.X509_ASN_ENCODING | windows.PKCS_7_ASN_ENCODING)
	cryptDecryptMessagePara.cCertStore = uint32(1)
	cryptDecryptMessagePara.rghCertStore = uintptr(unsafe.Pointer(&storeHandle))
	cryptDecryptMessagePara.dwFlags = uint32(0)

	// Call it once to get the decrypted data size
	var pbEncryptedBlob *byte
	var cbDecryptedBlob uint32
	pbEncryptedBlob = &decoded[0]
	raw, _, err := syscall.Syscall6(
		crypto.ProcCryptDecryptMessage.Addr(),
		6,
		uintptr(unsafe.Pointer(&cryptDecryptMessagePara)),
		uintptr(unsafe.Pointer(pbEncryptedBlob)),
		uintptr(len(decoded)),
		uintptr(0),
		uintptr(unsafe.Pointer(&cbDecryptedBlob)),
		uintptr(0),
	)
	if raw == 0 {
		errno := syscall.Errno(err)
		if errno == crypto.CrypteEAsn1BadTag {
			return nil, extensionerrors.ErrInvalidProtectedSettingsData
		}

		return nil, fmt.Errorf("VmExtension: Could not decrypt data due to '%d'", syscall.Errno(err))
	}

	// Create our buffer
	if cbDecryptedBlob == 0 {
		return nil, nil
	}

	var decryptedBytes = make([]byte, cbDecryptedBlob)
	var pdecryptedBytes *byte
	pdecryptedBytes = &decryptedBytes[0]

	raw, _, err = syscall.Syscall6(
		crypto.ProcCryptDecryptMessage.Addr(),
		6,
		uintptr(unsafe.Pointer(&cryptDecryptMessagePara)),
		uintptr(unsafe.Pointer(pbEncryptedBlob)),
		uintptr(len(decoded)),
		uintptr(unsafe.Pointer(pdecryptedBytes)),
		uintptr(unsafe.Pointer(&cbDecryptedBlob)),
		uintptr(0),
	)
	if raw == 0 {
		return nil, fmt.Errorf("VmExtension: Could not decrypt data due to '%d'", syscall.Errno(err))
	}

	// Get rid of the null terminator or deserialization will fail
	returnedBytes := decryptedBytes[:cbDecryptedBlob]

	return returnedBytes, nil
}