Signtool говорит, что подпись прошла успешно, но в файл добавляется ноль подписей - PullRequest
0 голосов
/ 30 марта 2020

Я работаю над нестандартным поставщиком CNG, чтобы разрешить подпись Authenticode с помощью частного API HSM.

Я внедрил провайдера КПГ и зарегистрировался. Мне удалось использовать signtool.exe для вызова API-интерфейса для частной подписи, предоставляемого HSM.

Вот команда, которую я использую

signtool.exe sign /v /debug /f cert.cer /csp "Sample Key Storage Provider" /k "keyid" /t http://timestamp.digicert.com /fd sha256 helloworld.exe

Команда выдает следующий вывод

The following certificates were considered:
    Issued to: Sample test certificate
    Issued by: Sample Certificate Authority
    Expires:   Thu May 28 13:40:10 2020
    SHA1 hash: A679DF5E89B9C23E57E89AEB434CA98230F52DC3

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
The following certificate was selected:
    Issued to: Sample test certificate
    Issued by: Sample Certificate Authority
    Expires:   Thu May 28 13:40:10 2020
    SHA1 hash: A679DF5E89B9C23E57E89AEB434CA98230F52DC3


The following additional certificates will be attached:
Done Adding Additional Store
[KSP Logging] Signature size: 256
[KSP Logging] Signhash status: 0
[KSP Logging] hash digest is
Wr╥ìΩ╤ⁿír1é┘│vCx²▀2╡3┼1┼!░¢╝╙
[KSP Logging] digest size 32
[KSP Logging] calling HSM for signing
[KSP Logging] Call to HSM success
[KSP Logging] Signature from API
Aq#^y╝¢O$Ü╟╓W╪▄s║U≡αK«åqDKÿï^NBD=érî╢Üùo╫à█RXàmf┐█K
┤╩F.I╠╗Hsé]▐)ùFR#D,y;╣JX╝H┼c,
[KSP Logging] Signature size 256
[KSP Logging] pbsig: Aq#^y╝¢O$Ü╟╓W╪▄s║U≡αK«åqDKÿï^NBD=érî╢Üùo╫à█RXàmf┐█K
┤╩F.I╠╗Hsé]▐)ùFR#D,y;╣JX╝H┼c,
[KSP Logging] Signhash status: 0
Successfully signed: helloworld.exe

Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0

Однако, когда я запускаю проверку, ниже вывод

> signtool.exe verify /v /pa helloworld.exe

Verifying: helloworld.exe
Signature Index: 0 (Primary Signature)
Hash of file (sha256): 3338A11DDAB9CBB7B39E65C30F235C2DF8EDE17BB5BE759A3213D25EC286F390

Signing Certificate Chain:
    Issued to: Sample Certificate Authority
    Issued by: Sample Certificate Authority
    Expires:   Fri Feb 07 21:37:36 2070
    SHA1 hash: 2B5B37DADFCBD018BDB2789176A69708FFCA25E0

        Issued to: Sample test certificate
        Issued by: Sample Certificate Authority
        Expires:   Thu May 28 13:40:10 2020
        SHA1 hash: A679DF5E89B9C23E57E89AEB434CA98230F52DC3

The signature is timestamped: Sun Mar 29 16:44:01 2020
Timestamp Verified by:
    Issued to: DigiCert Assured ID Root CA
    Issued by: DigiCert Assured ID Root CA
    Expires:   Sun Nov 09 17:00:00 2031
    SHA1 hash: 0563B8630D62D75ABBC8AB1E4BDFB5A899B24D43

        Issued to: DigiCert SHA2 Assured ID Timestamping CA
        Issued by: DigiCert Assured ID Root CA
        Expires:   Tue Jan 07 05:00:00 2031
        SHA1 hash: 3BA63A6E4841355772DEBEF9CDCF4D5AF353A297

            Issued to: TIMESTAMP-SHA256-2019-10-15
            Issued by: DigiCert SHA2 Assured ID Timestamping CA
            Expires:   Wed Oct 16 17:00:00 2030
            SHA1 hash: 0325BD505EDA96302DC22F4FA01E4C28BE2834C5

SignTool Error: No signature found.

Number of files successfully Verified: 0
Number of warnings: 0
Number of errors: 1

Ниже приведен код KSPSignHa sh в моем провайдере CNG

SECURITY_STATUS
WINAPI
SampleKSPSignHash(
    __in    NCRYPT_PROV_HANDLE hProvider,
    __in    NCRYPT_KEY_HANDLE hKey,
    __in_opt    VOID  *pPaddingInfo,
    __in_bcount(cbHashValue) PBYTE pbHashValue,
    __in    DWORD   cbHashValue,
    __out_bcount_part_opt(cbSignaturee, *pcbResult) PBYTE pbSignature,
    __in    DWORD   cbSignaturee,
    __out   DWORD * pcbResult,
    __in    DWORD   dwFlags)
{
    SECURITY_STATUS     Status = NTE_INTERNAL_ERROR;
    NTSTATUS            ntStatus = STATUS_INTERNAL_ERROR;
    SAMPLEKSP_KEY       *pKey = NULL;
    DWORD               cbTmpSig = 0;
    DWORD               cbTmp = 0;
    UNREFERENCED_PARAMETER(hProvider);

    debug("In SampleKSPSignHash\n");
    //
    // Validate input parameters.
    //
    pKey = SampleKspValidateKeyHandle(hKey);

    if(pKey == NULL)
    {
        Status = NTE_INVALID_HANDLE;
        goto cleanup;
    }

    if (pcbResult == NULL)
    {
        Status = NTE_INVALID_PARAMETER;
        goto cleanup;
    }

    if(dwFlags & ~(BCRYPT_PAD_PKCS1 | BCRYPT_PAD_PSS | NCRYPT_SILENT_FLAG))
    {
        Status = NTE_BAD_FLAGS;
        goto cleanup;
    }

    if(pKey->fFinished == FALSE)
    {
        Status = NTE_BAD_KEY_STATE;
        goto cleanup;
    }

    //
    // Verify that this key is allowed to perform sign operations.
    //

    if (pbSignature == NULL)
    {
       //This call is to query the size.
       ntStatus = BCryptGetProperty(pKey->hPublicKey,
                           BCRYPT_SIGNATURE_LENGTH,
                           (BYTE*)&cbTmpSig,
                           sizeof(DWORD),
                           &cbTmp,
                           0);
        if (!NT_SUCCESS(ntStatus))
        {
            Status = NormalizeNteStatus(ntStatus);
            goto cleanup;
        }

        Status = ERROR_SUCCESS;
        *pcbResult = cbTmpSig;
        goto cleanup;
    }

    if(pbHashValue == NULL || cbHashValue == 0)
    {
        Status = NTE_INVALID_PARAMETER;
        goto cleanup;
    }

    pbSignature = hsmSign(pbHashValue, cbHashValue, &pKey->pszKeyName);
    printf("pbsig: %s\n", pbSignature);

    Status = ERROR_SUCCESS;

cleanup:
    printf("Signhash status: %X \n", Status);
    return Status;
}

HSMClient. cpp

extern "C" unsigned char* hsmSign(const unsigned char* digest, int digestSize, const char* keyId);

unsigned char* hsmSign(const unsigned char* digest, int digestSize, const char* keyId) {
    ...
    request.SetKeyId(keyId);
    request.SetDigest(buffer);

    return hsm_client.Sign(request).GetResult().GetSignature().GetUnderlyingData();
}

Что я делаю неправильно, если двоичный файл не имеет подписи?

...