forked from soutade/libgourou
Add fetchLicenseServiceCertificate() because not all signing certificates (to be included into rights.xml) are the same than the one fetched at authentication
This commit is contained in:
parent
7f5a4900e0
commit
8bc346d139
|
@ -194,6 +194,8 @@ namespace gourou
|
||||||
void buildActivateReq(pugi::xml_document& activateReq);
|
void buildActivateReq(pugi::xml_document& activateReq);
|
||||||
ByteArray sendFulfillRequest(const pugi::xml_document& document, const std::string& url);
|
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 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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,15 @@
|
||||||
GNU Lesser General Public License for more details.
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
along with libgourou. If not, see <http://www.gnu.org/licenses/>.
|
along with libgourou. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USER_H_
|
#ifndef _USER_H_
|
||||||
#define _USER_H_
|
#define _USER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "bytearray.h"
|
#include "bytearray.h"
|
||||||
|
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
@ -46,7 +48,7 @@ namespace gourou
|
||||||
std::string& getDeviceFingerprint();
|
std::string& getDeviceFingerprint();
|
||||||
std::string& getUsername();
|
std::string& getUsername();
|
||||||
std::string& getLoginMethod();
|
std::string& getLoginMethod();
|
||||||
std::string& getCertificate();
|
std::string getLicenseServiceCertificate(std::string url);
|
||||||
std::string& getAuthenticationCertificate();
|
std::string& getAuthenticationCertificate();
|
||||||
std::string& getPrivateLicenseKey();
|
std::string& getPrivateLicenseKey();
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ namespace gourou
|
||||||
std::string deviceFingerprint;
|
std::string deviceFingerprint;
|
||||||
std::string username;
|
std::string username;
|
||||||
std::string loginMethod;
|
std::string loginMethod;
|
||||||
std::string certificate;
|
std::map<std::string,std::string> licenseServiceCertificates;
|
||||||
std::string authenticationCertificate;
|
std::string authenticationCertificate;
|
||||||
std::string privateLicenseKey;
|
std::string privateLicenseKey;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,12 @@ namespace gourou
|
||||||
if (downloadURL == "")
|
if (downloadURL == "")
|
||||||
EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "No download URL in document");
|
EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "No download URL in document");
|
||||||
|
|
||||||
|
node = doc.select_node("/envelope/fulfillmentResult/resourceItemInfo/resource").node();
|
||||||
|
resource = node.first_child().value();
|
||||||
|
|
||||||
|
if (resource == "")
|
||||||
|
EXCEPTION(FFI_INVALID_FULFILLMENT_DATA, "No resource in document");
|
||||||
|
|
||||||
pugi::xml_node licenseToken = doc.select_node("/envelope/fulfillmentResult/resourceItemInfo/licenseToken").node();
|
pugi::xml_node licenseToken = doc.select_node("/envelope/fulfillmentResult/resourceItemInfo/licenseToken").node();
|
||||||
|
|
||||||
if (!licenseToken)
|
if (!licenseToken)
|
||||||
|
@ -56,11 +62,13 @@ namespace gourou
|
||||||
if (!newLicenseToken.attribute("xmlns"))
|
if (!newLicenseToken.attribute("xmlns"))
|
||||||
newLicenseToken.append_attribute("xmlns") = ADOBE_ADEPT_NS;
|
newLicenseToken.append_attribute("xmlns") = ADOBE_ADEPT_NS;
|
||||||
|
|
||||||
pugi::xml_node licenseServiceInfo = root.append_child("licenseServiceInfo");
|
pugi::xml_node licenseServiceInfo = root.append_child("adept:licenseServiceInfo");
|
||||||
licenseServiceInfo.append_attribute("xmlns") = ADOBE_ADEPT_NS;
|
pugi::xml_node licenseURL = licenseToken.select_node("licenseURL").node();
|
||||||
licenseServiceInfo.append_copy(licenseToken.select_node("licenseURL").node());
|
licenseURL.set_name("adept:licenseURL");
|
||||||
pugi::xml_node certificate = licenseServiceInfo.append_child("certificate");
|
licenseServiceInfo.append_copy(licenseURL);
|
||||||
certificate.append_child(pugi::node_pcdata).set_value(user->getCertificate().c_str());
|
pugi::xml_node certificate = licenseServiceInfo.append_child("adept:certificate");
|
||||||
|
std::string certificateValue = user->getLicenseServiceCertificate(licenseURL.first_child().value());
|
||||||
|
certificate.append_child(pugi::node_pcdata).set_value(certificateValue.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FulfillmentItem::getMetadata(std::string name)
|
std::string FulfillmentItem::getMetadata(std::string name)
|
||||||
|
@ -88,4 +96,9 @@ namespace gourou
|
||||||
{
|
{
|
||||||
return downloadURL;
|
return downloadURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string FulfillmentItem::getResource()
|
||||||
|
{
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#define ASN_TEXT 0x04
|
#define ASN_TEXT 0x04
|
||||||
#define ASN_ATTRIBUTE 0x05
|
#define ASN_ATTRIBUTE 0x05
|
||||||
|
|
||||||
|
|
||||||
namespace gourou
|
namespace gourou
|
||||||
{
|
{
|
||||||
GOUROU_LOG_LEVEL logLevel = WARN;
|
GOUROU_LOG_LEVEL logLevel = WARN;
|
||||||
|
@ -453,6 +454,49 @@ namespace gourou
|
||||||
appendTextElem(activationToken, "adept:device", user->getDeviceUUID());
|
appendTextElem(activationToken, "adept:device", user->getDeviceUUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DRMProcessor::fetchLicenseServiceCertificate(const std::string& licenseURL,
|
||||||
|
const std::string& operatorURL)
|
||||||
|
{
|
||||||
|
if (user->getLicenseServiceCertificate(licenseURL) != "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string licenseServiceInfoReq = operatorURL + "/LicenseServiceInfo?licenseURL=" + licenseURL;
|
||||||
|
|
||||||
|
ByteArray replyData;
|
||||||
|
replyData = sendRequest(licenseServiceInfoReq);
|
||||||
|
|
||||||
|
pugi::xml_document licenseServicesDoc;
|
||||||
|
licenseServicesDoc.load_buffer(replyData.data(), replyData.length());
|
||||||
|
|
||||||
|
// Add new license certificate
|
||||||
|
pugi::xml_document activationDoc;
|
||||||
|
user->readActivation(activationDoc);
|
||||||
|
|
||||||
|
pugi::xml_node root;
|
||||||
|
pugi::xpath_node xpathRes = activationDoc.select_node("//adept:licenseServices");
|
||||||
|
|
||||||
|
// Create adept:licenseServices if it doesn't exists
|
||||||
|
if (!xpathRes)
|
||||||
|
{
|
||||||
|
xpathRes = activationDoc.select_node("/activationInfo");
|
||||||
|
root = xpathRes.node();
|
||||||
|
root = root.append_child("adept:licenseServices");
|
||||||
|
root.append_attribute("xmlns:adept") = ADOBE_ADEPT_NS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
root = xpathRes.node();
|
||||||
|
|
||||||
|
root = root.append_child("adept:licenseServiceInfo");
|
||||||
|
|
||||||
|
std::string certificate = extractTextElem(licenseServicesDoc,
|
||||||
|
"/licenseServiceInfo/certificate");
|
||||||
|
|
||||||
|
appendTextElem(root, "adept:licenseURL", licenseURL);
|
||||||
|
appendTextElem(root, "adept:certificate", certificate);
|
||||||
|
|
||||||
|
user->updateActivationFile(activationDoc);
|
||||||
|
}
|
||||||
|
|
||||||
FulfillmentItem* DRMProcessor::fulfill(const std::string& ACSMFile)
|
FulfillmentItem* DRMProcessor::fulfill(const std::string& ACSMFile)
|
||||||
{
|
{
|
||||||
if (!user->getPKCS12().length())
|
if (!user->getPKCS12().length())
|
||||||
|
@ -495,15 +539,16 @@ namespace gourou
|
||||||
EXCEPTION(FF_NO_OPERATOR_URL, "OperatorURL not found in ACSM document");
|
EXCEPTION(FF_NO_OPERATOR_URL, "OperatorURL not found in ACSM document");
|
||||||
|
|
||||||
std::string operatorURL = node.node().first_child().value();
|
std::string operatorURL = node.node().first_child().value();
|
||||||
operatorURL = trim(operatorURL) + "/Fulfill";
|
operatorURL = trim(operatorURL);
|
||||||
|
std::string fulfillURL = operatorURL + "/Fulfill";
|
||||||
|
|
||||||
operatorAuth(operatorURL);
|
operatorAuth(fulfillURL);
|
||||||
|
|
||||||
ByteArray replyData;
|
ByteArray replyData;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
replyData = sendRequest(fulfillReq, operatorURL);
|
replyData = sendRequest(fulfillReq, fulfillURL);
|
||||||
}
|
}
|
||||||
catch (gourou::Exception& e)
|
catch (gourou::Exception& e)
|
||||||
{
|
{
|
||||||
|
@ -515,8 +560,8 @@ namespace gourou
|
||||||
if (e.getErrorCode() == GOUROU_ADEPT_ERROR &&
|
if (e.getErrorCode() == GOUROU_ADEPT_ERROR &&
|
||||||
errorMsg.find("E_ADEPT_DISTRIBUTOR_AUTH") != std::string::npos)
|
errorMsg.find("E_ADEPT_DISTRIBUTOR_AUTH") != std::string::npos)
|
||||||
{
|
{
|
||||||
doOperatorAuth(operatorURL);
|
doOperatorAuth(fulfillURL);
|
||||||
replyData = sendRequest(fulfillReq, operatorURL);
|
replyData = sendRequest(fulfillReq, fulfillURL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -528,6 +573,10 @@ namespace gourou
|
||||||
|
|
||||||
fulfillReply.load_string((const char*)replyData.data());
|
fulfillReply.load_string((const char*)replyData.data());
|
||||||
|
|
||||||
|
std::string licenseURL = extractTextElem(fulfillReply, "//licenseToken/licenseURL");
|
||||||
|
|
||||||
|
fetchLicenseServiceCertificate(licenseURL, operatorURL);
|
||||||
|
|
||||||
return new FulfillmentItem(fulfillReply, user);
|
return new FulfillmentItem(fulfillReply, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/user.cpp
20
src/user.cpp
|
@ -48,7 +48,6 @@ namespace gourou {
|
||||||
uuid = gourou::extractTextElem(activationDoc, "//adept:user", throwOnNull);
|
uuid = gourou::extractTextElem(activationDoc, "//adept:user", throwOnNull);
|
||||||
deviceUUID = gourou::extractTextElem(activationDoc, "//device", throwOnNull);
|
deviceUUID = gourou::extractTextElem(activationDoc, "//device", throwOnNull);
|
||||||
deviceFingerprint = gourou::extractTextElem(activationDoc, "//fingerprint", throwOnNull);
|
deviceFingerprint = gourou::extractTextElem(activationDoc, "//fingerprint", throwOnNull);
|
||||||
certificate = gourou::extractTextElem(activationDoc, "//adept:certificate", throwOnNull);
|
|
||||||
authenticationCertificate = gourou::extractTextElem(activationDoc, "//adept:authenticationCertificate", throwOnNull);
|
authenticationCertificate = gourou::extractTextElem(activationDoc, "//adept:authenticationCertificate", throwOnNull);
|
||||||
privateLicenseKey = gourou::extractTextElem(activationDoc, "//adept:privateLicenseKey", throwOnNull);
|
privateLicenseKey = gourou::extractTextElem(activationDoc, "//adept:privateLicenseKey", throwOnNull);
|
||||||
username = gourou::extractTextElem(activationDoc, "//adept:username", throwOnNull);
|
username = gourou::extractTextElem(activationDoc, "//adept:username", throwOnNull);
|
||||||
|
@ -61,6 +60,15 @@ namespace gourou {
|
||||||
if (throwOnNull)
|
if (throwOnNull)
|
||||||
EXCEPTION(USER_INVALID_ACTIVATION_FILE, "Invalid activation file");
|
EXCEPTION(USER_INVALID_ACTIVATION_FILE, "Invalid activation file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pugi::xpath_node_set nodeSet = activationDoc.select_nodes("//adept:licenseServices/adept:licenseServiceInfo");
|
||||||
|
for (pugi::xpath_node_set::const_iterator it = nodeSet.begin();
|
||||||
|
it != nodeSet.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string url = gourou::extractTextElem(it->node(), "adept:licenseURL");
|
||||||
|
std::string certificate = gourou::extractTextElem(it->node(), "adept:certificate");
|
||||||
|
licenseServiceCertificates[url] = certificate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(gourou::Exception& e)
|
catch(gourou::Exception& e)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +82,6 @@ namespace gourou {
|
||||||
std::string& User::getDeviceFingerprint() { return deviceFingerprint; }
|
std::string& User::getDeviceFingerprint() { return deviceFingerprint; }
|
||||||
std::string& User::getUsername() { return username; }
|
std::string& User::getUsername() { return username; }
|
||||||
std::string& User::getLoginMethod() { return loginMethod; }
|
std::string& User::getLoginMethod() { return loginMethod; }
|
||||||
std::string& User::getCertificate() { return certificate; }
|
|
||||||
std::string& User::getAuthenticationCertificate() { return authenticationCertificate; }
|
std::string& User::getAuthenticationCertificate() { return authenticationCertificate; }
|
||||||
std::string& User::getPrivateLicenseKey() { return privateLicenseKey; }
|
std::string& User::getPrivateLicenseKey() { return privateLicenseKey; }
|
||||||
|
|
||||||
|
@ -200,4 +207,13 @@ namespace gourou {
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string User::getLicenseServiceCertificate(std::string url)
|
||||||
|
{
|
||||||
|
if (licenseServiceCertificates.count(trim(url)))
|
||||||
|
return licenseServiceCertificates[trim(url)];
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user