351 lines
11 KiB
C
351 lines
11 KiB
C
|
/*
|
||
|
Copyright 2021 Grégory Soutadé
|
||
|
|
||
|
This file is part of libgourou.
|
||
|
|
||
|
libgourou is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU Lesser General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
libgourou 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 Lesser General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Lesser General Public License
|
||
|
along with libgourou. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#ifndef _DRMPROCESSORCLIENT_H_
|
||
|
#define _DRMPROCESSORCLIENT_H_
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
namespace gourou
|
||
|
{
|
||
|
/**
|
||
|
* @brief All fucntions that must be implemented by a client
|
||
|
* This allow libgourou to have only few external libraries dependencies
|
||
|
* and improve code portability
|
||
|
*/
|
||
|
|
||
|
class DigestInterface
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* @brief Create a digest handler (for now only SHA1 is used)
|
||
|
*
|
||
|
* @param digestName Digest name to instanciate
|
||
|
*/
|
||
|
virtual void* createDigest(const std::string& digestName) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Update digest engine with new data
|
||
|
*
|
||
|
* @param handler Digest handler
|
||
|
* @param data Data to digest
|
||
|
* @param length Length of data
|
||
|
*
|
||
|
* @return OK/KO
|
||
|
*/
|
||
|
virtual int digestUpdate(void* handler, unsigned char* data, unsigned int length) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Finalize digest with remained buffered data and destroy handler
|
||
|
*
|
||
|
* @param handler Digest handler
|
||
|
* @param digestOut Digest result (buffer must be pre allocated with right size)
|
||
|
*
|
||
|
* @return OK/KO
|
||
|
*/
|
||
|
virtual int digestFinalize(void* handler, unsigned char* digestOut) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Global digest function
|
||
|
*
|
||
|
* @param digestName Digest name to instanciate
|
||
|
* @param data Data to digest
|
||
|
* @param length Length of data
|
||
|
* @param digestOut Digest result (buffer must be pre allocated with right size)
|
||
|
*
|
||
|
* @return OK/KO
|
||
|
*/
|
||
|
virtual int digest(const std::string& digestName, unsigned char* data, unsigned int length, unsigned char* digestOut) = 0;
|
||
|
};
|
||
|
|
||
|
class RandomInterface
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* @brief Generate random bytes
|
||
|
*
|
||
|
* @param bytesOut Buffer to fill with random bytes
|
||
|
* @param length Length of bytesOut
|
||
|
*/
|
||
|
virtual void randBytes(unsigned char* bytesOut, unsigned int length) = 0;
|
||
|
};
|
||
|
|
||
|
class HTTPInterface
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* @brief Send HTTP (GET or POST) request
|
||
|
*
|
||
|
* @param URL HTTP URL
|
||
|
* @param POSTData POST data if needed, if not set, a GET request is done
|
||
|
* @param contentType Optional content type of POST Data
|
||
|
*/
|
||
|
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string("")) = 0;
|
||
|
};
|
||
|
|
||
|
class RSAInterface
|
||
|
{
|
||
|
public:
|
||
|
enum RSA_KEY_TYPE {
|
||
|
RSA_KEY_PKCS12 = 0,
|
||
|
RSA_KEY_X509
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @brief Encrypt data with RSA private key. Data is padded using PKCS1.5
|
||
|
*
|
||
|
* @param RSAKey RSA key in binary form
|
||
|
* @param RSAKeyLength RSA key length
|
||
|
* @param keyType Key type
|
||
|
* @param password Optional password for RSA PKCS12 certificate
|
||
|
* @param data Data to encrypt
|
||
|
* @param dataLength Data length
|
||
|
* @param res Encryption result (pre allocated buffer)
|
||
|
*/
|
||
|
virtual void RSAPrivateEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
||
|
const RSA_KEY_TYPE keyType, const std::string& password,
|
||
|
const unsigned char* data, unsigned dataLength,
|
||
|
unsigned char* res) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Encrypt data with RSA public key. Data is padded using PKCS1.5
|
||
|
*
|
||
|
* @param RSAKey RSA key in binary form
|
||
|
* @param RSAKeyLength RSA key length
|
||
|
* @param keyType Key type
|
||
|
* @param password Optional password for RSA PKCS12 certificate
|
||
|
* @param data Data to encrypt
|
||
|
* @param dataLength Data length
|
||
|
* @param res Encryption result (pre allocated buffer)
|
||
|
*/
|
||
|
virtual void RSAPublicEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
||
|
const RSA_KEY_TYPE keyType,
|
||
|
const unsigned char* data, unsigned dataLength,
|
||
|
unsigned char* res) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Generate RSA key. Expnonent is fixed (65537 / 0x10001)
|
||
|
*
|
||
|
* @param keyLengthBits Length of key (in bits) to generate
|
||
|
*
|
||
|
* @return generatedKey
|
||
|
*/
|
||
|
virtual void* generateRSAKey(int keyLengthBits) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Destroy key previously generated
|
||
|
*
|
||
|
* @param handler Key to destroy
|
||
|
*/
|
||
|
virtual void destroyRSAHandler(void* handler) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Extract public key (big number) from RSA handler
|
||
|
*
|
||
|
* @param handler RSA handler (generated key)
|
||
|
* @param keyOut Pre allocated buffer (if *keyOut != 0). If *keyOut is 0, memory is internally allocated (must be freed)
|
||
|
* @param keyOutLength Length of result
|
||
|
*/
|
||
|
virtual void extractRSAPublicKey(void* handler, unsigned char** keyOut, unsigned int* keyOutLength) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Extract private key (big number) from RSA handler
|
||
|
*
|
||
|
* @param handler RSA handler (generated key)
|
||
|
* @param keyOut Pre allocated buffer (if *keyOut != 0). If *keyOut is 0, memory is internally allocated (must be freed)
|
||
|
* @param keyOutLength Length of result
|
||
|
*/
|
||
|
virtual void extractRSAPrivateKey(void* handler, unsigned char** keyOut, unsigned int* keyOutLength) = 0;
|
||
|
};
|
||
|
|
||
|
class CryptoInterface
|
||
|
{
|
||
|
public:
|
||
|
enum CHAINING_MODE {
|
||
|
CHAIN_ECB=0,
|
||
|
CHAIN_CBC
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @brief Do AES encryption. If length of data is not multiple of 16, PKCS#5 padding is done
|
||
|
*
|
||
|
* @param chaining Chaining mode
|
||
|
* @param key AES key
|
||
|
* @param keyLength AES key length
|
||
|
* @param iv IV key
|
||
|
* @param ivLength IV key length
|
||
|
* @param dataIn Data to encrypt
|
||
|
* @param dataInLength Data length
|
||
|
* @param dataOut Encrypted data
|
||
|
* @param dataOutLength Length of encrypted data
|
||
|
*/
|
||
|
virtual void AESEncrypt(CHAINING_MODE chaining,
|
||
|
const unsigned char* key, unsigned int keyLength,
|
||
|
const unsigned char* iv, unsigned int ivLength,
|
||
|
const unsigned char* dataIn, unsigned int dataInLength,
|
||
|
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Init AES CBC encryption
|
||
|
*
|
||
|
* @param chaining Chaining mode
|
||
|
* @param key AES key
|
||
|
* @param keyLength AES key length
|
||
|
* @param iv IV key
|
||
|
* @param ivLength IV key length
|
||
|
*
|
||
|
* @return AES handler
|
||
|
*/
|
||
|
virtual void* AESEncryptInit(CHAINING_MODE chaining,
|
||
|
const unsigned char* key, unsigned int keyLength,
|
||
|
const unsigned char* iv=0, unsigned int ivLength=0) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Encrypt data
|
||
|
*
|
||
|
* @param handler AES handler
|
||
|
* @param dataIn Data to encrypt
|
||
|
* @param dataInLength Data length
|
||
|
* @param dataOut Encrypted data
|
||
|
* @param dataOutLength Length of encrypted data
|
||
|
*/
|
||
|
virtual void AESEncryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
|
||
|
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Finalize AES encryption (pad and encrypt last block if needed)
|
||
|
* Destroy handler at the end
|
||
|
*
|
||
|
* @param handler AES handler
|
||
|
* @param dataOut Last block of encrypted data
|
||
|
* @param dataOutLength Length of encrypted data
|
||
|
*/
|
||
|
virtual void AESEncryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Do AES decryption. If length of data is not multiple of 16, PKCS#5 padding is done
|
||
|
*
|
||
|
* @param chaining Chaining mode
|
||
|
* @param key AES key
|
||
|
* @param keyLength AES key length
|
||
|
* @param iv IV key
|
||
|
* @param ivLength IV key length
|
||
|
* @param dataIn Data to encrypt
|
||
|
* @param dataInLength Data length
|
||
|
* @param dataOut Encrypted data
|
||
|
* @param dataOutLength Length of encrypted data
|
||
|
*/
|
||
|
virtual void AESDecrypt(CHAINING_MODE chaining,
|
||
|
const unsigned char* key, unsigned int keyLength,
|
||
|
const unsigned char* iv, unsigned int ivLength,
|
||
|
const unsigned char* dataIn, unsigned int dataInLength,
|
||
|
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Init AES decryption
|
||
|
*
|
||
|
* @param chaining Chaining mode
|
||
|
* @param key AES key
|
||
|
* @param keyLength AES key length
|
||
|
* @param iv IV key
|
||
|
* @param ivLength IV key length
|
||
|
*
|
||
|
* @return AES handler
|
||
|
*/
|
||
|
virtual void* AESDecryptInit(CHAINING_MODE chaining,
|
||
|
const unsigned char* key, unsigned int keyLength,
|
||
|
const unsigned char* iv=0, unsigned int ivLength=0) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Decrypt data
|
||
|
*
|
||
|
* @param handler AES handler
|
||
|
* @param dataIn Data to decrypt
|
||
|
* @param dataInLength Data length
|
||
|
* @param dataOut Decrypted data
|
||
|
* @param dataOutLength Length of decrypted data
|
||
|
*/
|
||
|
virtual void AESDecryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
|
||
|
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
|
||
|
/**
|
||
|
* @brief Finalize AES decryption (decrypt last block and remove padding if it is set).
|
||
|
* Destroy handler at the end
|
||
|
*
|
||
|
* @param handler AES handler
|
||
|
* @param dataOut Last block decrypted data
|
||
|
* @param dataOutLength Length of decrypted data
|
||
|
*/
|
||
|
virtual void AESDecryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;
|
||
|
};
|
||
|
|
||
|
|
||
|
class ZIPInterface
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* @brief Open a zip file and return an handler
|
||
|
*
|
||
|
* @param path Path of zip file
|
||
|
*
|
||
|
* @return ZIP file handler
|
||
|
*/
|
||
|
virtual void* zipOpen(const std::string& path) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Read zip internal file
|
||
|
*
|
||
|
* @param handler ZIP file handler
|
||
|
* @param path Internal path inside zip file
|
||
|
*
|
||
|
* @return File content
|
||
|
*/
|
||
|
virtual std::string zipReadFile(void* handler, const std::string& path) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Write zip internal file
|
||
|
*
|
||
|
* @param handler ZIP file handler
|
||
|
* @param path Internal path inside zip file
|
||
|
* @param content Internal file content
|
||
|
*/
|
||
|
virtual void zipWriteFile(void* handler, const std::string& path, const std::string& content) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Delete zip internal file
|
||
|
*
|
||
|
* @param handler ZIP file handler
|
||
|
* @param path Internal path inside zip file
|
||
|
*/
|
||
|
virtual void zipDeleteFile(void* handler, const std::string& path) = 0;
|
||
|
|
||
|
/**
|
||
|
* @brief Close ZIP file handler
|
||
|
*
|
||
|
* @param handler ZIP file handler
|
||
|
*/
|
||
|
virtual void zipClose(void* handler) = 0;
|
||
|
};
|
||
|
|
||
|
class DRMProcessorClient: public DigestInterface, public RandomInterface, public HTTPInterface, \
|
||
|
public RSAInterface, public CryptoInterface, public ZIPInterface
|
||
|
{};
|
||
|
}
|
||
|
#endif
|