/*
 * The Cryptonit security software suite is developped by IDEALX
 * Cryptonit Team (http://IDEALX.org/ and http://cryptonit.org).
 *
 * Copyright 2003-2006 IDEALX
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301, USA. 
 *
 * In addition, as two special exceptions:
 *
 * 1) IDEALX S.A.S gives permission to:
 *  * link the code of portions of his program with the OpenSSL library under
 *    certain conditions described in each source file
 *  * distribute linked combinations including the two, with respect to the
 *    OpenSSL license and with the GPL
 *
 * You must obey the GNU General Public License in all respects for all of the
 * code used other than OpenSSL. If you modify file(s) with this exception,
 * you may extend this exception to your version of the file(s), but you are
 * not obligated to do so. If you do not wish to do so, delete this exception
 * statement from your version, in all files (this very one along with all
 * source files).

 * 2) IDEALX S.A.S acknowledges that portions of his sourcecode uses (by the
 * way of headers inclusion) some work published by 'RSA Security Inc.'. Those
 * portions are "derived from the RSA Security Inc. PKCS #11Cryptographic
 * Token Interface (Cryptoki)" as described in each individual source file.
 */

#ifndef _UTILS_HH_
#define _UTILS_HH_

#include <string>
#include <vector>

#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/pkcs12.h>
/**
   Non object oriented functions
 */

static unsigned const char cov_2char[64]={
	/* from crypto/des/fcrypt.c */
	0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
	0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
	0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
	0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
	0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
	0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
	0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
	0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
};


char *generateSalt();
char *encryptPassword(const char *passwd, const char *magic, const char *salt);
int MKDIR(const char *x);

std::string getSalt(const char* password);

std::string simpleHash( void* buffer, int len );
std::string simpleHash( const char* filename );
std::string simpleHash(BIO *b);

const EVP_CIPHER* getCipher( std::string cipher );
std::vector< std::pair< std::string, std::string > > getAllCiphers();
std::vector< std::pair< std::string, std::string> > getAllDigests();

struct eqstr {
    bool operator()(const char* s1, const char* s2) const {
	return s1 == s2;
    }
};


/**
 * append dir to path
 * @param path : a path 
 * @param dir : a dir to append to the path
 * @return the resulting path
* example : appendDir("foo","bar") will return foo/bar
 */
std::string appendDir( const std::string path , const std::string dir );

std::string setExt( const std::string filename , const std::string ext );

/** Create an open a temporary file, using the
 *  given template.
 *  Use the mkstemp() function or emulate it if it
 *  is not available.
 */
int makeTempFile( std::string &tmpl );


/** Copy file to another. The destination file is created
 *  if it didn't exist.
 */
int copyFile( const std::string src, const std::string dest );


/** Return the user home dir using
 *  different environnement variables.
 *  Create it if it was not found.
 */
std::string getCryptonitHome();


/**
 * rewriting of OpenSSL PKCS12_parse functions family :
 * PKCS12_parse seems to be broken when all certificates in the PKCS12 
 * have  a localKeyID. 
 * This bug ^H^H^H feature  results in getting an empty CA Stack, and an
 * irrevelant user certificate ...
 * @param p12:  pointer on the PKCS12 to parse
 * @param password: PKCS12 password
 * @param key: EVP_PKEY structure to fill with the private wich will be extracted from the PKC12
 * @param cer : X509 structure to fill with the certificate matching the private key
 * @param  ca : a stack of CA's Certificates.
 */

int PKCS12_parse_fix(PKCS12 *p12 ,const char *password, EVP_PKEY **key , X509 **cer , STACK_OF(X509) **ca);

int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, const char *pass,int passlen, EVP_PKEY **key, STACK_OF(X509) **ca);

int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen, EVP_PKEY **key, STACK_OF(X509) **ca);

int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **key, STACK_OF(X509) **ca);
#endif
