Sample code for 30+ languages & platforms
SQL Server

Validate Certificate using OCSP Protocol

See more Certificates Examples

Demonstrates how to validate a certificate (check the revoked status) using the OCSP protocol.

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
    DECLARE @iTmp0 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 requires the Chilkat API to have been previously unlocked.
    -- See Global Unlock Sample for sample code.

    -- This example will check the revoked status of a certificate loaded from a file.
    DECLARE @cert int
    EXEC @hr = sp_OACreate 'Chilkat.Cert', @cert OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    EXEC sp_OAMethod @cert, 'LoadFromFile', @success OUT, 'qa_data/certs/google.crt'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @cert, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @cert
        RETURN
      END

    -- Get the cert's OCSP URL.
    DECLARE @ocspUrl nvarchar(4000)
    EXEC sp_OAGetProperty @cert, 'OcspUrl', @ocspUrl OUT

    -- Build the JSON that will be the OCSP request.

    -- Possible hash algorithms are sha1, sha256, sha384, sha512.  
    DECLARE @hashAlg nvarchar(4000)
    SELECT @hashAlg = 'sha256'
    DECLARE @prng int
    EXEC @hr = sp_OACreate 'Chilkat.Prng', @prng OUT

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

    EXEC sp_OASetProperty @json, 'EmitCompact', 0
    -- Read more about OCSP nonce lengths
    EXEC sp_OAMethod @prng, 'GenRandom', @sTmp0 OUT, 16, 'base64'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'extensions.ocspNonce', @sTmp0
    EXEC sp_OASetProperty @json, 'I', 0
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'request[i].cert.hashAlg', @hashAlg
    EXEC sp_OAMethod @cert, 'HashOf', @sTmp0 OUT, 'IssuerDN', @hashAlg, 'base64'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'request[i].cert.issuerNameHash', @sTmp0
    EXEC sp_OAMethod @cert, 'HashOf', @sTmp0 OUT, 'IssuerPublicKey', @hashAlg, 'base64'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'request[i].cert.issuerKeyHash', @sTmp0
    EXEC sp_OAGetProperty @cert, 'SerialNumber', @sTmp0 OUT
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'request[i].cert.serialNumber', @sTmp0

    EXEC sp_OAMethod @json, 'Emit', @sTmp0 OUT
    PRINT @sTmp0

    -- Our OCSP request looks something like this:
    -- {
    --   "extensions": {
    --     "ocspNonce": "qZDfbpO+nUxRzz6c/SPjE5QCAsPfpkQlRDxTnGl0gnxt7iXO"
    --   },
    --   "request": [
    --     {
    --       "cert": {
    --         "hashAlg": "sha1",
    --         "issuerNameHash": "9u2wY2IygZo19o11oJ0CShGqbK0=",
    --         "issuerKeyHash": "d8K4UJpndnaxLcKG0IOgfqZ+uks=",
    --         "serialNumber": "6175535D87BF94B6"
    --       }
    --     }
    --   ]
    -- }

    DECLARE @ocspRequest int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @ocspRequest OUT

    DECLARE @http int
    EXEC @hr = sp_OACreate 'Chilkat.Http', @http OUT

    -- Convert our JSON to a binary (ASN.1) OCSP request
    EXEC sp_OAMethod @http, 'CreateOcspRequest', @success OUT, @json, @ocspRequest
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @http, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @cert
        EXEC @hr = sp_OADestroy @prng
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @ocspRequest
        EXEC @hr = sp_OADestroy @http
        RETURN
      END

    -- Send the OCSP request to the OCSP server
    DECLARE @resp int
    EXEC @hr = sp_OACreate 'Chilkat.HttpResponse', @resp OUT

    EXEC sp_OAMethod @http, 'HttpBd', @success OUT, 'POST', @ocspUrl, @ocspRequest, 'application/ocsp-request', @resp
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @http, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @cert
        EXEC @hr = sp_OADestroy @prng
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @ocspRequest
        EXEC @hr = sp_OADestroy @http
        EXEC @hr = sp_OADestroy @resp
        RETURN
      END

    -- Get the binary (ASN.1) OCSP reply
    DECLARE @ocspReply int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @ocspReply OUT

    EXEC sp_OAMethod @resp, 'GetBodyBd', @success OUT, @ocspReply

    -- Convert the binary reply to JSON.
    -- Also returns the overall OCSP response status.
    DECLARE @jsonReply int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @jsonReply OUT

    DECLARE @ocspStatus int
    EXEC sp_OAMethod @http, 'ParseOcspReply', @ocspStatus OUT, @ocspReply, @jsonReply

    -- The ocspStatus can have one of these values:
    -- -1:  The ARG1 does not contain a valid OCSP reply.
    -- 0:  Successful - Response has valid confirmations..
    -- 1: Malformed request - Illegal confirmation request.
    -- 2: Internal error - Internal error in issuer.
    -- 3: Try later -  Try again later.
    -- 4: Not used - This value is never returned.
    -- 5: Sig required - Must sign the request.
    -- 6: Unauthorized - Request unauthorized.

    IF @ocspStatus < 0
      BEGIN

        PRINT 'Invalid OCSP reply.'
        EXEC @hr = sp_OADestroy @cert
        EXEC @hr = sp_OADestroy @prng
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @ocspRequest
        EXEC @hr = sp_OADestroy @http
        EXEC @hr = sp_OADestroy @resp
        EXEC @hr = sp_OADestroy @ocspReply
        EXEC @hr = sp_OADestroy @jsonReply
        RETURN
      END


    PRINT 'Overall OCSP Response Status: ' + @ocspStatus

    -- Let's examine the OCSP response (in JSON).
    EXEC sp_OASetProperty @jsonReply, 'EmitCompact', 0
    EXEC sp_OAMethod @jsonReply, 'Emit', @sTmp0 OUT
    PRINT @sTmp0

    -- The JSON reply looks like this:
    -- (Use the online tool at https://tools.chilkat.io/jsonParse.cshtml
    -- to generate JSON parsing code.)

    -- {
    --   "responseStatus": 0,
    --   "responseTypeOid": "1.3.6.1.5.5.7.48.1.1",
    --   "responseTypeName": "ocspBasic",
    --   "response": {
    --     "responderIdChoice": "KeyHash",
    --     "responderKeyHash": "d8K4UJpndnaxLcKG0IOgfqZ+uks=",
    --     "dateTime": "20180803193937Z",
    --     "cert": [
    --       {
    --         "hashOid": "1.3.14.3.2.26",
    --         "hashAlg": "SHA-1",
    --         "issuerNameHash": "9u2wY2IygZo19o11oJ0CShGqbK0=",
    --         "issuerKeyHash": "d8K4UJpndnaxLcKG0IOgfqZ+uks=",
    --         "serialNumber": "6175535D87BF94B6",
    --         "status": 0,
    --         "thisUpdate": "20180803193937Z",
    --         "nextUpdate": "20180810193937Z"
    --       }
    --     ]
    --   }
    -- }
    -- 

    -- The certificate status:
    DECLARE @certStatus int
    SELECT @certStatus = -1
    EXEC sp_OAMethod @jsonReply, 'HasMember', @iTmp0 OUT, 'response.cert[0].status'
    IF @iTmp0 = 1
      BEGIN
        EXEC sp_OAMethod @jsonReply, 'IntOf', @certStatus OUT, 'response.cert[0].status'
      END

    -- Possible certStatus values are:
    -- -1: No status returned.
    -- 0: Good
    -- 1: Revoked
    -- 2: Unknown.

    PRINT 'Certificate Status: ' + @certStatus

    EXEC @hr = sp_OADestroy @cert
    EXEC @hr = sp_OADestroy @prng
    EXEC @hr = sp_OADestroy @json
    EXEC @hr = sp_OADestroy @ocspRequest
    EXEC @hr = sp_OADestroy @http
    EXEC @hr = sp_OADestroy @resp
    EXEC @hr = sp_OADestroy @ocspReply
    EXEC @hr = sp_OADestroy @jsonReply


END
GO