Libgourou

Libgourou Commit Details

Date:2022-09-04 09:25:06 (1 year 19 days ago)
Author:Grégory Soutadé
Branch:master
Commit:6e3958f09e6eee9128c60e54ab81f2e834cd6ff8
Parents: 2dbd4cc343529568c3cf05d3f3c9f54501e56435
Message:Compute over encrypted key also for PDF files

Changes:
Minclude/libgourou.h (1 diff)
Msrc/libgourou.cpp (5 diffs)

File differences

include/libgourou.h
231231
232232
233233
234
234
235235
236236
237237
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);
std::string encryptedKeyFirstPass(pugi::xml_document& rightsDoc, const std::string& encryptedKey, const std::string& keyType);
std::string encryptedKeyFirstPass(pugi::xml_document& rightsDoc, const std::string& encryptedKey, const std::string& keyType, ITEM_TYPE type);
void decryptADEPTKey(const std::string& encryptedKey, unsigned char* decryptedKey);
void removeEPubDRM(const std::string& filenameIn, const std::string& filenameOut, const unsigned char* encryptionKey, unsigned encryptionKeySize);
void generatePDFObjectKey(int version,
src/libgourou.cpp
963963
964964
965965
966
966
967
967968
968969
969970
970971
971
972
972973
973974
974975
975976
976977
977978
978
979
979
980
981
982
983
984
985
986
987
988
989
990
991
992
980993
981994
982995
......
10541067
10551068
10561069
1057
1070
10581071
10591072
10601073
......
12451258
12461259
12471260
1261
1262
1263
1264
1265
1266
12481267
1268
1269
1270
1271
1272
1273
1274
12491275
12501276
12511277
......
13141340
13151341
13161342
1317
1343
13181344
13191345
13201346
......
13471373
13481374
13491375
1350
1376
13511377
13521378
13531379
/**
* RSA Key can be over encrypted with AES128-CBC if keyType attribute is set
* Key = SHA256(keyType)[14:22] || SHA256(keyType)[7:13]
* For EPUB, Key = SHA256(keyType)[14:22] || SHA256(keyType)[7:13]
* For PDF, Key = SHA256(keyType)[6:19] || SHA256(keyType)[3:6]
* IV = DeviceID ^ FulfillmentId ^ VoucherId
*
* @return Base64 encoded decrypted key
*/
std::string DRMProcessor::encryptedKeyFirstPass(pugi::xml_document& rightsDoc, const std::string& encryptedKey, const std::string& keyType)
std::string DRMProcessor::encryptedKeyFirstPass(pugi::xml_document& rightsDoc, const std::string& encryptedKey, const std::string& keyType, ITEM_TYPE type)
{
unsigned char digest[32], key[16], iv[16];
unsigned int dataOutLength;
std::string id;
client->digest("SHA256", (unsigned char*)keyType.c_str(), keyType.size(), digest);
memcpy(key, &digest[14], 9);
memcpy(&key[9], &digest[7], 7);
dumpBuffer(gourou::LG_LOG_DEBUG, "SHA of KeyType : ", digest, sizeof(digest));
switch(type)
{
case EPUB:
memcpy(key, &digest[14], 9);
memcpy(&key[9], &digest[7], 7);
break;
case PDF:
memcpy(key, &digest[6], 13);
memcpy(&key[13], &digest[3], 3);
break;
}
id = extractTextElem(rightsDoc, "/adept:rights/licenseToken/device");
if (id == "")
std::string keyType = extractTextAttribute(rightsDoc, "/adept:rights/licenseToken/encryptedKey", "keyType", false);
if (keyType != "")
encryptedKey = encryptedKeyFirstPass(rightsDoc, encryptedKey, keyType);
encryptedKey = encryptedKeyFirstPass(rightsDoc, encryptedKey, keyType, EPUB);
decryptADEPTKey(encryptedKey, decryptedKey);
std::string encryptedKey = extractTextElem(rightsDoc, "/adept:rights/licenseToken/encryptedKey");
if (!encryptionKey)
{
std::string keyType = extractTextAttribute(rightsDoc, "/adept:rights/licenseToken/encryptedKey", "keyType", false);
if (keyType != "")
encryptedKey = encryptedKeyFirstPass(rightsDoc, encryptedKey, keyType, PDF);
decryptADEPTKey(encryptedKey, decryptedKey);
dumpBuffer(gourou::LG_LOG_DEBUG, "Decrypted : ", decryptedKey, RSA_KEY_SIZE);
if (decryptedKey[0] != 0x00 || decryptedKey[1] != 0x02 ||
decryptedKey[RSA_KEY_SIZE-16-1] != 0x00)
EXCEPTION(DRM_ERR_ENCRYPTION_KEY, "Unable to retrieve encryption key");
}
else
{
GOUROU_LOG(DEBUG, "Use provided encryption key");
GOUROU_LOG(DEBUG, "Decrypt string " << dictIt->first << " " << dataLength);
client->decrypt(CryptoInterface::ALGO_RC4, CryptoInterface::CHAIN_ECB,
tmpKey, 16, /* Key */
tmpKey, sizeof(tmpKey), /* Key */
NULL, 0, /* IV */
encryptedData, dataLength,
clearData, &dataOutLength);
GOUROU_LOG(DEBUG, "Decrypt stream id " << object->objectId() << ", size " << stream->dataLength());
client->decrypt(CryptoInterface::ALGO_RC4, CryptoInterface::CHAIN_ECB,
tmpKey, 16, /* Key */
tmpKey, sizeof(tmpKey), /* Key */
NULL, 0, /* IV */
encryptedData, dataLength,
clearData, &dataOutLength);

Archive Download the corresponding diff file