How to retrieve information from multiple/dual code signatures on an executable file

后端 未结 2 1396
你的背包
你的背包 2021-01-02 18:13

I\'ve been using the following code (taken from KB323809 article) to retrieve information about the code signature on the executable file. This works fine for a single digit

相关标签:
2条回答
  • 2021-01-02 18:22

    In addition to the answer of Daniel Sie.

    Found an attribute (szOID_NESTED_SIGNATURE) that would contain the CMSG_SIGNER_INFO that need to be decoded with following steps (this is Delphi code but sense is clear):

      LNestedMsg := CryptMsgOpenToDecode(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, 0, 0, 0, nil, 0);
      CryptMsgUpdate(LNestedMsg, LFindedAttr.rgValue.pbData, LFindedAttr.rgValue.cbData, True);
      CryptMsgGetParam(LNestedMsg, CMSG_SIGNER_INFO_PARAM, 0, nil, @LSize);
      CryptMsgGetParam(LNestedMsg, CMSG_SIGNER_INFO_PARAM, 0, LNestedSignerInfo, @LSize);
    

    The acquired CMSG_SIGNER_INFO (LNestedSignerInfo) is the nested signature (in our case SHA2 signature).

    To obtain the time-stamp information (RFC3161) of that signature - search the Unauthenticated attribute with pszObjId = szOID_RFC3161_counterSign (1.3.6.1.4.1.311.3.3.1).

    Found attribute would contain the CMSG_SIGNER_INFO of the time-stamp counter signature, that also need to be decoded by previously described steps (CryptMsgOpenToDecode, CryptMsgUpdate, CryptMsgGetParam).

    The CERT_CONTEXT of nested signature or timestamp counter signature is need to be searched in store with is obtained from corresponding HCRYPTMSG (result of CryptMsgOpenToDecode).

      LNestedStore := CertOpenStore(CERT_STORE_PROV_MSG, PKCS_7_ASN_ENCODING or X509_ASN_ENCODING, 0, 0, LNestedMsg);
      LTimeStampStore := CertOpenStore(CERT_STORE_PROV_MSG, PKCS_7_ASN_ENCODING or X509_ASN_ENCODING, 0, 0, LTimeStampMsg);
    

    Example to decode szOID_RFC3161_counterSign attribute:

    LNestedSignerAttr := LNestedSigner.UnauthAttrs.rgAttr;
    for I := 0 to LNestedSigner.UnauthAttrs.cAttr - 1 do
    begin
      if SameText(string(LNestedSignerAttr.pszObjId), szOID_RFC3161_counterSign) then
      begin
        LNestedTimeStampMsg := CryptMsgOpenToDecode(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, 0, 0, 0, nil, nil);
        if not Assigned(LNestedTimeStampMsg) then
          RaiseLastOSError;
        try
          if not CryptMsgUpdate(LNestedTimeStampMsg, LNestedSignerAttr.rgValue.pbData, LNestedSignerAttr.rgValue.cbData, True) then
            RaiseLastOSError;
    
          if not CryptMsgGetParam(LNestedTimeStampMsg, CMSG_SIGNER_INFO_PARAM, 0, nil, @LSize) then
            RaiseLastOSError;
          GetMem(LTimeStampSigner, LSize);
          try
            if not CryptMsgGetParam(LNestedTimeStampMsg, CMSG_SIGNER_INFO_PARAM, 0, LTimeStampSigner, @LSize) then
              RaiseLastOSError;
    
            LAttr := LTimeStampSigner.AuthAttrs.rgAttr;
            for J := 0 to LTimeStampSigner.AuthAttrs.cAttr - 1 do
            begin
              if SameText(string(LAttr.pszObjId), szOID_RSA_signingTime) then
              begin
                LSize := SizeOf(LFileTime);
                if not CryptDecodeObject(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,
                  szOID_RSA_signingTime, LAttr.rgValue.pbData, LAttr.rgValue.cbData, 0, @LFileTime, @LSize) then
                  RaiseLastOSError;
    
                if FileTimeToLocalFileTime(@LFileTime, LLocalFileTime)
                  and FileTimeToSystemTime(@LLocalFileTime, LSystemTime) then
                    SHA2TimeStamp := SystemTimeToDateTime(LSystemTime)
                else
                  SHA2TimeStamp := 0;
    
              end;
              Inc(LAttr);
            end;
    
          finally
            FreeMem(LTimeStampSigner);
          end;
        finally
          if not CryptMsgClose(LNestedTimeStampMsg) then
            RaiseLastOSError;
        end;
      end;
    
      Inc(LNestedSignerAttr);
    end;
    
    0 讨论(0)
  • 2021-01-02 18:23

    Authenticode stores secondary signatures in the UnauthenticatedAttributes of primary signer (index 0), instead of additional PKCS 7 signer.

    From the primary signature, search the UnauthenticatedAttribue for below:

    //Indicates the attribute is an octet encoded PKCS7

    define szOID_NESTED_SIGNATURE "1.3.6.1.4.1.311.2.4.1"

    The encoded object of this attribute is a full PKCS 7 signer.

    Thanks.

    0 讨论(0)
提交回复
热议问题