#ifndef ENCRYPT_LIB_H
#define ENCRYPT_LIB_H
#ifdef HAS_SSL

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#endif

#ifdef  __cplusplus
extern "C" {
#endif

#ifdef HAS_SSL

typedef struct cert_info_st {
	char *domain, *organisation, *unit, *state, *city, *country, *email, *altname;
} cert_info;

int encrypt_lib_create_certificate(char *certificate_file, char *private_key_file, char *password, char *data_domain, long days);
int encrypt_lib_create_certificate2(char *certificate_file, EVP_PKEY *pk, char *data_domain, long days);
int encrypt_lib_create_certificate3(char *certificate_file, EVP_PKEY *pk, char *data_domain, char *data_email, long days);
int encrypt_lib_create_private_key(char *fname, int bits, char *password);

int encrypt_lib_create_csr(char *csr_file, char *private_key_file, char *password, long days, cert_info *ci, char *reason);
int encrypt_lib_create_cert(char *certificate_file, char *private_key_file, char *password, long days, cert_info *ci);


char *encrypt_lib_encrypt(X509 **certs, int num_certs, char *msg, int msg_len);
/*
Returns a base64 encoded encryption of the message.
*/

int encrypt_lib_decrypt(char *in_data, X509 *recipient_certificate, EVP_PKEY *private_key, char **out_data, int *out_data_len);
/*
Takes in a base64 encoded message encoded for recipient_certificate as one of the recipients,
and decodes it using the corresponding private key.
On success allocates data in out_data and stores decrypted data in it.
*/

char *encrypt_lib_sign(char *data, int data_len, X509 *cert, EVP_PKEY *private_key);
/*
Returns a base64 encoded signature.
*/

X509 *encrypt_lib_verify_and_get_cert(char *data, int data_len, char *signature);
/*
If signature is valid for given data, return the x509 signature.
No checking is done for if signature is actually a signed by a trusted CA.
(since this is written for an app using self signed certs - i.e. user accepts cert first
time and is notified if it ever changes. )
*/

void encrypt_lib_test2(char *private_key_file, char *certificate_file);
int hmac_sha1(unsigned char *data, int data_len, unsigned char *key, int key_len, unsigned char *digest,  unsigned int *digest_len);

int encrypt_lib_set_certificate_dir(char *dir);
int encrypt_lib_free();
X509 *encrypt_lib_get_certificate(char *user);
int encrypt_lib_save_certificate(char *user, X509 *cert);

enum {EXPECT_SIG_NO, EXPECT_SIG_YES, EXPECT_SIG_UNDECIDED};
int encrypt_lib_set_expect_sig(char *user, int expect_it);
int encrypt_lib_expect_sig(char *user);

X509 *encrypt_lib_bf_to_cert(char *bf);
char *encrypt_lib_cert_to_bf(X509 *cert);


EVP_PKEY *encrypt_lib_read_private_key(char *fname, char *password);
X509 *encrypt_lib_read_certificate2(char *fname, int return_no_cert_on_empty_file);
X509 *encrypt_lib_read_certificate(char *fname);
int encrypt_lib_write_certificate(char *fname, X509 *cert);
EVP_PKEY *encrypt_lib_read_public_key(char *fname);
int encrypt_lib_write_private_key(char *fname, EVP_PKEY *pk, char *password);
int encrypt_lib_delete_file(char *fname);
char *encrypt_lib_file_name(char *bf, int bfsz, char *user);
char *encrypt_lib_expect_file_name(char *bf, int bfsz, char *user);
int encrypt_lib_extract_signature(char *data);
int encrypt_lib_create_certificate_for_email(char *certificate_file, char *private_key_file, char *password, char *data_name, char *data_email, long days);
int encrypt_lib_encrypt_file(FILE *fin, FILE *fout, unsigned char *key_data,char *reason);
int encrypt_lib_decrypt_file(FILE *fin, int inlen, FILE *fout, char *secret, char *reason);

int encrypt_lib_encrypt_file_byname(char *fin, char *fout, unsigned char *key_data,char *reason);
int encrypt_lib_decrypt_file_byname(char *fin, char *fout, unsigned char *key_data,char *reason);
int encrypt_lib_create_pubkey(char *outfile, char* file);
int encrypt_lib_seed(void);
#define CERT_NO_CERT (X509 *)1

#endif

int encrypt_cert_checksum(char *cert_bf);
int more_secure_certs_init(int value);
// chrisp added function below...
int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx);

#ifdef  __cplusplus
}
#endif

#endif
