OCV Services

Introduction

OCV stands for 'Open Certificate validation'. For business applications relying on PKIs the process of trusting digital certificates is complex. It requires the ability to locate certificates from online resources in order to construct a valid certificate path to one or more trust anchors. Once a certificate path is successfully constructed it then needs to be subjected to a multi-step validation process, where many fields and extensions inside each certificate in the path are reviewed and validated according to a complex set of PKI rules. The OCV Server provides all of the above functionality in a centralized manner. This allows business applications to delegate all of the responsibility for certificate path discovery and validation. This greatly simplifies development of business applications that rely on PKIs, by hiding all the inherent complexity. The OCV takes part in the context defined by EFVS SC14 (Refernece model for eSignature Validation), following image is setting the context for OCV:

This chapter has been provided in order to understand the functionality provided by the OCV client available in T1C-JS

(

after activating the api-key for the OCV API

)

.

Functional Scope

  • complies with IETF RFC 5055 and RFC 3379 for delegated path discovery (DPD) and delegated path validation (DPV) of digital certificates

  • Supports dynamic Delegated Path Discovery (DPD) even in complex bridge CA, mesh and cross-certification PKI topologies

  • Supports full certificate validation using RFC 5280 and RFC 3379 validation algorithm, including validation of Key Usage, Extended Key Usage, Certificate Policies, Name validation, policy mapping and other related checks

  • Supports revocation checking using advanced OCSP and CRL handling

  • Provides ability to create multiple validation profiles each with their own final trust anchors, path building and validation settings

  • Support historical certificate validation service

  • High-performance architecture including caching of intermediate CA certificates and revocation info

  • Strong security using the latest crypto-algorithms

    Architecture - Component Overview

    The following component diagram denotes a global overview of the OCV (Open Certificate Validation API) building blocks.

The solution exposes and uses for several use cases an

CRL

and

OCSP

service layer.

The OCSP Layer consists of the following components:

  • Offline and online OCSP source

  • Signature OCSP source

  • CAdES, PAdES and XAdES source

The CRL layer consist of the following components:

  • Offline and online CRL source

  • JDBC source

  • Signature OCSP source

  • CAdES, PAdES and XAdES source

Client Integration

Supported Use Cases

The list of supported use cases will grown with upcoming releases, the T1C-JS supports:

  • Request server generated challenge for authentication purpose

  • Verify Signed Challenge for authentication purpose

  • Validate Certificate Chain (OCSP and CRL check)

Interface

    getChallenge(digestAlgorithm,callback:(error:CoreExceptions.RestException, data:any) => void):void;
    validateChallengeSignedHash(data:any,callback:(error:CoreExceptions.RestException, data:any) => void):void;
    validateCertificateChain(data:any,callback:(error:CoreExceptions.RestException, data:any) => void):void;

API Activation

In order to active the OCV API, the api-key should be contracted with the OCV API. To do so, you can contact: admin.be@trust1team.com or use the customer portal to request an api-key. Upon configuration of the T1C-JS, an additional url should be provided:

  var gclConfig = new GCLLib.GCLConfig();
  gclConfig.apiKey = "<some-api-key>";
  gclConfig.dsUrl = "https://accapim.t1t.be:443";
  gclConfig.ocvUrl = "https://accapim.t1t.be:443/trust1team/ocv-api/v1";
  GCLLib.CGCLClient.initialize(gclConfig, function(err, connector) { ... });

This configures the OCV URL for the T1C-JS instance used in your web application. Note that the api-key must be enabled in order to do so (the service will respond with an 'unauthenticated' response).

Examples

OCV Client Instance

In order to obtain an OCV client instance, you can call the following function:

GCLLib.CGCLClient.initialize(gclConfig, function(err, connector) { 
    var ocvClient = connector.ocv();
});

Validate Certificate Chain (OCSP and CRL check)

The certificates received can be validated against the CA (Certificate Authority). In order to do so, the T1C-JS uses the OCV API to perform:

  • validation of certificate expiration

  • validation of the certificate chain

  • OCSP validation of the certificate chain

  • CRL validation of the certificate chain

The following function can be called in order to perform the aforementioned validation:

    var ocvClient = connector.ocv();
    ocvClient.validateCertificateChain(_body,callback)

The body must be JSON and of the form:

{
  "certificateChain": [
    {
      "order": 0,
      "certificate": "string"
    }
  ]
}

The certificate order is of great importance; the order is 0-based, and the first certificate should be a leaf certificate, followed by one or more intermediates and ending with the root-certificate.

As an example; you can see how this works for Belgian eID on Belgian eID Plugin

We first retrieve the following certificates: root, citizen and authentication certificates:

  connector.beid(reader_id).allCerts(certFilter,function(err,certdata){...}

We receive the following response:

{
  "data": {
    "authentication_certificate": "MIIFhzCCA2+gAw...AA==",
    "citizen_certificate": "MIIF3jCCA8agA...AA=",
    "root_certificate": "MIIFjjCCA3a...4xg=="
  },
  "success": true
}

Now we can create the body in order to call the certificate validation function:

    connector.beid(reader_id).allCerts(certFilter,function(err,certdata){
        var authCert = {};
        authCert.order=0;
        authCert.certificate = certdata.data.authentication_certificate;
        var intermediateCert = {};
        intermediateCert.order=1;
        intermediateCert.certificate = certdata.data.citizen_certificate;
        var rootCert = {};
        rootCert.order=2;
        rootCert.certificate = certdata.data.root_certificate;
        var _body = {};
        var certificates = [];
        certificates.push(authCert);
        certificates.push(intermediateCert);
        certificates.push(rootCert);
        _body.certificateChain = certificates;
        connector.ocv().validateCertificateChain(_body,callback);
    });

The certificate validation response will contain the validation info for OCSP and CRL; the status must be true:

{
  "ocspResponse": {
    "status": true,
    "ocspLocation": "http://ocsp.eid.belgium.be/2"
  },
  "crlResponse": {
    "version": "2",
    "signatureAlgorithm": "RSA_SHA1",
    "status": true,
    "issuerCertificate": "C=BE,CN=Citizen CA,SERIALNUMBER=201603",
    "crlLocations": [
      "http://crl.eid.belgium.be/eidc201603.crl"
    ],
    "productionDate": "Tue Nov 29 15:51:08 UTC 2016"
  }
}

Authenticate with back-end generated Challenge

The OCV API exposes endpoints to generate a random challenge, and to validate the signed challenge hash. The following digest algorithms are supported:

  • MD5

  • SHA1

  • SHA256

  • SHA512

The following flow has been implemented in order to authenticate a user with a smart card. The code example denotes how to use the T1C-JS to do so in 3 steps:

  • generate challenge

  • sign challenge hash

  • validate signed challenge hash

Get Authentication Challenge

First we need to retrieve a challenge hash form the OCV API:

  var ocv = connector.ocv();
  ocv.getChallenge('SHA256',callback);

An example response:

{
  "hash": "ZMUv04O9A/NzNetkuwVY+9bbYlyBYvtCyDSka4dwaQ0=",
  "digestAlgorithm": "SHA256"
}

Sign Challenge Hash

The hash returned should be send to the T1C-GCL (local instance communicating with eID card in the smart card reader). When the user doesn't have a pin-pad reader, the pin dialog must be shown from the custom UI page in order to capture the pi (in order to prevent MIT attack the communication with T1C-GCL is always over https).

    var _body={};
    _body.data = <received_hash>;
    _body.algorithm_reference = "sha256"; //or MD5, SHA1, SHA512
    _body.pin = <entered_pin>; //when pin-pad -> this prorperty is omitted
    connector.beid(<reader_id>).authenticate(_body, callback);

An example response:

{
  "data": "CRAvepi1...o1j8ng==",
  "success": true
}

The data property is the signature of the challenge hash received from the OCV API.

Verify Authentication Challenge Signature

As a last step we need to verify the signature received in the previous step. We can do this using an OCV validation endpoint.

  var _req = {};
  _req.hash = <original_challenge_hash>; //received in first step
  _req.digestAlgorithm = <digest_algorithm>; //MD5,SHA1,...
  _req.base64Signature = <signature>; //received from previous call
  _req.base64Certificate = <authentication_certificate>; //for example Belgian eID auth certificate
  connector.ocv().validateChallengeSignedHash(_req,callback);

An example response:

{
  "hash": "8l90BxqllVYpp+x+aj8VsDTW0JcPL+JALqDrjGSnTgo=",
  "digestAlgorithm": "SHA256",
  "result": true
}

When the restul is 'true', the user has been authenticated correctly using a server generated challenge.

Last updated