namespace axl::cry

namespace cry {

// typedefs

typedef int socket_t;

// enums

enum VerifyAppStoreReceiptFlag;

// structs

struct AesKey;
struct AppStoreIap;
struct AppStoreReceipt;

// classes

class AppStoreReceiptPayloadParser;
class BigNum;
class Bio;
class BnCtx;
class CryptoError;
class CryptoErrorProvider;
class Dh;
class EcKey;
class EcPoint;
class FreeBigNum;
class FreeBio;
class FreeBnCtx;
class FreeDh;
class FreeEcKey;
class FreeEcPoint;
class FreePkcs7;
class FreeRsa;
class FreeX509;
class FreeX509Store;
class Pkcs7;
class Rsa;
class X509Cert;
class X509Error;
class X509ErrorProvider;
class X509Store;

// global functions

bool
verifyAppStoreReceipt(
    AppStoreReceipt* receipt,
    const void* p,
    size_t size,
    const void* computerGuid,
    size_t computerGuidSize,
    uint_t flags = 0
    );

bool
verifyAppStoreReceipt(
    AppStoreReceipt* receipt,
    const void* p,
    size_t size,
    uint_t flags = 0
    );

sl::String
getAsn1TimeString(const ASN1_TIME* time);

sl::String
getAsn1StringString(const ASN1_STRING* string);

sl::String
getAsn1ObjectString(const ASN1_OBJECT* object);

AXL_SL_DEFINE_GUID(
    g_cryptoErrorGuid,
    0x0216b513,
    0xa6bf,
    0x4d0e,
    0x91,
    0x85,
    0xdd,
    0x12,
    0x60,
    0xc7,
    0x53,
    0x56
    );

AXL_SL_DEFINE_GUID(
    g_x509ErrorGuid,
    0xa5c41eb8,
    0x75ff,
    0x487d,
    0xb0,
    0x4e,
    0xbd,
    0x23,
    0x36,
    0x38,
    0x8b,
    0x38
    );

void
registerCryptoErrorProviders();

size_t
setCryptoError(ulong_t code);

void
clearCryptoError();

size_t
setLastCryptoError();

template <typename T>
T
failWithLastCryptoError(T failResult);

bool
failWithLastCryptoError();

template <typename T>
T
completeWithLastCryptoError(
    T result,
    T failResult
    );

bool
completeWithLastCryptoError(int result);

bool
encodePem(
    sl::String* buffer,
    const sl::StringRef& name,
    const sl::StringRef& header,
    const void* p,
    size_t size
    );

bool
encodePem(
    sl::String* buffer,
    const sl::StringRef& name,
    const void* p,
    size_t size
    );

sl::String
encodePem(
    const sl::StringRef& name,
    const sl::StringRef& header,
    const void* p,
    size_t size
    );

sl::String
encodePem(
    const sl::StringRef& name,
    const void* p,
    size_t size
    );

bool
decodePem(
    sl::String* name,
    sl::String* header,
    sl::Array<char>* buffer,
    const sl::StringRef& pem
    );

bool
decodePem(
    sl::String* name,
    sl::Array<char>* buffer,
    const sl::StringRef& pem
    );

bool
decodePem(
    const sl::StringRef& expectedName,
    sl::String* header,
    sl::Array<char>* buffer,
    const sl::StringRef& pem
    );

bool
decodePem(
    const sl::StringRef& expectedName,
    sl::Array<char>* buffer,
    const sl::StringRef& pem
    );

} // namespace cry