Some code formating

This commit is contained in:
2026-01-18 15:44:20 +01:00
parent 8061681705
commit 8f0341d0bd
26 changed files with 3989 additions and 3988 deletions

View File

@@ -30,104 +30,104 @@
namespace macaron {
class Base64 {
public:
class Base64 {
public:
static std::string Encode(const std::string data) {
static
static std::string Encode(const std::string data) {
static
#if __STDC_VERSION__ >= 201112L
constexpr
constexpr
#endif /* __STDC_VERSION__ >= 201112L */
char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
size_t in_len = data.size();
size_t out_len = 4 * ((in_len + 2) / 3);
std::string ret(out_len, '\0');
size_t i;
char *p = const_cast<char*>(ret.c_str());
size_t in_len = data.size();
size_t out_len = 4 * ((in_len + 2) / 3);
std::string ret(out_len, '\0');
size_t i;
char *p = const_cast<char*>(ret.c_str());
for (i = 0; i < in_len - 2; i += 3) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int) (data[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[data[i + 2] & 0x3F];
}
if (i < in_len) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
if (i == (in_len - 1)) {
*p++ = sEncodingTable[((data[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
for (i = 0; i < in_len - 2; i += 3) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int) (data[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[data[i + 2] & 0x3F];
}
if (i < in_len) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
if (i == (in_len - 1)) {
*p++ = sEncodingTable[((data[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
return ret;
}
return ret;
}
static std::string Decode(const std::string& input, std::string& out) {
static
static std::string Decode(const std::string& input, std::string& out) {
static
#if __STDC_VERSION__ >= 201112L
constexpr
constexpr
#endif /* __STDC_VERSION__ >= 201112L */
unsigned char kDecodingTable[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
unsigned char kDecodingTable[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
size_t in_len = input.size();
if (in_len % 4 != 0) return "Input data size is not a multiple of 4";
size_t out_len = in_len / 4 * 3;
if (input[in_len - 1] == '=') out_len--;
if (input[in_len - 2] == '=') out_len--;
out.resize(out_len);
for (size_t i = 0, j = 0; i < in_len;) {
uint32_t a = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t b = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t c = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t d = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
if (j < out_len) out[j++] = (triple >> 2 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 1 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 0 * 8) & 0xFF;
}
return "";
}
};
size_t in_len = input.size();
if (in_len % 4 != 0) return "Input data size is not a multiple of 4";
size_t out_len = in_len / 4 * 3;
if (input[in_len - 1] == '=') out_len--;
if (input[in_len - 2] == '=') out_len--;
out.resize(out_len);
for (size_t i = 0, j = 0; i < in_len;) {
uint32_t a = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t b = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t c = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t d = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
if (j < out_len) out[j++] = (triple >> 2 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 1 * 8) & 0xFF;
if (j < out_len) out[j++] = (triple >> 0 * 8) & 0xFF;
}
return "";
}
};
}
#endif /* _MACARON_BASE64_H_ */

View File

@@ -38,149 +38,149 @@ namespace gourou
{
public:
/**
* @brief Create an empty byte array
*
* @param useMalloc If true, use malloc() instead of new[] for allocation
*/
ByteArray(bool useMalloc=false);
/**
* @brief Create an empty byte array
*
* @param useMalloc If true, use malloc() instead of new[] for allocation
*/
ByteArray(bool useMalloc=false);
/**
* @brief Create an empty byte array of length bytes
*
* @param length Length of data
* @param useMalloc If true, use malloc() instead of new[] for allocation
*/
ByteArray(unsigned int length, bool useMalloc=false);
/**
* @brief Create an empty byte array of length bytes
*
* @param length Length of data
* @param useMalloc If true, use malloc() instead of new[] for allocation
*/
ByteArray(unsigned int length, bool useMalloc=false);
/**
* @brief Initialize ByteArray with a copy of data
*
* @param data Data to be copied
* @param length Length of data
*/
ByteArray(const unsigned char* data, unsigned int length);
/**
* @brief Initialize ByteArray with a copy of data
*
* @param data Data to be copied
* @param length Length of data
*/
ByteArray(const unsigned char* data, unsigned int length);
/**
* @brief Initialize ByteArray with a copy of data
*
* @param data Data to be copied
* @param length Optional length of data. If length == -1, it use strlen(data) as length
*/
ByteArray(const char* data, int length=-1);
/**
* @brief Initialize ByteArray with a copy of data
*
* @param data Data to be copied
* @param length Optional length of data. If length == -1, it use strlen(data) as length
*/
ByteArray(const char* data, int length=-1);
/**
* @brief Initialize ByteArray with a copy of str
*
* @param str Use internal data of str
*/
ByteArray(const std::string& str);
/**
* @brief Initialize ByteArray with a copy of str
*
* @param str Use internal data of str
*/
ByteArray(const std::string& str);
ByteArray(const ByteArray& other);
~ByteArray();
ByteArray(const ByteArray& other);
~ByteArray();
/**
* @brief Encode "other" data into base64 and put it into a ByteArray
*/
static ByteArray fromBase64(const ByteArray& other);
/**
* @brief Encode "other" data into base64 and put it into a ByteArray
*/
static ByteArray fromBase64(const ByteArray& other);
/**
* @brief Encode data into base64 and put it into a ByteArray
*
* @param data Data to be encoded
* @param length Optional length of data. If length == -1, it use strlen(data) as length
*/
static ByteArray fromBase64(const char* data, int length=-1);
/**
* @brief Encode data into base64 and put it into a ByteArray
*
* @param data Data to be encoded
* @param length Optional length of data. If length == -1, it use strlen(data) as length
*/
static ByteArray fromBase64(const char* data, int length=-1);
/**
* @brief Encode str into base64 and put it into a ByteArray
*
* @param str Use internal data of str
*/
static ByteArray fromBase64(const std::string& str);
/**
* @brief Encode str into base64 and put it into a ByteArray
*
* @param str Use internal data of str
*/
static ByteArray fromBase64(const std::string& str);
/**
* @brief Return a string with base64 encoded internal data
*/
std::string toBase64();
/**
* @brief Return a string with base64 encoded internal data
*/
std::string toBase64();
/**
* @brief Convert hex string into bytes
*
* @param str Hex string
*/
static ByteArray fromHex(const std::string& str);
/**
* @brief Convert hex string into bytes
*
* @param str Hex string
*/
static ByteArray fromHex(const std::string& str);
/**
* @brief Return a string with human readable hex encoded internal data
*/
std::string toHex();
/**
* @brief Return a string with human readable hex encoded internal data
*/
std::string toHex();
/**
* @brief Append a byte to internal data
*/
void append(unsigned char c);
/**
* @brief Append a byte to internal data
*/
void append(unsigned char c);
/**
* @brief Append data to internal data
*/
void append(const unsigned char* data, unsigned int length);
/**
* @brief Append data to internal data
*/
void append(const unsigned char* data, unsigned int length);
/**
* @brief Append str to internal data
*/
void append(const char* str);
/**
* @brief Append str to internal data
*/
void append(const char* str);
/**
* @brief Append str to internal data
*/
void append(const std::string& str);
/**
* @brief Append str to internal data
*/
void append(const std::string& str);
/**
* @brief Get internal data. Must not be freed
*/
unsigned char* data() {return _data;}
/**
* @brief Get internal data. Must not be freed
*/
unsigned char* data() {return _data;}
/**
* @brief Get internal data and increment internal reference counter.
* Must bot be freed
*/
unsigned char* takeShadowData() {addRef() ; return _data;}
/**
* @brief Get internal data and increment internal reference counter.
* Must bot be freed
*/
unsigned char* takeShadowData() {addRef() ; return _data;}
/**
* @brief Release shadow data. It can now be freed by ByteArray
*/
void releaseShadowData() {delRef();}
/**
* @brief Release shadow data. It can now be freed by ByteArray
*/
void releaseShadowData() {delRef();}
/**
* @brief Get internal data length
*/
unsigned int length() const {return _length;}
/**
* @brief Get internal data length
*/
unsigned int length() const {return _length;}
/**
* @brief Get internal data length
*/
unsigned int size() const {return length();}
/**
* @brief Get internal data length
*/
unsigned int size() const {return length();}
/**
* @brief Increase or decrease internal buffer
* @param length New length of internal buffer
* @param keepData If true copy old data on new buffer, if false,
* create a new buffer with random data
*/
void resize(unsigned int length, bool keepData=true);
/**
* @brief Increase or decrease internal buffer
* @param length New length of internal buffer
* @param keepData If true copy old data on new buffer, if false,
* create a new buffer with random data
*/
void resize(unsigned int length, bool keepData=true);
ByteArray& operator=(const ByteArray& other);
ByteArray& operator=(const ByteArray& other);
private:
void initData(const unsigned char* data, unsigned int length);
void addRef();
void delRef();
void initData(const unsigned char* data, unsigned int length);
void addRef();
void delRef();
bool _useMalloc;
unsigned char* _data;
unsigned int _length;
static std::map<unsigned char*, int> refCounter;
bool _useMalloc;
unsigned char* _data;
unsigned int _length;
static std::map<unsigned char*, int> refCounter;
};
}
#endif

View File

@@ -30,54 +30,54 @@ namespace gourou
class Device
{
public:
static const int DEVICE_KEY_SIZE = 16;
static const int DEVICE_SERIAL_LEN = 10;
static const int DEVICE_KEY_SIZE = 16;
static const int DEVICE_SERIAL_LEN = 10;
/**
* @brief Main Device constructor
*
* @param processor Instance of DRMProcessor
* @param deviceFile Path of device.xml
* @param deviceKeyFile Path of devicesalt
*/
Device(DRMProcessor* processor, const std::string& deviceFile, const std::string& deviceKeyFile);
/**
* @brief Main Device constructor
*
* @param processor Instance of DRMProcessor
* @param deviceFile Path of device.xml
* @param deviceKeyFile Path of devicesalt
*/
Device(DRMProcessor* processor, const std::string& deviceFile, const std::string& deviceKeyFile);
/**
* @brief Return value of devicesalt file (DEVICE_KEY_SIZE len)
*/
const unsigned char* getDeviceKey();
/**
* @brief Return value of devicesalt file (DEVICE_KEY_SIZE len)
*/
const unsigned char* getDeviceKey();
/**
* @brief Get one value of device.xml (deviceClass, deviceSerial, deviceName, deviceType, hobbes, clientOS, clientLocale)
*/
std::string getProperty(const std::string& property, const std::string& _default=std::string(""));
std::string operator[](const std::string& property);
/**
* @brief Get one value of device.xml (deviceClass, deviceSerial, deviceName, deviceType, hobbes, clientOS, clientLocale)
*/
std::string getProperty(const std::string& property, const std::string& _default=std::string(""));
std::string operator[](const std::string& property);
/**
* @brief Create device.xml and devicesalt files when they did not exists
*
* @param processor Instance of DRMProcessor
* @param dirName Directory where to put files (.adept)
* @param hobbes Hobbes (client version) to set
* @param randomSerial Create a random serial (new device each time) or not (serial computed from machine specs)
*/
static Device* createDevice(DRMProcessor* processor, const std::string& dirName, const std::string& hobbes, bool randomSerial);
/**
* @brief Create device.xml and devicesalt files when they did not exists
*
* @param processor Instance of DRMProcessor
* @param dirName Directory where to put files (.adept)
* @param hobbes Hobbes (client version) to set
* @param randomSerial Create a random serial (new device each time) or not (serial computed from machine specs)
*/
static Device* createDevice(DRMProcessor* processor, const std::string& dirName, const std::string& hobbes, bool randomSerial);
private:
DRMProcessor* processor;
DRMProcessor* processor;
std::string deviceFile;
std::string deviceKeyFile;
unsigned char deviceKey[DEVICE_KEY_SIZE];
std::map<std::string, std::string> properties;
unsigned char deviceKey[DEVICE_KEY_SIZE];
std::map<std::string, std::string> properties;
Device(DRMProcessor* processor);
std::string makeFingerprint(const std::string& serial);
std::string makeSerial(bool random);
void parseDeviceFile();
void parseDeviceKeyFile();
void createDeviceFile(const std::string& hobbes, bool randomSerial);
void createDeviceKeyFile();
Device(DRMProcessor* processor);
std::string makeFingerprint(const std::string& serial);
std::string makeSerial(bool random);
void parseDeviceFile();
void parseDeviceKeyFile();
void createDeviceFile(const std::string& hobbes, bool randomSerial);
void createDeviceKeyFile();
};
}

View File

@@ -34,376 +34,376 @@ namespace gourou
class DigestInterface
{
public:
/**
* @brief Create a digest handler
*
* @param digestName Digest name to instanciate
*/
virtual void* createDigest(const std::string& digestName) = 0;
/**
* @brief Create a digest handler
*
* @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
*/
virtual void digestUpdate(void* handler, unsigned char* data, unsigned int length) = 0;
/**
* @brief Update digest engine with new data
*
* @param handler Digest handler
* @param data Data to digest
* @param length Length of data
*/
virtual void 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)
*/
virtual void digestFinalize(void* handler, unsigned char* digestOut) = 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)
*/
virtual void 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)
*/
virtual void digest(const std::string& digestName, unsigned char* data, unsigned int length, 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)
*/
virtual void 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;
/**
* @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
* @param responseHeaders Optional Response headers of HTTP request
* @param fd Optional file descriptor to write request result
* @param resume false if target file should be truncated, true to try resume download (works only in combination with a valid fd)
*
* @return data of HTTP response
*/
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""), std::map<std::string, std::string>* responseHeaders=0, int fd=0, bool resume=false) = 0;
/**
* @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
* @param responseHeaders Optional Response headers of HTTP request
* @param fd Optional file descriptor to write request result
* @param resume false if target file should be truncated, true to try resume download (works only in combination with a valid fd)
*
* @return data of HTTP response
*/
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""), std::map<std::string, std::string>* responseHeaders=0, int fd=0, bool resume=false) = 0;
};
class RSAInterface
{
public:
enum RSA_KEY_TYPE {
RSA_KEY_PKCS12 = 0,
RSA_KEY_PKCS8,
RSA_KEY_X509
};
enum RSA_KEY_TYPE {
RSA_KEY_PKCS12 = 0,
RSA_KEY_PKCS8,
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 Decrypt 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 RSAPrivateDecrypt(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 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 Decrypt 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 RSAPrivateDecrypt(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 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 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 Destroy key previously generated
*
* @param handler Key to destroy
*/
virtual void destroyRSAHandler(void* handler) = 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 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 Destroy key previously generated
*
* @param handler Key to destroy
*/
virtual void destroyRSAHandler(void* handler) = 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;
/**
* @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 certificate from PKCS12 blob
*
* @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 certOut Result certificate
* @param certOutLength Result certificate length
*/
virtual void extractCertificate(const unsigned char* RSAKey, unsigned int RSAKeyLength,
const RSA_KEY_TYPE keyType, const std::string& password,
unsigned char** certOut, unsigned int* certOutLength) = 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;
/**
* @brief Extract certificate from PKCS12 blob
*
* @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 certOut Result certificate
* @param certOutLength Result certificate length
*/
virtual void extractCertificate(const unsigned char* RSAKey, unsigned int RSAKeyLength,
const RSA_KEY_TYPE keyType, const std::string& password,
unsigned char** certOut, unsigned int* certOutLength) = 0;
};
class CryptoInterface
{
public:
enum CRYPTO_ALGO {
ALGO_AES=0,
ALGO_RC4
};
enum CRYPTO_ALGO {
ALGO_AES=0,
ALGO_RC4
};
enum CHAINING_MODE {
CHAIN_ECB=0,
CHAIN_CBC
};
/**
* @brief Do encryption. If length of data is not multiple of block size, PKCS#5 padding is done
*
* @param algo Algorithm to use
* @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 encrypt(CRYPTO_ALGO algo, 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;
enum CHAINING_MODE {
CHAIN_ECB=0,
CHAIN_CBC
};
/**
* @brief Init encryption
*
* @param chaining Chaining mode
* @param key Key
* @param keyLength Key length
* @param iv Optional IV key
* @param ivLength Optional IV key length
*
* @return AES handler
*/
virtual void* encryptInit(CRYPTO_ALGO algo, CHAINING_MODE chaining,
const unsigned char* key, unsigned int keyLength,
const unsigned char* iv=0, unsigned int ivLength=0) = 0;
/**
* @brief Do encryption. If length of data is not multiple of block size, PKCS#5 padding is done
*
* @param algo Algorithm to use
* @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 encrypt(CRYPTO_ALGO algo, 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 Encrypt data
*
* @param handler Crypto handler
* @param dataIn Data to encrypt
* @param dataInLength Data length
* @param dataOut Encrypted data
* @param dataOutLength Length of encrypted data
*/
virtual void encryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Init encryption
*
* @param chaining Chaining mode
* @param key Key
* @param keyLength Key length
* @param iv Optional IV key
* @param ivLength Optional IV key length
*
* @return AES handler
*/
virtual void* encryptInit(CRYPTO_ALGO algo, CHAINING_MODE chaining,
const unsigned char* key, unsigned int keyLength,
const unsigned char* iv=0, unsigned int ivLength=0) = 0;
/**
* @brief Finalize encryption (pad and encrypt last block if needed)
* Destroy handler at the end
*
* @param handler Crypto handler
* @param dataOut Last block of encrypted data
* @param dataOutLength Length of encrypted data
*/
virtual void encryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Encrypt data
*
* @param handler Crypto handler
* @param dataIn Data to encrypt
* @param dataInLength Data length
* @param dataOut Encrypted data
* @param dataOutLength Length of encrypted data
*/
virtual void encryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Do decryption. If length of data is not multiple of block size, PKCS#5 padding is done
*
* @param algo Algorithm to use
* @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 decrypt(CRYPTO_ALGO algo, 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 Finalize encryption (pad and encrypt last block if needed)
* Destroy handler at the end
*
* @param handler Crypto handler
* @param dataOut Last block of encrypted data
* @param dataOutLength Length of encrypted data
*/
virtual void encryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Init decryption
*
* @param chaining Chaining mode
* @param key Key
* @param keyLength Key length
* @param iv IV key
* @param ivLength IV key length
*
* @return AES handler
*/
virtual void* decryptInit(CRYPTO_ALGO algo, CHAINING_MODE chaining,
const unsigned char* key, unsigned int keyLength,
const unsigned char* iv=0, unsigned int ivLength=0) = 0;
/**
* @brief Do decryption. If length of data is not multiple of block size, PKCS#5 padding is done
*
* @param algo Algorithm to use
* @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 decrypt(CRYPTO_ALGO algo, 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 Decrypt data
*
* @param handler Crypto handler
* @param dataIn Data to decrypt
* @param dataInLength Data length
* @param dataOut Decrypted data
* @param dataOutLength Length of decrypted data
*/
virtual void decryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Finalize decryption (decrypt last block and remove padding if it is set).
* Destroy handler at the end
*
* @param handler Crypto handler
* @param dataOut Last block decrypted data
* @param dataOutLength Length of decrypted data
*/
virtual void decryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Init decryption
*
* @param chaining Chaining mode
* @param key Key
* @param keyLength Key length
* @param iv IV key
* @param ivLength IV key length
*
* @return AES handler
*/
virtual void* decryptInit(CRYPTO_ALGO algo, 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 Crypto handler
* @param dataIn Data to decrypt
* @param dataInLength Data length
* @param dataOut Decrypted data
* @param dataOutLength Length of decrypted data
*/
virtual void decryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
unsigned char* dataOut, unsigned int* dataOutLength) = 0;
/**
* @brief Finalize decryption (decrypt last block and remove padding if it is set).
* Destroy handler at the end
*
* @param handler Crypto handler
* @param dataOut Last block decrypted data
* @param dataOutLength Length of decrypted data
*/
virtual void decryptFinalize(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
* @param result Result buffer
* @param decompress If false, don't decompress read data
*/
virtual void zipReadFile(void* handler, const std::string& path, ByteArray& result, bool decompress=true) = 0;
/**
* @brief Write zip internal file
*
* @param handler ZIP file handler
* @param path Internal path inside zip file
* @param content File content
*/
virtual void zipWriteFile(void* handler, const std::string& path, ByteArray& content) = 0;
/**
* @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 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 Read zip internal file
*
* @param handler ZIP file handler
* @param path Internal path inside zip file
* @param result Result buffer
* @param decompress If false, don't decompress read data
*/
virtual void zipReadFile(void* handler, const std::string& path, ByteArray& result, bool decompress=true) = 0;
/**
* @brief Close ZIP file handler
*
* @param handler ZIP file handler
*/
virtual void zipClose(void* handler) = 0;
/**
* @brief Write zip internal file
*
* @param handler ZIP file handler
* @param path Internal path inside zip file
* @param content File content
*/
virtual void zipWriteFile(void* handler, const std::string& path, ByteArray& content) = 0;
/**
* @brief Inflate algorithm
*
* @param data Data to inflate
* @param result Zipped data
* @param wbits Window bits value for libz
*/
virtual void inflate(gourou::ByteArray& data, gourou::ByteArray& result,
int wbits=-15) = 0;
/**
* @brief Deflate algorithm
*
* @param data Data to deflate
* @param result Unzipped data
* @param wbits Window bits value for libz
* @param compressionLevel Compression level for libz
*/
virtual void deflate(gourou::ByteArray& data, gourou::ByteArray& result,
int wbits=-15, int compressionLevel=8) = 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;
/**
* @brief Inflate algorithm
*
* @param data Data to inflate
* @param result Zipped data
* @param wbits Window bits value for libz
*/
virtual void inflate(gourou::ByteArray& data, gourou::ByteArray& result,
int wbits=-15) = 0;
/**
* @brief Deflate algorithm
*
* @param data Data to deflate
* @param result Unzipped data
* @param wbits Window bits value for libz
* @param compressionLevel Compression level for libz
*/
virtual void deflate(gourou::ByteArray& data, gourou::ByteArray& result,
int wbits=-15, int compressionLevel=8) = 0;
};
class DRMProcessorClient: public DigestInterface, public RandomInterface, public HTTPInterface, \
public RSAInterface, public CryptoInterface, public ZIPInterface
public RSAInterface, public CryptoInterface, public ZIPInterface
{};
}
#endif

View File

@@ -34,52 +34,52 @@ namespace gourou
class FulfillmentItem
{
public:
/**
* @brief Main constructor. Not to be called by user
*
* @param doc Fulfill reply
* @param user User pointer
*/
FulfillmentItem(pugi::xml_document& doc, User* user);
/**
* @brief Main constructor. Not to be called by user
*
* @param doc Fulfill reply
* @param user User pointer
*/
FulfillmentItem(pugi::xml_document& doc, User* user);
~FulfillmentItem();
~FulfillmentItem();
/**
* @brief Return metadata value from ACSM metadata section
*
* @param name Name of key to return
*/
std::string getMetadata(std::string name);
/**
* @brief Return metadata value from ACSM metadata section
*
* @param name Name of key to return
*/
std::string getMetadata(std::string name);
/**
* @brief Return rights generated by ACS server (XML format)
*/
std::string getRights();
/**
* @brief Return rights generated by ACS server (XML format)
*/
std::string getRights();
/**
* @brief Return epub download URL
*/
std::string getDownloadURL();
/**
* @brief Return epub download URL
*/
std::string getDownloadURL();
/**
* @brief Return resource value
*/
std::string getResource();
/**
* @brief Return resource value
*/
std::string getResource();
/**
* @brief Return loan token if there is one
*/
LoanToken* getLoanToken();
/**
* @brief Return loan token if there is one
*/
LoanToken* getLoanToken();
private:
pugi::xml_document fulfillDoc;
pugi::xml_node metadatas;
pugi::xml_document rights;
std::string downloadURL;
std::string resource;
LoanToken* loanToken;
void buildRights(const pugi::xml_node& licenseToken, User* user);
pugi::xml_document fulfillDoc;
pugi::xml_node metadatas;
pugi::xml_document rights;
std::string downloadURL;
std::string resource;
LoanToken* loanToken;
void buildRights(const pugi::xml_node& licenseToken, User* user);
};
}

View File

@@ -48,204 +48,204 @@ namespace gourou
{
public:
static const std::string VERSION;
static const std::string VERSION;
enum ITEM_TYPE { EPUB=0, PDF };
/**
* @brief Main constructor. To be used once all is configured (user has signedIn, device is activated)
*
* @param client Client processor
* @param deviceFile Path of device.xml
* @param activationFile Path of activation.xml
* @param deviceKeyFile Path of devicesalt
*/
enum ITEM_TYPE { EPUB=0, PDF };
/**
* @brief Main constructor. To be used once all is configured (user has signedIn, device is activated)
*
* @param client Client processor
* @param deviceFile Path of device.xml
* @param activationFile Path of activation.xml
* @param deviceKeyFile Path of devicesalt
*/
DRMProcessor(DRMProcessorClient* client, const std::string& deviceFile, const std::string& activationFile, const std::string& deviceKeyFile);
~DRMProcessor();
/**
* @brief Fulfill ACSM file to server in order to retrieve ePub fulfillment item
*
* @param ACSMFile Path of ACSMFile
* @param notify Notify server if requested by response
*
* @return a FulfillmentItem if all is OK
*/
FulfillmentItem* fulfill(const std::string& ACSMFile, bool notify=true);
~DRMProcessor();
/**
* @brief Once fulfilled, ePub file needs to be downloaded.
* During this operation, DRM information is added into downloaded file
*
* @param item Item from fulfill() method
* @param path Output file path
* @param resume false if target file should be truncated, true to try resume download
*
* @return Type of downloaded item
*/
ITEM_TYPE download(FulfillmentItem* item, std::string path, bool resume=false);
/**
* @brief Fulfill ACSM file to server in order to retrieve ePub fulfillment item
*
* @param ACSMFile Path of ACSMFile
* @param notify Notify server if requested by response
*
* @return a FulfillmentItem if all is OK
*/
FulfillmentItem* fulfill(const std::string& ACSMFile, bool notify=true);
/**
* @brief SignIn into ACS Server (required to activate device)
*
* @param adobeID AdobeID username
* @param adobePassword Adobe password
*/
void signIn(const std::string& adobeID, const std::string& adobePassword);
/**
* @brief Once fulfilled, ePub file needs to be downloaded.
* During this operation, DRM information is added into downloaded file
*
* @param item Item from fulfill() method
* @param path Output file path
* @param resume false if target file should be truncated, true to try resume download
*
* @return Type of downloaded item
*/
ITEM_TYPE download(FulfillmentItem* item, std::string path, bool resume=false);
/**
* @brief Activate newly created device (user must have successfuly signedIn before)
*/
void activateDevice();
/**
* @brief SignIn into ACS Server (required to activate device)
*
* @param adobeID AdobeID username
* @param adobePassword Adobe password
*/
void signIn(const std::string& adobeID, const std::string& adobePassword);
/**
* @brief Return loaned book to server
*
* @param loanID Loan ID received during fulfill
* @param operatorURL URL of operator that loans this book
* @param notify Notify server if requested by response
*/
void returnLoan(const std::string& loanID, const std::string& operatorURL, bool notify=true);
/**
* @brief Activate newly created device (user must have successfuly signedIn before)
*/
void activateDevice();
/**
* @brief Return default ADEPT directory (ie /home/<user>/.config/adept)
*/
static std::string getDefaultAdeptDir(void);
/**
* @brief Create a new ADEPT environment (device.xml, devicesalt and activation.xml).
*
* @param client Client processor
* @param randomSerial Always generate a new device (or not)
* @param dirName Directory where to put generated files (.adept)
* @param hobbes Override hobbes default version
* @param ACSServer Override main ACS server (default adeactivate.adobe.com)
*/
/**
* @brief Return loaned book to server
*
* @param loanID Loan ID received during fulfill
* @param operatorURL URL of operator that loans this book
* @param notify Notify server if requested by response
*/
void returnLoan(const std::string& loanID, const std::string& operatorURL, bool notify=true);
/**
* @brief Return default ADEPT directory (ie /home/<user>/.config/adept)
*/
static std::string getDefaultAdeptDir(void);
/**
* @brief Create a new ADEPT environment (device.xml, devicesalt and activation.xml).
*
* @param client Client processor
* @param randomSerial Always generate a new device (or not)
* @param dirName Directory where to put generated files (.adept)
* @param hobbes Override hobbes default version
* @param ACSServer Override main ACS server (default adeactivate.adobe.com)
*/
static DRMProcessor* createDRMProcessor(DRMProcessorClient* client,
bool randomSerial=false, std::string dirName=std::string(""),
const std::string& hobbes=std::string(HOBBES_DEFAULT_VERSION),
const std::string& ACSServer=ACS_SERVER);
bool randomSerial=false, std::string dirName=std::string(""),
const std::string& hobbes=std::string(HOBBES_DEFAULT_VERSION),
const std::string& ACSServer=ACS_SERVER);
/**
* @brief Get current log level
*/
static int getLogLevel();
/**
* @brief Get current log level
*/
static int getLogLevel();
/**
* @brief Set log level (higher number for verbose output)
*/
static void setLogLevel(int logLevel);
/**
* @brief Set log level (higher number for verbose output)
*/
static void setLogLevel(int logLevel);
/**
* Functions used internally, should not be called by user
*/
/**
* Functions used internally, should not be called by user
*/
/**
* @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
* @param responseHeaders Optional Response headers of HTTP request
* @param fd Optional File descriptor to write received data
* @param resume false if target file should be truncated, true to try resume download (works only in combination of a valid fd)
*
* @return data of HTTP response
*/
ByteArray sendRequest(const std::string& URL, const std::string& POSTData=std::string(), const char* contentType=0, std::map<std::string, std::string>* responseHeaders=0, int fd=0, bool resume=false);
/**
* @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
* @param responseHeaders Optional Response headers of HTTP request
* @param fd Optional File descriptor to write received data
* @param resume false if target file should be truncated, true to try resume download (works only in combination of a valid fd)
*
* @return data of HTTP response
*/
ByteArray sendRequest(const std::string& URL, const std::string& POSTData=std::string(), const char* contentType=0, std::map<std::string, std::string>* responseHeaders=0, int fd=0, bool resume=false);
/**
* @brief Send HTTP POST request to URL with document as POSTData
*/
ByteArray sendRequest(const pugi::xml_document& document, const std::string& url);
/**
* @brief In place encrypt data with private device key
*/
ByteArray encryptWithDeviceKey(const unsigned char* data, unsigned int len);
/**
* @brief Send HTTP POST request to URL with document as POSTData
*/
ByteArray sendRequest(const pugi::xml_document& document, const std::string& url);
/**
* @brief In place decrypt data with private device key
*/
ByteArray decryptWithDeviceKey(const unsigned char* data, unsigned int len);
/**
* @brief In place encrypt data with private device key
*/
ByteArray encryptWithDeviceKey(const unsigned char* data, unsigned int len);
/**
* @brief Return base64 encoded value of RSA public key
*/
std::string serializeRSAPublicKey(void* rsa);
/**
* @brief In place decrypt data with private device key
*/
ByteArray decryptWithDeviceKey(const unsigned char* data, unsigned int len);
/**
* @brief Return base64 encoded value of RSA private key encrypted with private device key
*/
std::string serializeRSAPrivateKey(void* rsa);
/**
* @brief Return base64 encoded value of RSA public key
*/
std::string serializeRSAPublicKey(void* rsa);
/**
* @brief Export clear private license key into path
*/
void exportPrivateLicenseKey(std::string path);
/**
* @brief Get current user
*/
User* getUser() { return user; }
/**
* @brief Return base64 encoded value of RSA private key encrypted with private device key
*/
std::string serializeRSAPrivateKey(void* rsa);
/**
* @brief Get current device
*/
Device* getDevice() { return device; }
/**
* @brief Export clear private license key into path
*/
void exportPrivateLicenseKey(std::string path);
/**
* @brief Get current user
*/
User* getUser() { return user; }
/**
* @brief Get current device
*/
Device* getDevice() { return device; }
/**
* @brief Get current client
*/
DRMProcessorClient* getClient() { return client; }
/**
* @brief Remove ADEPT DRM
* Warning: for PDF format, filenameIn must be different than filenameOut
*
* @param filenameIn Input file (with ADEPT DRM)
* @param filenameOut Output file (without ADEPT DRM)
* @param type Type of file (ePub or PDF)
* @param encryptionKey Optional encryption key, do not try to decrypt the one inside input file
* @param encryptionKeySize Size of encryption key (if provided)
*/
void removeDRM(const std::string& filenameIn, const std::string& filenameOut, ITEM_TYPE type, const unsigned char* encryptionKey=0, unsigned encryptionKeySize=0);
/**
* @brief Get current client
*/
DRMProcessorClient* getClient() { return client; }
/**
* @brief Remove ADEPT DRM
* Warning: for PDF format, filenameIn must be different than filenameOut
*
* @param filenameIn Input file (with ADEPT DRM)
* @param filenameOut Output file (without ADEPT DRM)
* @param type Type of file (ePub or PDF)
* @param encryptionKey Optional encryption key, do not try to decrypt the one inside input file
* @param encryptionKeySize Size of encryption key (if provided)
*/
void removeDRM(const std::string& filenameIn, const std::string& filenameOut, ITEM_TYPE type, const unsigned char* encryptionKey=0, unsigned encryptionKeySize=0);
private:
gourou::DRMProcessorClient* client;
gourou::DRMProcessorClient* client;
gourou::Device* device;
gourou::User* user;
DRMProcessor(DRMProcessorClient* client);
void pushString(void* sha_ctx, const std::string& string);
void pushTag(void* sha_ctx, uint8_t tag);
void hashNode(const pugi::xml_node& root, void *sha_ctx, std::map<std::string,std::string> nsHash);
void hashNode(const pugi::xml_node& root, unsigned char* sha_out);
void signNode(pugi::xml_node& rootNode);
void addNonce(pugi::xml_node& root);
void buildAuthRequest(pugi::xml_document& authReq);
void buildInitLicenseServiceRequest(pugi::xml_document& initLicReq, std::string operatorURL);
void doOperatorAuth(std::string operatorURL);
void operatorAuth(std::string operatorURL);
void buildFulfillRequest(pugi::xml_document& acsmDoc, pugi::xml_document& fulfillReq);
void buildActivateReq(pugi::xml_document& activateReq);
void buildReturnReq(pugi::xml_document& returnReq, const std::string& loanID, const std::string& operatorURL);
ByteArray sendFulfillRequest(const pugi::xml_document& document, const std::string& url);
void buildSignInRequest(pugi::xml_document& signInRequest, const std::string& adobeID, const std::string& adobePassword, const std::string& authenticationCertificate);
void fetchLicenseServiceCertificate(const std::string& licenseURL,
const std::string& operatorURL);
void buildNotifyReq(pugi::xml_document& returnReq, pugi::xml_node& body);
void notifyServer(pugi::xml_node& notifyRoot);
void notifyServer(pugi::xml_document& fulfillReply);
std::string encryptedKeyFirstPass(pugi::xml_document& rightsDoc, const std::string& encryptedKey, const std::string& keyType);
void decryptADEPTKey(pugi::xml_document& rightsDoc, unsigned char* decryptedKey, const unsigned char* encryptionKey=0, unsigned encryptionKeySize=0);
void removeEPubDRM(const std::string& filenameIn, const std::string& filenameOut, const unsigned char* encryptionKey, unsigned encryptionKeySize);
void generatePDFObjectKey(int version,
const unsigned char* masterKey, unsigned int masterKeyLength,
int objectId, int objectGenerationNumber,
unsigned char* keyOut);
void removePDFDRM(const std::string& filenameIn, const std::string& filenameOut, const unsigned char* encryptionKey, unsigned encryptionKeySize);
void pushString(void* sha_ctx, const std::string& string);
void pushTag(void* sha_ctx, uint8_t tag);
void hashNode(const pugi::xml_node& root, void *sha_ctx, std::map<std::string,std::string> nsHash);
void hashNode(const pugi::xml_node& root, unsigned char* sha_out);
void signNode(pugi::xml_node& rootNode);
void addNonce(pugi::xml_node& root);
void buildAuthRequest(pugi::xml_document& authReq);
void buildInitLicenseServiceRequest(pugi::xml_document& initLicReq, std::string operatorURL);
void doOperatorAuth(std::string operatorURL);
void operatorAuth(std::string operatorURL);
void buildFulfillRequest(pugi::xml_document& acsmDoc, pugi::xml_document& fulfillReq);
void buildActivateReq(pugi::xml_document& activateReq);
void buildReturnReq(pugi::xml_document& returnReq, const std::string& loanID, const std::string& operatorURL);
ByteArray sendFulfillRequest(const pugi::xml_document& document, const std::string& url);
void buildSignInRequest(pugi::xml_document& signInRequest, const std::string& adobeID, const std::string& adobePassword, const std::string& authenticationCertificate);
void fetchLicenseServiceCertificate(const std::string& licenseURL,
const std::string& operatorURL);
void buildNotifyReq(pugi::xml_document& returnReq, pugi::xml_node& body);
void notifyServer(pugi::xml_node& notifyRoot);
void notifyServer(pugi::xml_document& fulfillReply);
std::string encryptedKeyFirstPass(pugi::xml_document& rightsDoc, const std::string& encryptedKey, const std::string& keyType);
void decryptADEPTKey(pugi::xml_document& rightsDoc, unsigned char* decryptedKey, const unsigned char* encryptionKey=0, unsigned encryptionKeySize=0);
void removeEPubDRM(const std::string& filenameIn, const std::string& filenameOut, const unsigned char* encryptionKey, unsigned encryptionKeySize);
void generatePDFObjectKey(int version,
const unsigned char* masterKey, unsigned int masterKeyLength,
int objectId, int objectGenerationNumber,
unsigned char* keyOut);
void removePDFDRM(const std::string& filenameIn, const std::string& filenameOut, const unsigned char* encryptionKey, unsigned encryptionKeySize);
};
}

View File

@@ -43,152 +43,152 @@ namespace gourou
/**
* Some common utilities
*/
#define ADOBE_ADEPT_NS "http://ns.adobe.com/adept"
#define ADOBE_ADEPT_NS "http://ns.adobe.com/adept"
static const int SHA1_LEN = 20;
static const int RSA_KEY_SIZE = 128;
static const int RSA_KEY_SIZE_BITS = (RSA_KEY_SIZE*8);
enum GOUROU_ERROR {
GOUROU_DEVICE_DOES_NOT_MATCH = 0x1000,
GOUROU_INVALID_CLIENT,
GOUROU_TAG_NOT_FOUND,
GOUROU_ADEPT_ERROR,
GOUROU_FILE_ERROR,
GOUROU_INVALID_PROPERTY
GOUROU_DEVICE_DOES_NOT_MATCH = 0x1000,
GOUROU_INVALID_CLIENT,
GOUROU_TAG_NOT_FOUND,
GOUROU_ADEPT_ERROR,
GOUROU_FILE_ERROR,
GOUROU_INVALID_PROPERTY
};
enum FULFILL_ERROR {
FF_ACSM_FILE_NOT_EXISTS = 0x1100,
FF_INVALID_ACSM_FILE,
FF_NO_HMAC_IN_ACSM_FILE,
FF_NOT_ACTIVATED,
FF_NO_OPERATOR_URL,
FF_SERVER_INTERNAL_ERROR
FF_ACSM_FILE_NOT_EXISTS = 0x1100,
FF_INVALID_ACSM_FILE,
FF_NO_HMAC_IN_ACSM_FILE,
FF_NOT_ACTIVATED,
FF_NO_OPERATOR_URL,
FF_SERVER_INTERNAL_ERROR
};
enum DOWNLOAD_ERROR {
DW_NO_ITEM = 0x1200,
DW_NO_EBX_HANDLER,
DW_NO_ITEM = 0x1200,
DW_NO_EBX_HANDLER,
};
enum SIGNIN_ERROR {
SIGN_INVALID_CREDENTIALS = 0x1300,
SIGN_INVALID_CREDENTIALS = 0x1300,
};
enum ACTIVATE_ERROR {
ACTIVATE_NOT_SIGNEDIN = 0x1400
ACTIVATE_NOT_SIGNEDIN = 0x1400
};
enum DEV_ERROR {
DEV_MKPATH = 0x2000,
DEV_MAC_ERROR,
DEV_INVALID_DEVICE_FILE,
DEV_INVALID_DEVICE_KEY_FILE,
DEV_INVALID_DEV_PROPERTY,
DEV_MKPATH = 0x2000,
DEV_MAC_ERROR,
DEV_INVALID_DEVICE_FILE,
DEV_INVALID_DEVICE_KEY_FILE,
DEV_INVALID_DEV_PROPERTY,
};
enum USER_ERROR {
USER_MKPATH = 0x3000,
USER_INVALID_ACTIVATION_FILE,
USER_NO_AUTHENTICATION_URL,
USER_NO_PROPERTY,
USER_INVALID_INPUT,
USER_MKPATH = 0x3000,
USER_INVALID_ACTIVATION_FILE,
USER_NO_AUTHENTICATION_URL,
USER_NO_PROPERTY,
USER_INVALID_INPUT,
};
enum FULFILL_ITEM_ERROR {
FFI_INVALID_FULFILLMENT_DATA = 0x4000,
FFI_INVALID_LOAN_TOKEN
FFI_INVALID_FULFILLMENT_DATA = 0x4000,
FFI_INVALID_LOAN_TOKEN
};
enum CLIENT_ERROR {
CLIENT_BAD_PARAM = 0x5000,
CLIENT_INVALID_PKCS12,
CLIENT_INVALID_CERTIFICATE,
CLIENT_NO_PRIV_KEY,
CLIENT_NO_PUB_KEY,
CLIENT_RSA_ERROR,
CLIENT_BAD_CHAINING,
CLIENT_BAD_KEY_SIZE,
CLIENT_BAD_ZIP_FILE,
CLIENT_ZIP_ERROR,
CLIENT_GENERIC_EXCEPTION,
CLIENT_NETWORK_ERROR,
CLIENT_INVALID_PKCS8,
CLIENT_FILE_ERROR,
CLIENT_OSSL_ERROR,
CLIENT_CRYPT_ERROR,
CLIENT_DIGEST_ERROR,
CLIENT_HTTP_ERROR
CLIENT_BAD_PARAM = 0x5000,
CLIENT_INVALID_PKCS12,
CLIENT_INVALID_CERTIFICATE,
CLIENT_NO_PRIV_KEY,
CLIENT_NO_PUB_KEY,
CLIENT_RSA_ERROR,
CLIENT_BAD_CHAINING,
CLIENT_BAD_KEY_SIZE,
CLIENT_BAD_ZIP_FILE,
CLIENT_ZIP_ERROR,
CLIENT_GENERIC_EXCEPTION,
CLIENT_NETWORK_ERROR,
CLIENT_INVALID_PKCS8,
CLIENT_FILE_ERROR,
CLIENT_OSSL_ERROR,
CLIENT_CRYPT_ERROR,
CLIENT_DIGEST_ERROR,
CLIENT_HTTP_ERROR
};
enum DRM_REMOVAL_ERROR {
DRM_ERR_ENCRYPTION_KEY = 0x6000,
DRM_VERSION_NOT_SUPPORTED,
DRM_FILE_ERROR,
DRM_FORMAT_NOT_SUPPORTED,
DRM_IN_OUT_EQUALS,
DRM_MISSING_PARAMETER,
DRM_INVALID_KEY_SIZE,
DRM_ERR_ENCRYPTION_KEY_FP,
DRM_INVALID_USER
DRM_ERR_ENCRYPTION_KEY = 0x6000,
DRM_VERSION_NOT_SUPPORTED,
DRM_FILE_ERROR,
DRM_FORMAT_NOT_SUPPORTED,
DRM_IN_OUT_EQUALS,
DRM_MISSING_PARAMETER,
DRM_INVALID_KEY_SIZE,
DRM_ERR_ENCRYPTION_KEY_FP,
DRM_INVALID_USER
};
#ifndef _NOEXCEPT
#if __STDC_VERSION__ >= 201112L
# define _NOEXCEPT noexcept
# define _NOEXCEPT_(x) noexcept(x)
#else
# define _NOEXCEPT throw()
# define _NOEXCEPT_(x)
#endif
#endif /* !_NOEXCEPT */
#ifndef _NOEXCEPT
#if __STDC_VERSION__ >= 201112L
# define _NOEXCEPT noexcept
# define _NOEXCEPT_(x) noexcept(x)
#else
# define _NOEXCEPT throw()
# define _NOEXCEPT_(x)
#endif
#endif /* !_NOEXCEPT */
/**
* Generic exception class
*/
class Exception : public std::exception
{
public:
Exception(int code, const char* message, const char* file, int line):
code(code), line(line), file(file)
{
std::stringstream msg;
msg << "Exception code : 0x" << std::setbase(16) << code << std::endl;
msg << "Message : " << message << std::endl;
if (logLevel >= LG_LOG_DEBUG)
msg << "File : " << file << ":" << std::setbase(10) << line << std::endl;
fullmessage = strdup(msg.str().c_str());
}
Exception(int code, const char* message, const char* file, int line):
code(code), line(line), file(file)
{
std::stringstream msg;
msg << "Exception code : 0x" << std::setbase(16) << code << std::endl;
msg << "Message : " << message << std::endl;
if (logLevel >= LG_LOG_DEBUG)
msg << "File : " << file << ":" << std::setbase(10) << line << std::endl;
fullmessage = strdup(msg.str().c_str());
}
Exception(const Exception& other)
{
this->code = other.code;
this->line = line;
this->file = file;
this->fullmessage = strdup(other.fullmessage);
}
Exception(const Exception& other)
{
this->code = other.code;
this->line = line;
this->file = file;
this->fullmessage = strdup(other.fullmessage);
}
~Exception() _NOEXCEPT
{
free(fullmessage);
}
~Exception() _NOEXCEPT
{
free(fullmessage);
}
const char * what () const throw () { return fullmessage; }
int getErrorCode() {return code;}
private:
int code, line;
const char* message, *file;
char* fullmessage;
const char * what () const throw () { return fullmessage; }
int getErrorCode() {return code;}
private:
int code, line;
const char* message, *file;
char* fullmessage;
};
/**
* @brief Throw an exception
*/
#define EXCEPTION(code, message) \
#define EXCEPTION(code, message) \
{std::stringstream __msg;__msg << message; throw gourou::Exception(code, __msg.str().c_str(), __FILE__, __LINE__);}
/**
@@ -197,15 +197,15 @@ namespace gourou
class StringXMLWriter : public pugi::xml_writer
{
public:
virtual void write(const void* data, size_t size)
{
result.append(static_cast<const char*>(data), size);
}
virtual void write(const void* data, size_t size)
{
result.append(static_cast<const char*>(data), size);
}
const std::string& getResult() {return result;}
const std::string& getResult() {return result;}
private:
std::string result;
std::string result;
};
static const char* ws = " \t\n\r\f\v";
@@ -215,8 +215,8 @@ namespace gourou
*/
inline std::string& rtrim(std::string& s, const char* t = ws)
{
s.erase(s.find_last_not_of(t) + 1);
return s;
s.erase(s.find_last_not_of(t) + 1);
return s;
}
/**
@@ -224,8 +224,8 @@ namespace gourou
*/
inline std::string& ltrim(std::string& s, const char* t = ws)
{
s.erase(0, s.find_first_not_of(t));
return s;
s.erase(0, s.find_first_not_of(t));
return s;
}
/**
@@ -233,7 +233,7 @@ namespace gourou
*/
inline std::string& trim(std::string& s, const char* t = ws)
{
return ltrim(rtrim(s, t), t);
return ltrim(rtrim(s, t), t);
}
static inline pugi::xml_node getNode(const pugi::xml_node& root, const char* tagName, bool throwOnNull=true)
@@ -241,17 +241,17 @@ namespace gourou
pugi::xpath_node xpath_node = root.select_node(tagName);
if (!xpath_node)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Tag " << tagName << " not found");
return pugi::xml_node();
}
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Tag " << tagName << " not found");
return xpath_node.node();
return pugi::xml_node();
}
return xpath_node.node();
}
/**
* @brief Extract text node from tag in document
* It can throw an exception if tag does not exists
@@ -259,19 +259,19 @@ namespace gourou
*/
static inline std::string extractTextElem(const pugi::xml_node& root, const char* tagName, bool throwOnNull=true)
{
pugi::xml_node node = getNode(root, tagName, throwOnNull);
pugi::xml_node node = getNode(root, tagName, throwOnNull);
node = node.first_child();
node = node.first_child();
if (!node)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Text element for tag " << tagName << " not found");
if (!node)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Text element for tag " << tagName << " not found");
return "";
}
}
std::string res = node.value();
std::string res = node.value();
return trim(res);
}
@@ -280,23 +280,23 @@ namespace gourou
* It can throw an exception if tag does not exists
*/
static inline void setTextElem(const pugi::xml_node& root, const char* tagName,
const std::string& value, bool throwOnNull=true)
const std::string& value, bool throwOnNull=true)
{
pugi::xml_node node = getNode(root, tagName, throwOnNull);
pugi::xml_node node = getNode(root, tagName, throwOnNull);
if (!node)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Text element for tag " << tagName << " not found");
if (!node)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Text element for tag " << tagName << " not found");
return;
}
}
node = node.first_child();
node = node.first_child();
if (!node)
node.append_child(pugi::node_pcdata).set_value(value.c_str());
else
node.set_value(value.c_str());
if (!node)
node.append_child(pugi::node_pcdata).set_value(value.c_str());
else
node.set_value(value.c_str());
}
/**
@@ -306,20 +306,20 @@ namespace gourou
*/
static inline std::string extractTextAttribute(const pugi::xml_node& root, const char* tagName, const char* attributeName, bool throwOnNull=true)
{
pugi::xml_node node = getNode(root, tagName, throwOnNull);
pugi::xml_node node = getNode(root, tagName, throwOnNull);
pugi::xml_attribute attr = node.attribute(attributeName);
pugi::xml_attribute attr = node.attribute(attributeName);
if (!attr)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Attribute element " << attributeName << " for tag " << tagName << " not found");
if (!attr)
{
if (throwOnNull)
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Attribute element " << attributeName << " for tag " << tagName << " not found");
return "";
}
}
std::string res = attr.value();
return trim(res);
std::string res = attr.value();
return trim(res);
}
/**
@@ -331,8 +331,8 @@ namespace gourou
*/
static inline void appendTextElem(pugi::xml_node& root, const std::string& name, const std::string& value)
{
pugi::xml_node node = root.append_child(name.c_str());
node.append_child(pugi::node_pcdata).set_value(value.c_str());
pugi::xml_node node = root.append_child(name.c_str());
node.append_child(pugi::node_pcdata).set_value(value.c_str());
}
/**
@@ -343,21 +343,21 @@ namespace gourou
*/
static inline std::string extractIdFromUUID(const std::string& uuid)
{
unsigned int i = 0;
std::string res;
if (uuid.find("urn:uuid:") == 0)
i = 9;
unsigned int i = 0;
std::string res;
for(; i<uuid.size(); i++)
{
if (uuid[i] != '-')
res += uuid[i];
}
if (uuid.find("urn:uuid:") == 0)
i = 9;
return res;
for(; i<uuid.size(); i++)
{
if (uuid[i] != '-')
res += uuid[i];
}
return res;
}
/**
* @brief Open a file descriptor on path. If it already exists and truncate == true, it's truncated
*
@@ -365,31 +365,31 @@ namespace gourou
*/
static inline int createNewFile(std::string path, bool truncate=true)
{
int options = O_CREAT|O_WRONLY;
if (truncate)
options |= O_TRUNC;
else
options |= O_APPEND;
int options = O_CREAT|O_WRONLY;
if (truncate)
options |= O_TRUNC;
else
options |= O_APPEND;
int fd = open(path.c_str(), options, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
int fd = open(path.c_str(), options, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
if (fd <= 0)
EXCEPTION(GOUROU_FILE_ERROR, "Unable to create " << path);
if (fd <= 0)
EXCEPTION(GOUROU_FILE_ERROR, "Unable to create " << path);
return fd;
return fd;
}
/**
* @brief Write data in a file. If it already exists, it's truncated
*/
static inline void writeFile(std::string path, const unsigned char* data, unsigned int length)
{
int fd = createNewFile(path);
if (write(fd, data, length) != length)
EXCEPTION(GOUROU_FILE_ERROR, "Write error for file " << path);
int fd = createNewFile(path);
close (fd);
if (write(fd, data, length) != length)
EXCEPTION(GOUROU_FILE_ERROR, "Write error for file " << path);
close (fd);
}
/**
@@ -397,7 +397,7 @@ namespace gourou
*/
static inline void writeFile(std::string path, ByteArray& data)
{
writeFile(path, data.data(), data.length());
writeFile(path, data.data(), data.length());
}
/**
@@ -405,7 +405,7 @@ namespace gourou
*/
static inline void writeFile(std::string path, const std::string& data)
{
writeFile(path, (const unsigned char*)data.c_str(), data.length());
writeFile(path, (const unsigned char*)data.c_str(), data.length());
}
/**
@@ -413,15 +413,15 @@ namespace gourou
*/
static inline void readFile(std::string path, const unsigned char* data, unsigned int length)
{
int fd = open(path.c_str(), O_RDONLY);
int fd = open(path.c_str(), O_RDONLY);
if (fd <= 0)
EXCEPTION(GOUROU_FILE_ERROR, "Unable to open " << path);
if (fd <= 0)
EXCEPTION(GOUROU_FILE_ERROR, "Unable to open " << path);
if (read(fd, (void*)data, length) != length)
EXCEPTION(GOUROU_FILE_ERROR, "Read error for file " << path);
if (read(fd, (void*)data, length) != length)
EXCEPTION(GOUROU_FILE_ERROR, "Read error for file " << path);
close (fd);
close (fd);
}
#define PATH_MAX_STRING_SIZE 256
@@ -429,73 +429,73 @@ namespace gourou
// https://gist.github.com/ChisholmKyle/0cbedcd3e64132243a39
/* recursive mkdir */
static inline int mkdir_p(const char *dir, const mode_t mode) {
char tmp[PATH_MAX_STRING_SIZE];
char *p = NULL;
struct stat sb;
size_t len;
/* copy path */
len = strnlen (dir, PATH_MAX_STRING_SIZE);
if (len == 0 || len == PATH_MAX_STRING_SIZE) {
return -1;
}
memcpy (tmp, dir, len);
tmp[len] = '\0';
char tmp[PATH_MAX_STRING_SIZE];
char *p = NULL;
struct stat sb;
size_t len;
/* remove trailing slash */
if(tmp[len - 1] == '/') {
tmp[len - 1] = '\0';
}
/* copy path */
len = strnlen (dir, PATH_MAX_STRING_SIZE);
if (len == 0 || len == PATH_MAX_STRING_SIZE) {
return -1;
}
memcpy (tmp, dir, len);
tmp[len] = '\0';
/* check if path exists and is a directory */
if (stat (tmp, &sb) == 0) {
if (S_ISDIR (sb.st_mode)) {
return 0;
}
}
/* recursive mkdir */
for(p = tmp + 1; *p; p++) {
if(*p == '/') {
*p = 0;
/* test path */
if (stat(tmp, &sb) != 0) {
/* path does not exist - create directory */
if (mkdir(tmp, mode) < 0) {
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
/* not a directory */
return -1;
}
*p = '/';
}
}
/* test path */
if (stat(tmp, &sb) != 0) {
/* path does not exist - create directory */
if (mkdir(tmp, mode) < 0) {
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
/* not a directory */
return -1;
}
return 0;
/* remove trailing slash */
if(tmp[len - 1] == '/') {
tmp[len - 1] = '\0';
}
/* check if path exists and is a directory */
if (stat (tmp, &sb) == 0) {
if (S_ISDIR (sb.st_mode)) {
return 0;
}
}
/* recursive mkdir */
for(p = tmp + 1; *p; p++) {
if(*p == '/') {
*p = 0;
/* test path */
if (stat(tmp, &sb) != 0) {
/* path does not exist - create directory */
if (mkdir(tmp, mode) < 0) {
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
/* not a directory */
return -1;
}
*p = '/';
}
}
/* test path */
if (stat(tmp, &sb) != 0) {
/* path does not exist - create directory */
if (mkdir(tmp, mode) < 0) {
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
/* not a directory */
return -1;
}
return 0;
}
static inline void dumpBuffer(GOUROU_LOG_LEVEL level, const char* title, const unsigned char* data, unsigned int len)
{
if (gourou::logLevel < level)
return;
printf("%s", title);
for(unsigned int i=0; i<len; i++)
{
if (i && !(i%16)) printf("\n");
printf("%02x ", data[i]);
}
printf("\n");
if (gourou::logLevel < level)
return;
printf("%s", title);
for(unsigned int i=0; i<len; i++)
{
if (i && !(i%16)) printf("\n");
printf("%02x ", data[i]);
}
printf("\n");
}
}

View File

@@ -24,11 +24,11 @@
namespace gourou {
enum GOUROU_LOG_LEVEL {
LG_LOG_ERROR,
LG_LOG_WARN,
LG_LOG_INFO,
LG_LOG_DEBUG,
LG_LOG_TRACE
LG_LOG_ERROR,
LG_LOG_WARN,
LG_LOG_INFO,
LG_LOG_DEBUG,
LG_LOG_TRACE
};
extern GOUROU_LOG_LEVEL logLevel;

View File

@@ -32,21 +32,21 @@ namespace gourou
class LoanToken
{
public:
/**
* @brief Main constructor. Not to be called by user
*
* @param doc Fulfill reply
*/
LoanToken(pugi::xml_document& doc);
/**
* @brief Main constructor. Not to be called by user
*
* @param doc Fulfill reply
*/
LoanToken(pugi::xml_document& doc);
/**
* @brief Get a property (id, operatorURL, validity)
*/
std::string getProperty(const std::string& property, const std::string& _default=std::string(""));
std::string operator[](const std::string& property);
/**
* @brief Get a property (id, operatorURL, validity)
*/
std::string getProperty(const std::string& property, const std::string& _default=std::string(""));
std::string operator[](const std::string& property);
private:
std::map<std::string, std::string> properties;
std::map<std::string, std::string> properties;
};
}

View File

@@ -30,7 +30,7 @@
namespace gourou
{
class DRMProcessor;
/**
* @brief This class is a container for activation.xml (activation info). It should not be used by user.
*/
@@ -39,73 +39,73 @@ namespace gourou
public:
User(DRMProcessor* processor, const std::string& activationFile);
/**
* @brief Retrieve some values from activation.xml
*/
std::string& getUUID();
std::string& getPKCS12();
std::string& getDeviceUUID();
std::string& getDeviceFingerprint();
std::string& getUsername();
std::string& getLoginMethod();
std::string getLicenseServiceCertificate(std::string url);
std::string& getAuthenticationCertificate();
std::string& getPrivateLicenseKey();
/**
* @brief Retrieve some values from activation.xml
*/
std::string& getUUID();
std::string& getPKCS12();
std::string& getDeviceUUID();
std::string& getDeviceFingerprint();
std::string& getUsername();
std::string& getLoginMethod();
std::string getLicenseServiceCertificate(std::string url);
std::string& getAuthenticationCertificate();
std::string& getPrivateLicenseKey();
/**
* @brief Read activation.xml and put result into doc
*/
void readActivation(pugi::xml_document& doc);
/**
* @brief Read activation.xml and put result into doc
*/
void readActivation(pugi::xml_document& doc);
/**
* @brief Update activation.xml with new data
*/
void updateActivationFile(const char* data);
/**
* @brief Update activation.xml with new data
*/
void updateActivationFile(const char* data);
/**
* @brief Update activation.xml with doc data
*/
void updateActivationFile(const pugi::xml_document& doc);
/**
* @brief Update activation.xml with doc data
*/
void updateActivationFile(const pugi::xml_document& doc);
/**
* @brief Get one value of activation.xml
*/
std::string getProperty(const std::string property);
/**
* @brief Get all nodes with property name
*/
pugi::xpath_node_set getProperties(const std::string property);
/**
* @brief Create activation.xml and devicesalt files if they did not exists
*
* @param processor Instance of DRMProcessor
* @param dirName Directory where to put files (.adept)
* @param ACSServer Server used for signIn
*/
static User* createUser(DRMProcessor* processor, const std::string& dirName, const std::string& ACSServer);
/**
* @brief Get one value of activation.xml
*/
std::string getProperty(const std::string property);
/**
* @brief Get all nodes with property name
*/
pugi::xpath_node_set getProperties(const std::string property);
/**
* @brief Create activation.xml and devicesalt files if they did not exists
*
* @param processor Instance of DRMProcessor
* @param dirName Directory where to put files (.adept)
* @param ACSServer Server used for signIn
*/
static User* createUser(DRMProcessor* processor, const std::string& dirName, const std::string& ACSServer);
private:
DRMProcessor* processor;
pugi::xml_document activationDoc;
std::string activationFile;
std::string pkcs12;
std::string uuid;
std::string deviceUUID;
std::string deviceFingerprint;
std::string username;
std::string loginMethod;
std::map<std::string,std::string> licenseServiceCertificates;
std::string authenticationCertificate;
std::string privateLicenseKey;
DRMProcessor* processor;
pugi::xml_document activationDoc;
User(DRMProcessor* processor);
void parseActivationFile(bool throwOnNull=true);
ByteArray signIn(const std::string& adobeID, const std::string& adobePassword,
ByteArray authenticationCertificate);
std::string activationFile;
std::string pkcs12;
std::string uuid;
std::string deviceUUID;
std::string deviceFingerprint;
std::string username;
std::string loginMethod;
std::map<std::string,std::string> licenseServiceCertificates;
std::string authenticationCertificate;
std::string privateLicenseKey;
User(DRMProcessor* processor);
void parseActivationFile(bool throwOnNull=true);
ByteArray signIn(const std::string& adobeID, const std::string& adobePassword,
ByteArray authenticationCertificate);
};
}