Sample code for 30+ languages & platforms
SQL Server

Validate PDF Signatures

See more PDF Signatures Examples

This example demonstrates how to validate the signatures in a PDF and also shows how to get information from each signature.

Note: This example requires Chilkat v9.5.0.85 or greater.

Chilkat SQL Server Downloads

SQL Server
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    -- Important: Do not use nvarchar(max).  See the warning about using nvarchar(max).
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 0

    -- This example requires the Chilkat API to have been previously unlocked.
    -- See Global Unlock Sample for sample code.

    DECLARE @pdf int
    EXEC @hr = sp_OACreate 'Chilkat.Pdf', @pdf OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    -- Load a PDF that has cryptographic signatures to be validated
    EXEC sp_OAMethod @pdf, 'LoadFile', @success OUT, 'qa_data/pdf/sign_testing_1/helloSigned2.pdf'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @pdf
        RETURN
      END

    -- Each time we verify a signature, information about the signature is written into
    -- sigInfo (replacing whatever sigInfo previously contained).
    DECLARE @sigInfo int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @sigInfo OUT

    EXEC sp_OASetProperty @sigInfo, 'EmitCompact', 0

    -- Iterate over each signature and validate each.
    DECLARE @numSignatures int
    EXEC sp_OAGetProperty @pdf, 'NumSignatures', @numSignatures OUT
    DECLARE @validated int
    SELECT @validated = 0
    DECLARE @i int
    SELECT @i = 0
    WHILE @i < @numSignatures
      BEGIN
        EXEC sp_OAMethod @pdf, 'VerifySignature', @validated OUT, @i, @sigInfo


        PRINT 'Signature ' + @i + ' validated: ' + @validated
        EXEC sp_OAMethod @sigInfo, 'Emit', @sTmp0 OUT
        PRINT @sTmp0
        SELECT @i = @i + 1
      END


    PRINT 'Finished.'

    -- When VerifySignature validates a signature, a lot of information is deposited into the JSON sigInfo object.
    -- The information can vary depending on what was included in the signature (for example, various authenticated attributes
    -- and unauthenticated attributes may or may not be included).
    -- Here is a sample of the information you'll see.
    -- 
    -- The following online tool can be used to generate code to parse any given JSON.
    -- Generate Parsing Code from JSON

    -- {
    --   "validated": true,
    --   "signatureDictionary": {         <--- This is the contents of the PDF Signature Dictionary for this signature.
    --     "/ByteRange": [
    --       0,
    --       154682,
    --       170512,
    --       3233
    --     ],
    --     "/Contents": "<hex_data>",
    --     "/Filter": "/Adobe.PPKLite",        <--- The meaning of the Signature Dictionary entries are defined in the PDF format specification document.
    --     "/M": "D:20201006110216-05'00'",
    --     "/Name": "yubikey rsa 1024 authentication",
    --     "/Prop_Build": {
    --       "/App": {
    --         "/Name": "/Adobe#20Acrobat#20Pro#20DC",
    --         "/OS": [
    --           "/Win"
    --         ],
    --         "/R": 1313792,
    --         "/REx": "2020.012.20048",
    --         "/TrustedMode": true
    --       },
    --       "/Filter": {
    --         "/Date": "Sep 11 2020 16:30:54",
    --         "/Name": "/Adobe.PPKLite",
    --         "/R": 131104,
    --         "/V": 2
    --       },
    --       "/PubSec": {
    --         "/Date": "Sep 11 2020 16:30:54",
    --         "/NonEFontNoWarn": true,
    --         "/R": 131105
    --       }
    --     },
    --     "/SubFilter": "/adbe.pkcs7.detached",
    --     "/Type": "/Sig"
    --   },
    --   "pkcs7": {          <--- This is the content of the CMS signature.
    --     "verify": {
    --       "certs": [      <--- Each signing certificate is listed here (by issuer common name and signing cert's serail number (in hex))
    --         {
    --           "issuerCN": "yubikey rsa 1024 authentication",
    --           "serial": "66BE58138D761E92BC594A722932657BE26D421F"
    --         }
    --       ],
    --       "digestAlgorithms": [
    --         "sha256"
    --       ],
    --       "signerInfo": [     <--- contains data from each SignerInfo
    --         {
    --           "cert": {
    --             "serialNumber": "66BE58138D761E92BC594A722932657BE26D421F",
    --             "issuerCN": "yubikey rsa 1024 authentication",
    --             "digestAlgOid": "2.16.840.1.101.3.4.2.1",
    --             "digestAlgName": "SHA256"
    --           },
    --           "contentType": "1.2.840.113549.1.7.1",
    --           "messageDigest": "btQOuSEvC31mdRFHtyEUPw8R9NuKfk0XPcQ6Lcmn6pk=",
    --           "signingAlgOid": "1.2.840.113549.1.1.11",
    --           "signingAlgName": "RSA-SHA256-PKCSV-1_5",
    --           "authAttr": {     <--- CMS authenticated attributes are contained here.
    --             "1.2.840.113583.1.1.8": {
    --               "der": "MAA="
    --             },
    --             "1.2.840.113549.1.9.3": {
    --               "name": "contentType",
    --               "oid": "1.2.840.113549.1.7.1"
    --             },
    --             "1.2.840.113549.1.9.4": {
    --               "name": "messageDigest",
    --               "digest": "btQOuSEvC31mdRFHtyEUPw8R9NuKfk0XPcQ6Lcmn6pk="
    --             }
    --           },
    --           "unauthAttr": {    <--- CMS unauthenticated attributes are contained here.
    --             "1.2.840.113549.1.9.16.2.14": {
    --               "name": "timestampToken",
    --               "der": "MIIOvAYJKo ... Es/70g=",
    --               "verify": {
    --                 "digestAlgorithms": [
    --                   "sha256"
    --                 ],
    --                 "signerInfo": [
    --                   {
    --                     "cert": {
    --                       "serialNumber": "04CD3F8568AE76C61BB0FE7160CCA76D",
    --                       "issuerCN": "DigiCert SHA2 Assured ID Timestamping CA",
    --                       "digestAlgOid": "2.16.840.1.101.3.4.2.1",
    --                       "digestAlgName": "SHA256"
    --                     },
    --                     "contentType": "1.2.840.113549.1.9.16.1.4",
    --                     "signingTime": "201006160423Z",
    --                     "messageDigest": "Atv5Rj3kidB8IR6CplYiX3o6De/k8SC6JJ6uUPAGO0g=",
    --                     "signingAlgOid": "1.2.840.113549.1.1.1",
    --                     "signingAlgName": "RSA-PKCSV-1_5",
    --                     "authAttr": {
    --                       "1.2.840.113549.1.9.3": {
    --                         "name": "contentType",
    --                         "oid": "1.2.840.113549.1.9.16.1.4"
    --                       },
    --                       "1.2.840.113549.1.9.5": {
    --                         "name": "signingTime",
    --                         "utctime": "201006160423Z"
    --                       },
    --                       "1.2.840.113549.1.9.16.2.12": {
    --                         "name": "signingCertificate",
    --                         "der": "MBowGDAWBBQDJb1QXtqWMC3CL0+gHkwovig0xQ=="
    --                       },
    --                       "1.2.840.113549.1.9.4": {
    --                         "name": "messageDigest",
    --                         "digest": "Atv5Rj3kidB8IR6CplYiX3o6De/k8SC6JJ6uUPAGO0g="
    --                       }
    --                     }
    --                   }
    --                 ]
    --               },
    --               "timestampSignatureVerified": true,
    --               "tstInfo": {
    --                 "tsaPolicyId": "2.16.840.1.114412.7.1",
    --                 "messageImprint": {
    --                   "hashAlg": "sha256",
    --                   "digest": "gLJtrRWUSDfjzDkF1MfWG1wyHA6FrUJLkWMGRG+eMlA=",
    --                   "digestMatches": true
    --                 },
    --                 "serialNumber": "00CE57E1113970607EF63B1D1160545321",
    --                 "genTime": "20201006160423Z"
    --               }
    --             }
    --           }
    --         }
    --       ],
    --       "pkcs7": {
    --         "verify": {
    --           "certs": [
    --             {
    --               "issuerCN": "DigiCert SHA2 Assured ID Timestamping CA",
    --               "serial": "04CD3F8568AE76C61BB0FE7160CCA76D"
    --             },
    --             {
    --               "issuerCN": "DigiCert Assured ID Root CA",
    --               "serial": "0AA125D6D6321B7E41E405DA3697C215"
    --             }
    --           ]
    --         }
    --       }
    --     }
    --   }
    -- }

    -- **** The point of this code is to show how to get at each desired piece of information contained in the signature.
    -- **** If your signature contains additional information not shown here, then you can use the online tool to generate the parse code.
    -- **** It is likely you're only interested in a few items of information, and therefore you wouldn't copy all of this code, but might
    -- **** choose to use bits and pieces to get the information you find important.

    DECLARE @json int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @json OUT

    -- Imagine that the "json" object contains the information obtained by validating a signature...
    -- The code below was generated using the online tool:  Generate Parsing Code from JSON

    DECLARE @unauthAttrTimestampTokenTstInfoGenTime int
    EXEC @hr = sp_OACreate 'Chilkat.DtObj', @unauthAttrTimestampTokenTstInfoGenTime OUT

    DECLARE @signingTime int
    EXEC @hr = sp_OACreate 'Chilkat.DtObj', @signingTime OUT

    DECLARE @authAttrSigningTimeUtctime int
    EXEC @hr = sp_OACreate 'Chilkat.DtObj', @authAttrSigningTimeUtctime OUT

    DECLARE @intVal int

    DECLARE @strVal nvarchar(4000)

    DECLARE @issuerCN nvarchar(4000)

    DECLARE @serial nvarchar(4000)

    DECLARE @certSerialNumber nvarchar(4000)

    DECLARE @certIssuerCN nvarchar(4000)

    DECLARE @certDigestAlgOid nvarchar(4000)

    DECLARE @certDigestAlgName nvarchar(4000)

    DECLARE @contentType nvarchar(4000)

    DECLARE @messageDigest nvarchar(4000)

    DECLARE @signingAlgOid nvarchar(4000)

    DECLARE @signingAlgName nvarchar(4000)

    DECLARE @authAttr1_2_840_113583_1_1_8Der nvarchar(4000)

    DECLARE @authAttrContentTypeName nvarchar(4000)

    DECLARE @authAttrContentTypeOid nvarchar(4000)

    DECLARE @authAttrMessageDigestName nvarchar(4000)

    DECLARE @authAttrMessageDigestDigest nvarchar(4000)

    DECLARE @unauthAttrTimestampTokenName nvarchar(4000)

    DECLARE @unauthAttrTimestampTokenDer nvarchar(4000)

    DECLARE @unauthAttrTimestampTokenTimestampSignatureVerified int

    DECLARE @unauthAttrTimestampTokenTstInfoTsaPolicyId nvarchar(4000)

    DECLARE @unauthAttrTimestampTokenTstInfoMessageImprintHashAlg nvarchar(4000)

    DECLARE @unauthAttrTimestampTokenTstInfoMessageImprintDigest nvarchar(4000)

    DECLARE @unauthAttrTimestampTokenTstInfoMessageImprintDigestMatches int

    DECLARE @unauthAttrTimestampTokenTstInfoSerialNumber nvarchar(4000)

    DECLARE @j int

    DECLARE @count_j int

    DECLARE @authAttrSigningTimeName nvarchar(4000)

    DECLARE @authAttrSigningCertificateName nvarchar(4000)

    DECLARE @authAttrSigningCertificateDer nvarchar(4000)

    EXEC sp_OAMethod @json, 'BoolOf', @validated OUT, 'validated'
    DECLARE @signatureDictionary_Contents nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Contents OUT, 'signatureDictionary./Contents'
    DECLARE @signatureDictionary_Filter nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Filter OUT, 'signatureDictionary./Filter'
    DECLARE @signatureDictionary_M nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_M OUT, 'signatureDictionary./M'
    DECLARE @signatureDictionary_Name nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Name OUT, 'signatureDictionary./Name'
    DECLARE @signatureDictionary_Prop_Build_App_Name nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Prop_Build_App_Name OUT, 'signatureDictionary./Prop_Build./App./Name'
    DECLARE @signatureDictionary_Prop_Build_App_R int
    EXEC sp_OAMethod @json, 'IntOf', @signatureDictionary_Prop_Build_App_R OUT, 'signatureDictionary./Prop_Build./App./R'
    DECLARE @signatureDictionary_Prop_Build_App_REx nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Prop_Build_App_REx OUT, 'signatureDictionary./Prop_Build./App./REx'
    DECLARE @signatureDictionary_Prop_Build_App_TrustedMode int
    EXEC sp_OAMethod @json, 'BoolOf', @signatureDictionary_Prop_Build_App_TrustedMode OUT, 'signatureDictionary./Prop_Build./App./TrustedMode'
    DECLARE @signatureDictionary_Prop_Build_Filter_Date nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Prop_Build_Filter_Date OUT, 'signatureDictionary./Prop_Build./Filter./Date'
    DECLARE @signatureDictionary_Prop_Build_Filter_Name nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Prop_Build_Filter_Name OUT, 'signatureDictionary./Prop_Build./Filter./Name'
    DECLARE @signatureDictionary_Prop_Build_Filter_R int
    EXEC sp_OAMethod @json, 'IntOf', @signatureDictionary_Prop_Build_Filter_R OUT, 'signatureDictionary./Prop_Build./Filter./R'
    DECLARE @signatureDictionary_Prop_Build_Filter_V int
    EXEC sp_OAMethod @json, 'IntOf', @signatureDictionary_Prop_Build_Filter_V OUT, 'signatureDictionary./Prop_Build./Filter./V'
    DECLARE @signatureDictionary_Prop_Build_PubSec_Date nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Prop_Build_PubSec_Date OUT, 'signatureDictionary./Prop_Build./PubSec./Date'
    DECLARE @signatureDictionary_Prop_Build_PubSec_NonEFontNoWarn int
    EXEC sp_OAMethod @json, 'BoolOf', @signatureDictionary_Prop_Build_PubSec_NonEFontNoWarn OUT, 'signatureDictionary./Prop_Build./PubSec./NonEFontNoWarn'
    DECLARE @signatureDictionary_Prop_Build_PubSec_R int
    EXEC sp_OAMethod @json, 'IntOf', @signatureDictionary_Prop_Build_PubSec_R OUT, 'signatureDictionary./Prop_Build./PubSec./R'
    DECLARE @signatureDictionary_SubFilter nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_SubFilter OUT, 'signatureDictionary./SubFilter'
    DECLARE @signatureDictionary_Type nvarchar(4000)
    EXEC sp_OAMethod @json, 'StringOf', @signatureDictionary_Type OUT, 'signatureDictionary./Type'
    SELECT @i = 0
    DECLARE @count_i int
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'signatureDictionary./ByteRange'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'IntOf', @intVal OUT, 'signatureDictionary./ByteRange[i]'
        SELECT @i = @i + 1
      END
    SELECT @i = 0
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'signatureDictionary./Prop_Build./App./OS'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'StringOf', @strVal OUT, 'signatureDictionary./Prop_Build./App./OS[i]'
        SELECT @i = @i + 1
      END
    SELECT @i = 0
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'pkcs7.verify.certs'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'StringOf', @issuerCN OUT, 'pkcs7.verify.certs[i].issuerCN'
        EXEC sp_OAMethod @json, 'StringOf', @serial OUT, 'pkcs7.verify.certs[i].serial'
        SELECT @i = @i + 1
      END
    SELECT @i = 0
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'pkcs7.verify.digestAlgorithms'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'StringOf', @strVal OUT, 'pkcs7.verify.digestAlgorithms[i]'
        SELECT @i = @i + 1
      END
    SELECT @i = 0
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'pkcs7.verify.signerInfo'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'StringOf', @certSerialNumber OUT, 'pkcs7.verify.signerInfo[i].cert.serialNumber'
        EXEC sp_OAMethod @json, 'StringOf', @certIssuerCN OUT, 'pkcs7.verify.signerInfo[i].cert.issuerCN'
        EXEC sp_OAMethod @json, 'StringOf', @certDigestAlgOid OUT, 'pkcs7.verify.signerInfo[i].cert.digestAlgOid'
        EXEC sp_OAMethod @json, 'StringOf', @certDigestAlgName OUT, 'pkcs7.verify.signerInfo[i].cert.digestAlgName'
        EXEC sp_OAMethod @json, 'StringOf', @contentType OUT, 'pkcs7.verify.signerInfo[i].contentType'
        EXEC sp_OAMethod @json, 'StringOf', @messageDigest OUT, 'pkcs7.verify.signerInfo[i].messageDigest'
        EXEC sp_OAMethod @json, 'StringOf', @signingAlgOid OUT, 'pkcs7.verify.signerInfo[i].signingAlgOid'
        EXEC sp_OAMethod @json, 'StringOf', @signingAlgName OUT, 'pkcs7.verify.signerInfo[i].signingAlgName'
        EXEC sp_OAMethod @json, 'StringOf', @authAttr1_2_840_113583_1_1_8Der OUT, 'pkcs7.verify.signerInfo[i].authAttr."1.2.840.113583.1.1.8".der'
        EXEC sp_OAMethod @json, 'StringOf', @authAttrContentTypeName OUT, 'pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.3".name'
        EXEC sp_OAMethod @json, 'StringOf', @authAttrContentTypeOid OUT, 'pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.3".oid'
        EXEC sp_OAMethod @json, 'StringOf', @authAttrMessageDigestName OUT, 'pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.4".name'
        EXEC sp_OAMethod @json, 'StringOf', @authAttrMessageDigestDigest OUT, 'pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.4".digest'
        EXEC sp_OAMethod @json, 'StringOf', @unauthAttrTimestampTokenName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".name'
        EXEC sp_OAMethod @json, 'StringOf', @unauthAttrTimestampTokenDer OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".der'
        EXEC sp_OAMethod @json, 'BoolOf', @unauthAttrTimestampTokenTimestampSignatureVerified OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".timestampSignatureVerified'
        EXEC sp_OAMethod @json, 'StringOf', @unauthAttrTimestampTokenTstInfoTsaPolicyId OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".tstInfo.tsaPolicyId'
        EXEC sp_OAMethod @json, 'StringOf', @unauthAttrTimestampTokenTstInfoMessageImprintHashAlg OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".tstInfo.messageImprint.hashAlg'
        EXEC sp_OAMethod @json, 'StringOf', @unauthAttrTimestampTokenTstInfoMessageImprintDigest OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".tstInfo.messageImprint.digest'
        EXEC sp_OAMethod @json, 'BoolOf', @unauthAttrTimestampTokenTstInfoMessageImprintDigestMatches OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".tstInfo.messageImprint.digestMatches'
        EXEC sp_OAMethod @json, 'StringOf', @unauthAttrTimestampTokenTstInfoSerialNumber OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".tstInfo.serialNumber'
        EXEC sp_OAMethod @json, 'DtOf', @success OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".tstInfo.genTime', 0, @unauthAttrTimestampTokenTstInfoGenTime
        SELECT @j = 0
        EXEC sp_OAMethod @json, 'SizeOfArray', @count_j OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.digestAlgorithms'
        WHILE @j < @count_j
          BEGIN
            EXEC sp_OASetProperty @json, 'J', @j
            EXEC sp_OAMethod @json, 'StringOf', @strVal OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.digestAlgorithms[j]'
            SELECT @j = @j + 1
          END
        SELECT @j = 0
        EXEC sp_OAMethod @json, 'SizeOfArray', @count_j OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo'
        WHILE @j < @count_j
          BEGIN
            EXEC sp_OASetProperty @json, 'J', @j
            EXEC sp_OAMethod @json, 'StringOf', @certSerialNumber OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].cert.serialNumber'
            EXEC sp_OAMethod @json, 'StringOf', @certIssuerCN OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].cert.issuerCN'
            EXEC sp_OAMethod @json, 'StringOf', @certDigestAlgOid OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].cert.digestAlgOid'
            EXEC sp_OAMethod @json, 'StringOf', @certDigestAlgName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].cert.digestAlgName'
            EXEC sp_OAMethod @json, 'StringOf', @contentType OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].contentType'
            EXEC sp_OAMethod @json, 'DtOf', @success OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].signingTime', 0, @signingTime
            EXEC sp_OAMethod @json, 'StringOf', @messageDigest OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].messageDigest'
            EXEC sp_OAMethod @json, 'StringOf', @signingAlgOid OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].signingAlgOid'
            EXEC sp_OAMethod @json, 'StringOf', @signingAlgName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].signingAlgName'
            EXEC sp_OAMethod @json, 'StringOf', @authAttrContentTypeName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.3".name'
            EXEC sp_OAMethod @json, 'StringOf', @authAttrContentTypeOid OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.3".oid'
            EXEC sp_OAMethod @json, 'StringOf', @authAttrSigningTimeName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.5".name'
            EXEC sp_OAMethod @json, 'DtOf', @success OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.5".utctime', 0, @authAttrSigningTimeUtctime
            EXEC sp_OAMethod @json, 'StringOf', @authAttrSigningCertificateName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.16.2.12".name'
            EXEC sp_OAMethod @json, 'StringOf', @authAttrSigningCertificateDer OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.16.2.12".der'
            EXEC sp_OAMethod @json, 'StringOf', @authAttrMessageDigestName OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.4".name'
            EXEC sp_OAMethod @json, 'StringOf', @authAttrMessageDigestDigest OUT, 'pkcs7.verify.signerInfo[i].unauthAttr."1.2.840.113549.1.9.16.2.14".verify.signerInfo[j].authAttr."1.2.840.113549.1.9.4".digest'
            SELECT @j = @j + 1
          END
        SELECT @i = @i + 1
      END
    SELECT @i = 0
    EXEC sp_OAMethod @json, 'SizeOfArray', @count_i OUT, 'pkcs7.verify.pkcs7.verify.certs'
    WHILE @i < @count_i
      BEGIN
        EXEC sp_OASetProperty @json, 'I', @i
        EXEC sp_OAMethod @json, 'StringOf', @issuerCN OUT, 'pkcs7.verify.pkcs7.verify.certs[i].issuerCN'
        EXEC sp_OAMethod @json, 'StringOf', @serial OUT, 'pkcs7.verify.pkcs7.verify.certs[i].serial'
        SELECT @i = @i + 1
      END

    EXEC @hr = sp_OADestroy @pdf
    EXEC @hr = sp_OADestroy @sigInfo
    EXEC @hr = sp_OADestroy @json
    EXEC @hr = sp_OADestroy @unauthAttrTimestampTokenTstInfoGenTime
    EXEC @hr = sp_OADestroy @signingTime
    EXEC @hr = sp_OADestroy @authAttrSigningTimeUtctime


END
GO