Skip to content
typelogic edited this page Aug 12, 2020 · 45 revisions

Introduction

This library and in combination with some higher-level languages such as Python or Java is used to create and issue a cryptographically secure and biometrically binding QR code identity cards. The generated QR code ID is binded to its owner via face recognition. Therefore, if another person carries and swipes this QR code ID, it will not verify. The QR code contents are cryptographically protected and digitally signed.

The shared library libidpasslite.so or idpasslite.dll is a monolithic amalgamation of various existing opensource components. It is intentionally crafted to be singular and as much as possible self-contained. In general terms, the library is a fusion of two functions:

  • face recognition function
  • cryptography function

In cases of further requirements and integrations wherein the library shall rely on other dynamic libraries or remote procedure calls in the execution of its functions at runtime, then these composite artifacts shall be cryptographically binded for integrity and versioned.

The libidpasslite.so library shall be digitally signed to trace it back to the sources version it was built from and to form a linguistic bind to higher programming languages. For example,

strings libidpasslite.so | grep DXTRACKER
DXTRACKER 8b3fb1d1788ad52eb25a3d69f54f7877f5ef708e

points to the repository's commit hash from which the library was built. The DX prefix was from Android where this library initially started.

Initialize the library

The API's design uses Google's protocol buffer serialization format version 3.12.3. For example, in the snippet below shows a C++ client side caller where an api::KeySet structure or object is created, initialized, serialized and de-serialized. These protobuf serialization/de-serialization pattern occurs in some API calls to supply the function parameter or from the function's return values.

#include "idpass.h"
#include "proto/api/api.pb.h"

void initialize_snippet() 
{
    unsigned char signaturekey[64];
    unsigned char encryptionkey[32];

    idpass_lite_generate_secret_signature_key(signaturekey, 64);
    idpass_lite_generate_encryption_key(encryptionkey, 32);

    // create api::KeySet object
    api::KeySet keyset;
 
    // initialize object member fields
    keyset.set_encryptionkey(encryptionkey, 32);
    keyset.set_signaturekey(signaturekey, 64);

    // serialize object into byte array 
    std::vector<unsigned char> keysetbuf(keyset.ByteSizeLong());
    keyset.SerializeToArray(keysetbuf.data(), keysetbuf.size());

    // call the library's main initialization API
    void* context = idpass_lite_init(keysetbuf.data(), keysetbuf.size(), nullptr, 0);
}

The deserialization part is not shown in the above snippet as it happens inside the idpass_lite_init function. The de-serialization part shall re-construct the exact api::KeySet object instance within the library.

The idpass.h header file exposes a C API. However, the internal implementation uses C++ due to the following:

  • Google's protocol buffers is natively in C++
  • Dlib is purely in C++

Create an IDPASSLITE ID for a new user

After initializing the library, the snippet below shows how to setup the identity details for a user, call an API to create an IDPASSLITE card, and then saving the issued identification card as a QR code image.

// prepare protobuf object
api::Ident ident;

// take photo of user
std::string filename = "userphoto.jpg";
std::ifstream photofile(filename, std::ios::binary);
std::vector<char> photo(std::istreambuf_iterator<char>{photofile}, {});

// initialize protobuf object with identity details
ident.set_surname("Doe");
ident.set_givenname("John");
ident.set_placeofbirth("Kibawe, Bukidnon");
ident.set_pin("12345");
ident.mutable_dateofbirth()->set_year(1978);
ident.mutable_dateofbirth()->set_month(12);
ident.mutable_dateofbirth()->set_day(17);
ident.set_photo(photo.data(), photo.size());

// serialize protobuf object into a byte array
std::vector<unsigned char> identbuf(ident.ByteSizeLong());
ident.SerializeToArray(identbuf.data(), identbuf.size());

// call API to create IDPASSLITE card for ident
int idcard_len;
unsigned char* idcard = idpass_lite_create_card_with_face(context, 
    &idcard_len, identbuf.data(), identbuf.size());

// save idcard as a QR code image
idpass_lite_saveToBitmap(context, idcard, idcard_len, "qrcode_id.bmp");

Using the issued IDPASSLITE card for secure transaction

The issued IDPASSLITE QR code ID can be later used by the card owner for secure transactions. The ID card owner's facial biometric template (this is not his photo) is securely stored inside his QR code ID and forms a bind between the ID and its owner. Therefore, another person carrying this ID and not knowing its secret pin code shall not be able to perform a transaction using the ID.

The two general classifications of secure transaction using the IDPASSLITE card ID are:

  • The card owner issuing digital signature of a piece of data
  • The card owner encrypting any piece of data

Each issued IDPASSLITE QR code ID card contains a unique ED25519 cryptographic key. The contents of the QR code ID is securely protected with an AEAD symmetric encryption and digitally signed with the issuer's ED25519 key.

In addition, the library can be initialized with a list of root certificates and each created card can be supplied with a list of intermediate certificates.

Clone this wiki locally