Sample code for 30+ languages & platforms
Delphi DLL

Validate Certificate using OCSP Protocol

See more Certificates Examples

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

Chilkat Delphi DLL Downloads

Delphi DLL
uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Prng, HttpResponse, JsonObject, Cert, Http, BinData;

...

procedure TForm1.Button1Click(Sender: TObject);
var
success: Boolean;
cert: HCkCert;
ocspUrl: PWideChar;
hashAlg: PWideChar;
prng: HCkPrng;
json: HCkJsonObject;
ocspRequest: HCkBinData;
http: HCkHttp;
resp: HCkHttpResponse;
ocspReply: HCkBinData;
jsonReply: HCkJsonObject;
ocspStatus: Integer;
certStatus: Integer;

begin
success := False;

// 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.
cert := CkCert_Create();
success := CkCert_LoadFromFile(cert,'qa_data/certs/google.crt');
if (success = False) then
  begin
    Memo1.Lines.Add(CkCert__lastErrorText(cert));
    Exit;
  end;

// Get the cert's OCSP URL.
ocspUrl := CkCert__ocspUrl(cert);

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

// Possible hash algorithms are sha1, sha256, sha384, sha512.  
hashAlg := 'sha256';
prng := CkPrng_Create();
json := CkJsonObject_Create();
CkJsonObject_putEmitCompact(json,False);
// Read more about OCSP nonce lengths
CkJsonObject_UpdateString(json,'extensions.ocspNonce',CkPrng__genRandom(prng,16,'base64'));
CkJsonObject_putI(json,0);
CkJsonObject_UpdateString(json,'request[i].cert.hashAlg',hashAlg);
CkJsonObject_UpdateString(json,'request[i].cert.issuerNameHash',CkCert__hashOf(cert,'IssuerDN',hashAlg,'base64'));
CkJsonObject_UpdateString(json,'request[i].cert.issuerKeyHash',CkCert__hashOf(cert,'IssuerPublicKey',hashAlg,'base64'));
CkJsonObject_UpdateString(json,'request[i].cert.serialNumber',CkCert__serialNumber(cert));

Memo1.Lines.Add(CkJsonObject__emit(json));

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

ocspRequest := CkBinData_Create();
http := CkHttp_Create();

// Convert our JSON to a binary (ASN.1) OCSP request
success := CkHttp_CreateOcspRequest(http,json,ocspRequest);
if (success = False) then
  begin
    Memo1.Lines.Add(CkHttp__lastErrorText(http));
    Exit;
  end;

// Send the OCSP request to the OCSP server
resp := CkHttpResponse_Create();
success := CkHttp_HttpBd(http,'POST',ocspUrl,ocspRequest,'application/ocsp-request',resp);
if (success = False) then
  begin
    Memo1.Lines.Add(CkHttp__lastErrorText(http));
    Exit;
  end;

// Get the binary (ASN.1) OCSP reply
ocspReply := CkBinData_Create();
CkHttpResponse_GetBodyBd(resp,ocspReply);

// Convert the binary reply to JSON.
// Also returns the overall OCSP response status.
jsonReply := CkJsonObject_Create();
ocspStatus := CkHttp_ParseOcspReply(http,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) then
  begin
    Memo1.Lines.Add('Invalid OCSP reply.');
    Exit;
  end;

Memo1.Lines.Add('Overall OCSP Response Status: ' + IntToStr(ocspStatus));

// Let's examine the OCSP response (in JSON).
CkJsonObject_putEmitCompact(jsonReply,False);
Memo1.Lines.Add(CkJsonObject__emit(jsonReply));

// 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:
certStatus := -1;
if (CkJsonObject_HasMember(jsonReply,'response.cert[0].status') = True) then
  begin
    certStatus := CkJsonObject_IntOf(jsonReply,'response.cert[0].status');
  end;

// Possible certStatus values are:
// -1: No status returned.
// 0: Good
// 1: Revoked
// 2: Unknown.
Memo1.Lines.Add('Certificate Status: ' + IntToStr(certStatus));

CkCert_Dispose(cert);
CkPrng_Dispose(prng);
CkJsonObject_Dispose(json);
CkBinData_Dispose(ocspRequest);
CkHttp_Dispose(http);
CkHttpResponse_Dispose(resp);
CkBinData_Dispose(ocspReply);
CkJsonObject_Dispose(jsonReply);

end;