# Certificates

Interface to create and validate certificates.

## File information

File | common/interface/certificates.h
Classes | ICertificates
Data types | certificate_error_t certificate_type_t fingerprint_t
Examples | Example

### Logging

To enable logging for ICertificates, the flag LOG_TLS must be set in the managers diagnostic settings.

# Classes

## ICertificates

    class ICertificates {
    public:
        static certificate_error_t ValidateCertificate(class IInstanceLog * log, const byte * cert, size_t certLen, class ICertificateInformation * info = nullptr, bool privateKeyRequired = true, bool verifyChain = true);
        static bool CreateCertificateSigningRequest(class IInstanceLog * log, class ICertificateSigningRequest * iCsr);
        static byte * ConvertPEMToDER(this, csr->GetRequestPEM(), outLength);
        static char * ConvertDERToPEM(class IInstanceLog * log, const byte * der, size_t derLength);
        virtual byte * CertificateFingerprint(class IInstanceLog * log, const byte * cert, size_t certLen, size_t * length, fingerprint_t type = FINGERPRINT_SHA256) = 0;
        virtual byte * CreateCertificate(class IInstanceLog * log, size_t * certLen, certificate_type_t type = CERTIFICATE_PEM) = 0;
    };

### Public functions

ValidateCertificate (static function)

  This function validates a certificate in PEM format.

  #### Parameters

  IInstanceLog * log | An IInstanceLog pointer to the logging interface.
  const byte * cert | A byte buffer which holds the certificate.
  size_t certLen | The length of the byte buffer.
  ICertificateInformation * info | An optional ICertificateInformation object which will hold information about the certificate after successfull information.
  bool privateKeyRequired | Default true; if false, the chain does not need to contain a private key.
  bool verifyChain | Default true; if false, the certificate chain is not verified.

  #### Return value

  An enum certificate_error_t which indicates a possible error.

  #### Remarks

  If you want certificate informations, you must hand an instance of ICertificateInformation, which you can create with ICertificateInformation::Create. You are responsible for deletion of this object afterwards!

CreateCertificateSigningRequest (static function)

  This function will create a private RSA key together with a certificate signing request.

  #### Parameters

  IInstanceLog * log | An IInstanceLog pointer to the logging interface.
  ICertificateSigningRequest * iCsr | An ICertificateSigningRequest object which will hold information about the CSR and after the creation the private key and request.

  #### Return value

  A boolean, if false, something failed (enable TLS traces to see possible erros).

  #### Remarks

  As the generation of an RSA certificate may take a while, depending on the architecture and key length, you should consider to call this function inside a thread to avoid blocking of your App.

ConvertPEMToDER (static function)

  This function will convert a PEM formatted certificate to a DER format.

  #### Parameters

  IInstanceLog * log | An IInstanceLog pointer to the logging interface.
  const char * pem | A const char * which holds the null terminated PEM string.
  size_t & outLength | A reference to a size_t variable which will hold the length of the returned buffer afterwards.

  #### Return value

  A byte * buffer. You must free this buffer yourself! On errors, a nullptr is returned and the error can be found in the log file with an enabled TLS log flag.

  #### Remarks

  Just simple PEMs with a single certificate and without certificate data description, just with ----- lines and base64 encoding are supported.

ConvertDERToPEM (static function)

  This function will convert a DER formatted certificate to a PEM format.

  #### Parameters

  IInstanceLog * log | An IInstanceLog pointer to the logging interface.
  const byte * der | A const byte * which holds the DER binary data.
  size_t derLength | The length of the der byte array.

  #### Return value

  A char * buffer. You must free this buffer yourself! On errors, a nullptr is returned and the error can be found in the log file with an enabled TLS log flag.

  #### Remarks

  Just a single public key certificate is supported.

CertificateFingerprint

  This function generates a certificate fingerprint for PEM certificates.

  #### Parameters

  IInstanceLog * log | An IInstanceLog pointer to the logging interface.
  const byte * cert | A byte buffer which holds the certificate.
  size_t certLen | The length of the byte buffer.
  fingerprint_t type | The fingerprint hash type.

  #### Return value

  A byte buffer holding the fingerprint hash. The buffer must be freed by the caller.

CreateCertificate

  This function creates a certificate.

  #### Parameters

  IInstanceLog * log | An IInstanceLog pointer to the logging interface.
  size_t * certLen | The length of the returned buffer.
  certificate_type_t type | The output certificate type.

  #### Return value

  A byte buffer holding the certificates private and public key. The buffer must be freed by the caller.

## ICertificateSigningRequest

    class ICertificateSigningRequest {
    public:
        static ICertificateSigningRequest * Create(const char * commonName, certificate_key_length_t keyLength);;
        virtual void AddDnsName(const char * dnsName) = 0;;
        virtual certificate_key_length_t GetKeyLength() = 0;;
        virtual const char * GetCommonName() = 0;;
        virtual const char * GetPrivateKeyPEM() = 0;;
        virtual const char * GetRequestPEM() = 0;;
    };

### Usage

This class is used to hand neccessary information to ICertificates::CreateCertificateSigningRequest and afterwards also holds the created privated key and CSR on success.
An object is created by ICertificateSigningRequest::Create. You can hand one or multiple DNS names with the function AddDnsName(const char * dnsName).
You must delete the object after your usage.

### Public functions

Create (static function)

  This function creates an object for the interface class ICertificateSigningRequest.

  #### Parameters

  const char * commonName | The common name for the signing request.
  certificate_key_length_t keyLength | The key length of the generated certificate.

  #### Return value

  An object of type ICertificateSigningRequest.

AddDnsName

  Adds a DNS name which will be added as subject alternative name to the CSR.

  #### Parameters

  const char * dnsName | The DNS name.

GetKeyLength

  #### Return value

  An enum certificate_key_length_t with the set key length.

GetCommonName

  #### Return value

  A const char * with the common name.

GetPrivateKeyPEM

  #### Return value

  A const char * with the private key in PEM format.

GetRequestPEM

  #### Return value

  A const char * with the certificate signing request in PEM format..

## ICertificateInformation

        class ICertificateInformation {
        public:
        static ICertificateInformation * Create();
        virtual const char * GetCommonName() = 0;
        virtual const char * GetIssuer() = 0;
        virtual int GetNotAfter() = 0;
        virtual int GetNotBefore() = 0;
        virtual size_t GetChainDepth() = 0;
        virtual const char * GetChainCertificate(size_t index) = 0;
        virtual size_t GetDnsNamesCount() = 0;
        virtual const char * GetDnsName(size_t index) = 0;
        virtual size_t GetIpAddressesCount() = 0;
        virtual const char * GetIpAddress(size_t index) = 0;
        virtual const char * GetFingerprintSHA256() = 0;
        virtual const char * GetSignatureAlgorithm() = 0;
        };

### Usage

An object is created by ICertificateInformation::Create.
You must delete the object after your usage.

### Public functions

Create (static function)

  This function creates an object for the interface class ICertificateInformation.

  #### Return value

  An object of type ICertificateInformation.

GetCommonName

  #### Return value

  A const char * with the common name.

GetCommonName

  #### Return value

  A const char * with the issuer.

GetNotAfter

  #### Return value

  Valid not after as ulong64 UTC timestamp in milliseconds.

GetNotBefore

  #### Return value

  Valid not before as ulong64 UTC timestamp in milliseconds.

GetChainDepth

  #### Return value

  The size_t chain depth, aka count of chain certificates.

GetChainCertificate

  #### Parameters

  size_t index | The index of the chain certificate which shall be returned.

  #### Return value

  A const char * pointer to the chain certificate in PEM format. If index is not found, nullptr is returned.

GetDnsNamesCount

  #### Return value

  The size_t count of DNS SAN entries.

GetDnsName

  #### Parameters

  size_t index | The index of the DNS name which shall be returned.

  #### Return value

  A const char * pointer to the DNS name. If index is not found, nullptr is returned.

GetIpAddressesCount

  #### Return value

  The size_t count of IP address SAN entries.

GetIpAddress

  #### Parameters

  size_t index | The index of the IP address which shall be returned.

  #### Return value

  A const char * pointer to the IP address. If index is not found, nullptr is returned.

GetFingerprintSHA256

  #### Return value

  A const char * pointer to the SHA256 fingerprint.

GetSignatureAlgorithm

  #### Return value

  A const char * pointer to the used signature algorithm.

# Data types

## certificate_error_t

    typedef enum {
        CERTIFICATE_OK = 0,
        CERTIFICATE_PARSING_FAILED,
        CERTIFICATE_PUBLIC_KEY_INVALID,
        CERTIFICATE_PRIVATE_KEY_INVALID,
        CERTIFICATE_LOAD_FAILED,
        CERTIFICATE_CHAIN_INVALID
    } certificate_error_t;

### Overview

The `enum certificate_error_t` is used to determine the error code of the parsing or if the parsing succeeded.

## certificate_type_t

    typedef enum {
        CERTIFICATE_PEM = 0
    } certificate_type_t;

### Overview

The `enum certificate_type_t` holds all supported certificate types.

## fingerprint_t

    typedef enum {
        FINGERPRINT_MD5,
        FINGERPRINT_SHA1,
        FINGERPRINT_SHA224,
        FINGERPRINT_SHA256,
        FINGERPRINT_SHA384,
        FINGERPRINT_SHA512
    } fingerprint_t;

## certificate_key_length_t

    typedef enum {
        CERTIFICAFTE_KEY_LENGTH_2048,
        CERTIFICAFTE_KEY_LENGTH_3072,
        CERTIFICAFTE_KEY_LENGTH_4096

    } certificate_key_length_t;

### Overview

The `enum fingerprint_t` holds all supported fingerprint hash types.

# Code Example

    size_t pemBufferLen = 0;
    byte * pemBuffer = ICertificates::CreateCertificate(logIf, &pemBufferLen, CERTIFICATE_PEM);
    if(pemBuffer) {
        ICertificateInformation * info = ICertificateInformation::Create();
        if(ICertificates::ValidateCertificate(logIf, pemBuffer, pemBufferLen, info) == CERTIFICATE_OK) {
            size_t certFplength;
            byte * fingerPrint = CertificateFingerprint(logIf, pemBuffer, pemBufferLen, &certFplength, FINGERPRINT_SHA512);
            debug->printf("fingerprint of new certificate: %s notAfter:%llu", fingerPrint, info->GetNotAfter());
            free(fingerPrint);
        }
        free(pemBuffer);
        delete info;
    }