forked from soutade/libgourou
Compute over encrypted key also for PDF files
This commit is contained in:
parent
2dbd4cc343
commit
6e3958f09e
|
@ -231,7 +231,7 @@ namespace gourou
|
||||||
void buildSignInRequest(pugi::xml_document& signInRequest, const std::string& adobeID, const std::string& adobePassword, const std::string& authenticationCertificate);
|
void buildSignInRequest(pugi::xml_document& signInRequest, const std::string& adobeID, const std::string& adobePassword, const std::string& authenticationCertificate);
|
||||||
void fetchLicenseServiceCertificate(const std::string& licenseURL,
|
void fetchLicenseServiceCertificate(const std::string& licenseURL,
|
||||||
const std::string& operatorURL);
|
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 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 removeEPubDRM(const std::string& filenameIn, const std::string& filenameOut, const unsigned char* encryptionKey, unsigned encryptionKeySize);
|
||||||
void generatePDFObjectKey(int version,
|
void generatePDFObjectKey(int version,
|
||||||
|
|
|
@ -963,20 +963,33 @@ namespace gourou
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSA Key can be over encrypted with AES128-CBC if keyType attribute is set
|
* 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
|
* IV = DeviceID ^ FulfillmentId ^ VoucherId
|
||||||
*
|
*
|
||||||
* @return Base64 encoded decrypted key
|
* @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 char digest[32], key[16], iv[16];
|
||||||
unsigned int dataOutLength;
|
unsigned int dataOutLength;
|
||||||
std::string id;
|
std::string id;
|
||||||
|
|
||||||
client->digest("SHA256", (unsigned char*)keyType.c_str(), keyType.size(), digest);
|
client->digest("SHA256", (unsigned char*)keyType.c_str(), keyType.size(), digest);
|
||||||
|
|
||||||
|
dumpBuffer(gourou::LG_LOG_DEBUG, "SHA of KeyType : ", digest, sizeof(digest));
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case EPUB:
|
||||||
memcpy(key, &digest[14], 9);
|
memcpy(key, &digest[14], 9);
|
||||||
memcpy(&key[9], &digest[7], 7);
|
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");
|
id = extractTextElem(rightsDoc, "/adept:rights/licenseToken/device");
|
||||||
if (id == "")
|
if (id == "")
|
||||||
|
@ -1054,7 +1067,7 @@ namespace gourou
|
||||||
std::string keyType = extractTextAttribute(rightsDoc, "/adept:rights/licenseToken/encryptedKey", "keyType", false);
|
std::string keyType = extractTextAttribute(rightsDoc, "/adept:rights/licenseToken/encryptedKey", "keyType", false);
|
||||||
|
|
||||||
if (keyType != "")
|
if (keyType != "")
|
||||||
encryptedKey = encryptedKeyFirstPass(rightsDoc, encryptedKey, keyType);
|
encryptedKey = encryptedKeyFirstPass(rightsDoc, encryptedKey, keyType, EPUB);
|
||||||
|
|
||||||
decryptADEPTKey(encryptedKey, decryptedKey);
|
decryptADEPTKey(encryptedKey, decryptedKey);
|
||||||
|
|
||||||
|
@ -1245,7 +1258,20 @@ namespace gourou
|
||||||
std::string encryptedKey = extractTextElem(rightsDoc, "/adept:rights/licenseToken/encryptedKey");
|
std::string encryptedKey = extractTextElem(rightsDoc, "/adept:rights/licenseToken/encryptedKey");
|
||||||
|
|
||||||
if (!encryptionKey)
|
if (!encryptionKey)
|
||||||
|
{
|
||||||
|
std::string keyType = extractTextAttribute(rightsDoc, "/adept:rights/licenseToken/encryptedKey", "keyType", false);
|
||||||
|
|
||||||
|
if (keyType != "")
|
||||||
|
encryptedKey = encryptedKeyFirstPass(rightsDoc, encryptedKey, keyType, PDF);
|
||||||
|
|
||||||
decryptADEPTKey(encryptedKey, decryptedKey);
|
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
|
else
|
||||||
{
|
{
|
||||||
GOUROU_LOG(DEBUG, "Use provided encryption key");
|
GOUROU_LOG(DEBUG, "Use provided encryption key");
|
||||||
|
@ -1314,7 +1340,7 @@ namespace gourou
|
||||||
GOUROU_LOG(DEBUG, "Decrypt string " << dictIt->first << " " << dataLength);
|
GOUROU_LOG(DEBUG, "Decrypt string " << dictIt->first << " " << dataLength);
|
||||||
|
|
||||||
client->decrypt(CryptoInterface::ALGO_RC4, CryptoInterface::CHAIN_ECB,
|
client->decrypt(CryptoInterface::ALGO_RC4, CryptoInterface::CHAIN_ECB,
|
||||||
tmpKey, 16, /* Key */
|
tmpKey, sizeof(tmpKey), /* Key */
|
||||||
NULL, 0, /* IV */
|
NULL, 0, /* IV */
|
||||||
encryptedData, dataLength,
|
encryptedData, dataLength,
|
||||||
clearData, &dataOutLength);
|
clearData, &dataOutLength);
|
||||||
|
@ -1347,7 +1373,7 @@ namespace gourou
|
||||||
GOUROU_LOG(DEBUG, "Decrypt stream id " << object->objectId() << ", size " << stream->dataLength());
|
GOUROU_LOG(DEBUG, "Decrypt stream id " << object->objectId() << ", size " << stream->dataLength());
|
||||||
|
|
||||||
client->decrypt(CryptoInterface::ALGO_RC4, CryptoInterface::CHAIN_ECB,
|
client->decrypt(CryptoInterface::ALGO_RC4, CryptoInterface::CHAIN_ECB,
|
||||||
tmpKey, 16, /* Key */
|
tmpKey, sizeof(tmpKey), /* Key */
|
||||||
NULL, 0, /* IV */
|
NULL, 0, /* IV */
|
||||||
encryptedData, dataLength,
|
encryptedData, dataLength,
|
||||||
clearData, &dataOutLength);
|
clearData, &dataOutLength);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user