rust-italia / dgc

A parser and validator for the EU Digital Green Certificate (dgc) a.k.a. greenpass
https://github.com/rust-italia/dgc
MIT License
26 stars 11 forks source link

C bindings #37

Open lu-zero opened 2 years ago

lu-zero commented 2 years ago
lmammino commented 2 years ago

Wow, this one looks super interesting. I have no idea how to do this stuff, so definitely a learning opportunity for me! :)

Looking forward to seeing this happening

lu-zero commented 2 years ago

We can try to make it a show & tell event.

lu-zero commented 2 years ago

Here how it could look like

#ifndef DGC_H
#define DGC_H

/* Generated with cbindgen:0.20.0 */

#define DGC_MAJOR 0
#define DGC_MINOR 0
#define DGC_PATCH 7

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/**
 * The main container for one or more DGC entries.
 */
typedef struct DgcContainer DgcContainer;

/**
 * Represents all the possible types of failures that can occure when parsing a certificate.
 */
typedef struct DgcParseError DgcParseError;

/**
 * Represents all the possible outcomes of trying to validate a signature
 * for a given certificate.
 */
typedef struct DgcValidity DgcValidity;

/**
 * Struct used to index all the available public keys which
 * can be used to validate the signature on a given certificate.
 *
 * Keys are indexed by their `kid` (Key ID) which is an arbitrary sequence of bytes.
 */
typedef struct TrustList TrustList;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
 * Decodes the certificate and returns the [`DgcContainer`] data contained in it.
 *
 * This function is recommended when you don't want to validate the signature but you
 * are just interested in reading the content of the certificate.
 */
const struct DgcParseError *dgc_decode(const uint8_t *data,
                                       uintptr_t len,
                                       struct DgcContainer **container);

/**
 * Parses and validates a given certificate.
 *
 * This function is a high level helper that allows you to extract the data from a
 * certificate and at the same time it tries to validate the signature against a given
 * trustlist.
 *
 * This function will return an error if the certificate cannot be parsed or is invalid.
 * If the certificate can be parsed correctly, this function returns a tuple containing a
 * [`DgcContainer`] and a [`SignatureValidity`].
 *
 * This design allows for permissive validation of the certificate signature.
 * In fact, `SignatureValidity` can be used to determine if the signature is valid and even if it is
 * invalid (or the validity cannot be assessed) you could still access all the information
 * in the certificate.
 */
const struct DgcParseError *dgc_validate(const uint8_t *data,
                                         uintptr_t len,
                                         const struct TrustList *trustlist,
                                         struct DgcContainer **container,
                                         struct DgcValidity **validity);

bool dgc_signature_is_valid(const struct DgcValidity *error);

uint8_t *dgc_container_to_json(const struct DgcContainer *container);

void dgc_container_free_json(uint8_t **json);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

#endif /* DGC_H */