
/*---------------------------------------------------------------------------*/
/* certificates.h															 */
/* copyright (c) innovaphone 2017                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

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

typedef enum {
    CERTIFICATE_PEM = 0
} certificate_type_t;

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

typedef enum {
    CERTIFICAFTE_KEY_LENGTH_2048 = 2048,
    CERTIFICAFTE_KEY_LENGTH_3072 = 3072,
    CERTIFICAFTE_KEY_LENGTH_4096 = 4096
} certificate_key_length_t;

class ICertificateSigningRequest {
public:
    static ICertificateSigningRequest * Create(const char * commonName, certificate_key_length_t keyLength);

    virtual ~ICertificateSigningRequest() {};
    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;
};

class ICertificateInformation {
public:
    static ICertificateInformation * Create();

    virtual ~ICertificateInformation() {};
    virtual const char * GetCommonName() = 0;
    virtual const char * GetIssuer() = 0;
    virtual const char * GetChainCertificate(size_t index) = 0;
    virtual const char * GetDnsName(size_t index) = 0;
    virtual const char * GetIpAddress(size_t index) = 0;
    virtual const char * GetFingerprintSHA256() = 0;
    virtual const char * GetSignatureAlgorithm() = 0;
    virtual int GetKeyLength() = 0;
    virtual size_t GetChainDepth() = 0;
    virtual size_t GetDnsNamesCount() = 0;
    virtual size_t GetIpAddressesCount() = 0;
    virtual long64 GetNotBefore() = 0;
    virtual long64 GetNotAfter() = 0;
};

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(class IInstanceLog * log, const char * pem, size_t & 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;
};
