forked from soutade/libgourou
Initial commit
This commit is contained in:
26
utils/LICENSE
Normal file
26
utils/LICENSE
Normal file
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2021, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
24
utils/Makefile
Normal file
24
utils/Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
TARGETS=acsmdownloader activate
|
||||
|
||||
CXXFLAGS=-Wall `pkg-config --cflags Qt5Core Qt5Network` -fPIC -I$(ROOT)/include -I$(ROOT)/lib/pugixml/src/
|
||||
LDFLAGS=`pkg-config --libs Qt5Core Qt5Network` -L$(ROOT) -lgourou -lcrypto -lzip
|
||||
|
||||
ifneq ($(DEBUG),)
|
||||
CXXFLAGS += -ggdb -O0
|
||||
else
|
||||
CXXFLAGS += -O2
|
||||
endif
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
acsmdownloader: drmprocessorclientimpl.cpp acsmdownloader.cpp
|
||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||
|
||||
activate: drmprocessorclientimpl.cpp activate.cpp
|
||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
|
||||
ultraclean: clean
|
255
utils/acsmdownloader.cpp
Normal file
255
utils/acsmdownloader.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
Copyright (c) 2021, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <libgourou.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
static const char* deviceFile = "device.xml";
|
||||
static const char* activationFile = "activation.xml";
|
||||
static const char* devicekeyFile = "devicesalt";
|
||||
static const char* acsmFile = 0;
|
||||
static const char* outputFile = 0;
|
||||
static const char* outputDir = 0;
|
||||
static const char* defaultDirs[] = {
|
||||
".adept/",
|
||||
"./adobe-digital-editions/",
|
||||
"./.adobe-digital-editions/"
|
||||
};
|
||||
|
||||
|
||||
class ACSMDownloader: public QRunnable
|
||||
{
|
||||
public:
|
||||
ACSMDownloader(QCoreApplication* app):
|
||||
app(app)
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
DRMProcessorClientImpl client;
|
||||
gourou::DRMProcessor processor(&client, deviceFile, activationFile, devicekeyFile);
|
||||
|
||||
gourou::FulfillmentItem* item = processor.fulfill(acsmFile);
|
||||
|
||||
std::string filename;
|
||||
if (!outputFile)
|
||||
{
|
||||
filename = item->getMetadata("title");
|
||||
if (filename == "")
|
||||
filename = "output.epub";
|
||||
else
|
||||
filename += ".epub";
|
||||
}
|
||||
|
||||
if (outputDir)
|
||||
{
|
||||
QDir dir(outputDir);
|
||||
if (!dir.exists(outputDir))
|
||||
dir.mkpath(outputDir);
|
||||
|
||||
filename = std::string(outputDir) + "/" + filename;
|
||||
}
|
||||
|
||||
processor.download(item, filename);
|
||||
std::cout << "Created " << filename << std::endl;
|
||||
} catch(std::exception& e)
|
||||
{
|
||||
std::cout << e.what() << std::endl;
|
||||
this->app->exit(1);
|
||||
}
|
||||
|
||||
this->app->exit(0);
|
||||
}
|
||||
|
||||
private:
|
||||
QCoreApplication* app;
|
||||
};
|
||||
|
||||
static const char* findFile(const char* filename, bool inDefaultDirs=true)
|
||||
{
|
||||
QFile file(filename);
|
||||
|
||||
if (file.exists())
|
||||
return strdup(filename);
|
||||
|
||||
if (!inDefaultDirs) return 0;
|
||||
|
||||
for (int i=0; i<(int)ARRAY_SIZE(defaultDirs); i++)
|
||||
{
|
||||
QString path = QString(defaultDirs[i]) + QString(filename);
|
||||
file.setFileName(path);
|
||||
if (file.exists())
|
||||
return strdup(path.toStdString().c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage(const char* cmd)
|
||||
{
|
||||
std::cout << "Download EPUB file from ACSM request file" << std::endl;
|
||||
|
||||
std::cout << "Usage: " << cmd << " [(-d|--device-file) device.xml] [(-a|--activation-file) activation.xml] [(-s|--device-key-file) devicesalt] [(-O|--output-dir) dir] [(-o|--output-file) output.epub] [(-v|--verbose)] [(-h|--help)] (-f|--acsm-file) file.acsm" << std::endl << std::endl;
|
||||
|
||||
std::cout << " " << "-d|--device-file" << "\t" << "device.xml file from eReader" << std::endl;
|
||||
std::cout << " " << "-a|--activation-file" << "\t" << "activation.xml file from eReader" << std::endl;
|
||||
std::cout << " " << "-k|--device-key-file" << "\t" << "private device key file (eg devicesalt/devkey.bin) from eReader" << std::endl;
|
||||
std::cout << " " << "-O|--output-dir" << "\t" << "Optional output directory were to put result (default ./)" << std::endl;
|
||||
std::cout << " " << "-o|--output-file" << "\t" << "Optional output epub filename (default <title.epub>)" << std::endl;
|
||||
std::cout << " " << "-f|--acsm-file" << "\t" << "ACSM request file for epub download" << std::endl;
|
||||
std::cout << " " << "-v|--verbose" << "\t\t" << "Increase verbosity, can be set multiple times" << std::endl;
|
||||
std::cout << " " << "-h|--help" << "\t\t" << "This help" << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Device file, activation file and device key file are optionals. If not set, they are looked into :" << std::endl;
|
||||
std::cout << " * Current directory" << std::endl;
|
||||
std::cout << " * .adept" << std::endl;
|
||||
std::cout << " * adobe-digital-editions directory" << std::endl;
|
||||
std::cout << " * .adobe-digital-editions directory" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int c, ret = -1;
|
||||
|
||||
const char** files[] = {&devicekeyFile, &deviceFile, &activationFile};
|
||||
int verbose = gourou::DRMProcessor::getLogLevel();
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"device-file", required_argument, 0, 'd' },
|
||||
{"activation-file", required_argument, 0, 'a' },
|
||||
{"device-key-file", required_argument, 0, 'k' },
|
||||
{"output-dir", required_argument, 0, 'O' },
|
||||
{"output-file", required_argument, 0, 'o' },
|
||||
{"acsm-file", required_argument, 0, 'f' },
|
||||
{"verbose", no_argument, 0, 'v' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "d:a:k:O:o:f:vh",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
deviceFile = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
activationFile = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
devicekeyFile = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
acsmFile = optarg;
|
||||
break;
|
||||
case 'O':
|
||||
outputDir = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
outputFile = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
gourou::DRMProcessor::setLogLevel(verbose);
|
||||
|
||||
if (!acsmFile || (outputDir && !outputDir[0]) ||
|
||||
(outputFile && !outputFile[0]))
|
||||
{
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
ACSMDownloader downloader(&app);
|
||||
|
||||
int i;
|
||||
for (i=0; i<(int)ARRAY_SIZE(files); i++)
|
||||
{
|
||||
*files[i] = findFile(*files[i]);
|
||||
if (!*files[i])
|
||||
{
|
||||
std::cout << "Error : " << *files[i] << " doesn't exists" << std::endl;
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
QFile file(acsmFile);
|
||||
if (!file.exists())
|
||||
{
|
||||
std::cout << "Error : " << acsmFile << " doesn't exists" << std::endl;
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
QThreadPool::globalInstance()->start(&downloader);
|
||||
|
||||
ret = app.exec();
|
||||
|
||||
end:
|
||||
for (i=0; i<(int)ARRAY_SIZE(files); i++)
|
||||
{
|
||||
if (*files[i])
|
||||
free((void*)*files[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
263
utils/activate.cpp
Normal file
263
utils/activate.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
Copyright (c) 2021, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <libgourou.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
static const char* username = 0;
|
||||
static const char* password = 0;
|
||||
static const char* outputDir = 0;
|
||||
static const char* hobbesVersion = HOBBES_DEFAULT_VERSION;
|
||||
static bool randomSerial = false;
|
||||
|
||||
// From http://www.cplusplus.com/articles/E6vU7k9E/
|
||||
static int getch() {
|
||||
int ch;
|
||||
struct termios t_old, t_new;
|
||||
|
||||
tcgetattr(STDIN_FILENO, &t_old);
|
||||
t_new = t_old;
|
||||
t_new.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t_new);
|
||||
|
||||
ch = getchar();
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t_old);
|
||||
return ch;
|
||||
}
|
||||
|
||||
static std::string getpass(const char *prompt, bool show_asterisk=false)
|
||||
{
|
||||
const char BACKSPACE=127;
|
||||
const char RETURN=10;
|
||||
|
||||
std::string password;
|
||||
unsigned char ch=0;
|
||||
|
||||
std::cout <<prompt;
|
||||
|
||||
while((ch=getch())!= RETURN)
|
||||
{
|
||||
if(ch==BACKSPACE)
|
||||
{
|
||||
if(password.length()!=0)
|
||||
{
|
||||
if(show_asterisk)
|
||||
std::cout <<"\b \b";
|
||||
password.resize(password.length()-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
password+=ch;
|
||||
if(show_asterisk)
|
||||
std::cout <<'*';
|
||||
}
|
||||
}
|
||||
std::cout <<std::endl;
|
||||
return password;
|
||||
}
|
||||
|
||||
|
||||
class Activate: public QRunnable
|
||||
{
|
||||
public:
|
||||
Activate(QCoreApplication* app):
|
||||
app(app)
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
DRMProcessorClientImpl client;
|
||||
gourou::DRMProcessor* processor = gourou::DRMProcessor::createDRMProcessor(
|
||||
&client, randomSerial, outputDir, hobbesVersion);
|
||||
|
||||
processor->signIn(username, password);
|
||||
processor->activateDevice();
|
||||
|
||||
std::cout << username << " fully signed and device activated in " << outputDir << std::endl;
|
||||
} catch(std::exception& e)
|
||||
{
|
||||
std::cout << e.what() << std::endl;
|
||||
this->app->exit(1);
|
||||
}
|
||||
|
||||
this->app->exit(0);
|
||||
}
|
||||
|
||||
private:
|
||||
QCoreApplication* app;
|
||||
};
|
||||
|
||||
static void usage(const char* cmd)
|
||||
{
|
||||
std::cout << "Create new device files used by ADEPT DRM" << std::endl;
|
||||
|
||||
std::cout << "Usage: " << cmd << " (-u|--username) username [(-p|--password) password] [(-O|--output-dir) dir] [(-r|--random-serial)] [(-v|--verbose)] [(-h|--help)]" << std::endl << std::endl;
|
||||
|
||||
std::cout << " " << "-u|--username" << "\t\t" << "AdobeID username (ie adobe.com email account)" << std::endl;
|
||||
std::cout << " " << "-p|--password" << "\t\t" << "AdobeID password (asked if not set via command line) " << std::endl;
|
||||
std::cout << " " << "-O|--output-dir" << "\t" << "Optional output directory were to put result (default ./.adept). This directory must not already exists" << std::endl;
|
||||
std::cout << " " << "-H|--hobbes-version" << "\t"<< "Force RMSDK version to a specific value (default: version of current librmsdk)" << std::endl;
|
||||
std::cout << " " << "-r|--random-serial" << "\t"<< "Generate a random device serial (if not set, it will be dependent of your current configuration)" << std::endl;
|
||||
std::cout << " " << "-v|--verbose" << "\t\t" << "Increase verbosity, can be set multiple times" << std::endl;
|
||||
std::cout << " " << "-h|--help" << "\t\t" << "This help" << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
static const char* abspath(const char* filename)
|
||||
{
|
||||
const char* root = getcwd(0, PATH_MAX);
|
||||
QString fullPath = QString(root) + QString("/") + QString(filename);
|
||||
const char* res = strdup(fullPath.toStdString().c_str());
|
||||
|
||||
free((void*)root);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int c, ret = -1;
|
||||
const char* _outputDir = outputDir;
|
||||
int verbose = gourou::DRMProcessor::getLogLevel();
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"username", required_argument, 0, 'u' },
|
||||
{"password", required_argument, 0, 'p' },
|
||||
{"output-dir", required_argument, 0, 'O' },
|
||||
{"hobbes-version",required_argument, 0, 'H' },
|
||||
{"random-serial", no_argument, 0, 'r' },
|
||||
{"verbose", no_argument, 0, 'v' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "u:p:O:H:rvh",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'u':
|
||||
username = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
password = optarg;
|
||||
break;
|
||||
case 'O':
|
||||
_outputDir = optarg;
|
||||
break;
|
||||
case 'H':
|
||||
hobbesVersion = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
break;
|
||||
case 'r':
|
||||
randomSerial = true;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
gourou::DRMProcessor::setLogLevel(verbose);
|
||||
|
||||
if (!username)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!_outputDir || _outputDir[0] == 0)
|
||||
{
|
||||
outputDir = abspath(DEFAULT_ADEPT_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Relative path
|
||||
if (_outputDir[0] == '.' || _outputDir[0] != '/')
|
||||
{
|
||||
QFile file(_outputDir);
|
||||
// realpath doesn't works if file/dir doesn't exists
|
||||
if (file.exists())
|
||||
outputDir = realpath(_outputDir, 0);
|
||||
else
|
||||
outputDir = abspath(_outputDir);
|
||||
}
|
||||
else
|
||||
outputDir = strdup(_outputDir);
|
||||
}
|
||||
|
||||
if (!password)
|
||||
{
|
||||
char prompt[128];
|
||||
std::snprintf(prompt, sizeof(prompt), "Enter password for <%s> : ", username);
|
||||
std::string pass = getpass((const char*)prompt, false);
|
||||
password = pass.c_str();
|
||||
}
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
Activate activate(&app);
|
||||
QThreadPool::globalInstance()->start(&activate);
|
||||
|
||||
ret = app.exec();
|
||||
|
||||
free((void*)outputDir);
|
||||
return ret;
|
||||
}
|
385
utils/drmprocessorclientimpl.cpp
Normal file
385
utils/drmprocessorclientimpl.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
Copyright (c) 2021, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QFile>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include <libgourou_common.h>
|
||||
#include <libgourou_log.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
/* Digest interface */
|
||||
void* DRMProcessorClientImpl::createDigest(const std::string& digestName)
|
||||
{
|
||||
EVP_MD_CTX *sha_ctx = EVP_MD_CTX_new();
|
||||
const EVP_MD* md = EVP_get_digestbyname(digestName.c_str());
|
||||
EVP_DigestInit(sha_ctx, md);
|
||||
|
||||
return sha_ctx;
|
||||
}
|
||||
|
||||
int DRMProcessorClientImpl::digestUpdate(void* handler, unsigned char* data, unsigned int length)
|
||||
{
|
||||
return EVP_DigestUpdate((EVP_MD_CTX *)handler, data, length);
|
||||
}
|
||||
|
||||
int DRMProcessorClientImpl::digestFinalize(void* handler, unsigned char* digestOut)
|
||||
{
|
||||
int res = EVP_DigestFinal((EVP_MD_CTX *)handler, digestOut, NULL);
|
||||
EVP_MD_CTX_free((EVP_MD_CTX *)handler);
|
||||
return res;
|
||||
}
|
||||
|
||||
int DRMProcessorClientImpl::digest(const std::string& digestName, unsigned char* data, unsigned int length, unsigned char* digestOut)
|
||||
{
|
||||
void* handler = createDigest(digestName);
|
||||
if (!handler)
|
||||
return -1;
|
||||
if (digestUpdate(handler, data, length))
|
||||
return -1;
|
||||
return digestFinalize(handler, digestOut);
|
||||
}
|
||||
|
||||
/* Random interface */
|
||||
void DRMProcessorClientImpl::randBytes(unsigned char* bytesOut, unsigned int length)
|
||||
{
|
||||
RAND_bytes(bytesOut, length);
|
||||
}
|
||||
|
||||
/* HTTP interface */
|
||||
std::string DRMProcessorClientImpl::sendHTTPRequest(const std::string& URL, const std::string& POSTData, const std::string& contentType)
|
||||
{
|
||||
QNetworkRequest request(QUrl(URL.c_str()));
|
||||
QNetworkAccessManager networkManager;
|
||||
QByteArray replyData;
|
||||
|
||||
GOUROU_LOG(gourou::INFO, "Send request to " << URL);
|
||||
if (POSTData.size())
|
||||
{
|
||||
GOUROU_LOG(gourou::DEBUG, "<<< " << std::endl << POSTData);
|
||||
}
|
||||
|
||||
request.setRawHeader("Accept", "*/*");
|
||||
request.setRawHeader("User-Agent", "book2png");
|
||||
if (contentType.size())
|
||||
request.setRawHeader("Content-Type", contentType.c_str());
|
||||
|
||||
QNetworkReply* reply;
|
||||
|
||||
if (POSTData.size())
|
||||
reply = networkManager.post(request, POSTData.c_str());
|
||||
else
|
||||
reply = networkManager.get(request);
|
||||
|
||||
QCoreApplication* app = QCoreApplication::instance();
|
||||
networkManager.moveToThread(app->thread());
|
||||
while (!reply->isFinished())
|
||||
app->processEvents();
|
||||
|
||||
replyData = reply->readAll();
|
||||
if (reply->rawHeader("Content-Type") == "application/vnd.adobe.adept+xml")
|
||||
{
|
||||
GOUROU_LOG(gourou::DEBUG, ">>> " << std::endl << replyData.data());
|
||||
}
|
||||
|
||||
return std::string(replyData.data(), replyData.length());
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::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)
|
||||
{
|
||||
PKCS12 * pkcs12;
|
||||
EVP_PKEY* pkey;
|
||||
X509* cert;
|
||||
STACK_OF(X509)* ca;
|
||||
RSA * rsa;
|
||||
|
||||
pkcs12 = d2i_PKCS12(NULL, &RSAKey, RSAKeyLength);
|
||||
if (!pkcs12)
|
||||
EXCEPTION(gourou::CLIENT_INVALID_PKCS12, ERR_error_string(ERR_get_error(), NULL));
|
||||
PKCS12_parse(pkcs12, password.c_str(), &pkey, &cert, &ca);
|
||||
rsa = EVP_PKEY_get1_RSA(pkey);
|
||||
|
||||
int ret = RSA_private_encrypt(dataLength, data, res, rsa, RSA_PKCS1_PADDING);
|
||||
|
||||
if (ret < 0)
|
||||
EXCEPTION(gourou::CLIENT_RSA_ERROR, ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
if (gourou::logLevel >= gourou::DEBUG)
|
||||
{
|
||||
printf("Sig : ");
|
||||
for(int i=0; i<(int)sizeof(res); i++)
|
||||
printf("%02x ", res[i]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::RSAPublicEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
||||
const RSA_KEY_TYPE keyType,
|
||||
const unsigned char* data, unsigned dataLength,
|
||||
unsigned char* res)
|
||||
{
|
||||
X509 * x509 = d2i_X509(0, &RSAKey, RSAKeyLength);
|
||||
if (!x509)
|
||||
EXCEPTION(gourou::CLIENT_INVALID_CERTIFICATE, "Invalid certificate");
|
||||
|
||||
EVP_PKEY * evpKey = X509_get_pubkey(x509);
|
||||
RSA* rsa = EVP_PKEY_get1_RSA(evpKey);
|
||||
EVP_PKEY_free(evpKey);
|
||||
|
||||
if (!rsa)
|
||||
EXCEPTION(gourou::CLIENT_NO_PRIV_KEY, "No private key in certificate");
|
||||
|
||||
int ret = RSA_public_encrypt(dataLength, data, res, rsa, RSA_PKCS1_PADDING);
|
||||
if (ret < 0)
|
||||
EXCEPTION(gourou::CLIENT_RSA_ERROR, ERR_error_string(ERR_get_error(), NULL));
|
||||
}
|
||||
|
||||
void* DRMProcessorClientImpl::generateRSAKey(int keyLengthBits)
|
||||
{
|
||||
BIGNUM * bn = BN_new();
|
||||
RSA * rsa = RSA_new();
|
||||
BN_set_word(bn, 0x10001);
|
||||
RSA_generate_key_ex(rsa, keyLengthBits, bn, 0);
|
||||
BN_free(bn);
|
||||
|
||||
return rsa;
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::destroyRSAHandler(void* handler)
|
||||
{
|
||||
RSA_free((RSA*)handler);
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::extractRSAPublicKey(void* handler, unsigned char** keyOut, unsigned int* keyOutLength)
|
||||
{
|
||||
EVP_PKEY * evpKey = EVP_PKEY_new();
|
||||
EVP_PKEY_set1_RSA(evpKey, (RSA*)handler);
|
||||
X509_PUBKEY *x509_pubkey = 0;
|
||||
X509_PUBKEY_set(&x509_pubkey, evpKey);
|
||||
|
||||
*keyOutLength = i2d_X509_PUBKEY(x509_pubkey, keyOut);
|
||||
|
||||
X509_PUBKEY_free(x509_pubkey);
|
||||
EVP_PKEY_free(evpKey);
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::extractRSAPrivateKey(void* handler, unsigned char** keyOut, unsigned int* keyOutLength)
|
||||
{
|
||||
EVP_PKEY * evpKey = EVP_PKEY_new();
|
||||
EVP_PKEY_set1_RSA(evpKey, (RSA*)handler);
|
||||
PKCS8_PRIV_KEY_INFO * privKey = EVP_PKEY2PKCS8(evpKey);
|
||||
|
||||
*keyOutLength = i2d_PKCS8_PRIV_KEY_INFO(privKey, keyOut);
|
||||
|
||||
PKCS8_PRIV_KEY_INFO_free(privKey);
|
||||
EVP_PKEY_free(evpKey);
|
||||
}
|
||||
|
||||
/* Crypto interface */
|
||||
void DRMProcessorClientImpl::AESEncrypt(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv, unsigned int ivLength,
|
||||
const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength)
|
||||
{
|
||||
void* handler = AESEncryptInit(chaining, key, keyLength, iv, ivLength);
|
||||
AESEncryptUpdate(handler, dataIn, dataInLength, dataOut, dataOutLength);
|
||||
AESEncryptFinalize(handler, dataOut+*dataOutLength, dataOutLength);
|
||||
}
|
||||
|
||||
void* DRMProcessorClientImpl::AESEncryptInit(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv, unsigned int ivLength)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
|
||||
switch(keyLength)
|
||||
{
|
||||
case 16:
|
||||
switch(chaining)
|
||||
{
|
||||
case CHAIN_ECB:
|
||||
EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv);
|
||||
break;
|
||||
case CHAIN_CBC:
|
||||
EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
|
||||
break;
|
||||
default:
|
||||
EXCEPTION(gourou::CLIENT_BAD_CHAINING, "Unknown chaining mode " << chaining);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
EXCEPTION(gourou::CLIENT_BAD_KEY_SIZE, "Invalid key size " << keyLength);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void* DRMProcessorClientImpl::AESDecryptInit(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv, unsigned int ivLength)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
|
||||
switch(keyLength)
|
||||
{
|
||||
case 16:
|
||||
switch(chaining)
|
||||
{
|
||||
case CHAIN_ECB:
|
||||
EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv);
|
||||
break;
|
||||
case CHAIN_CBC:
|
||||
EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
|
||||
break;
|
||||
default:
|
||||
EXCEPTION(gourou::CLIENT_BAD_CHAINING, "Unknown chaining mode " << chaining);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
EXCEPTION(gourou::CLIENT_BAD_KEY_SIZE, "Invalid key size " << keyLength);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::AESEncryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength)
|
||||
{
|
||||
EVP_EncryptUpdate((EVP_CIPHER_CTX*)handler, dataOut, (int*)dataOutLength, dataIn, dataInLength);
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::AESEncryptFinalize(void* handler,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength)
|
||||
{
|
||||
int len;
|
||||
EVP_EncryptFinal_ex((EVP_CIPHER_CTX*)handler, dataOut, &len);
|
||||
*dataOutLength += len;
|
||||
EVP_CIPHER_CTX_free((EVP_CIPHER_CTX*)handler);
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::AESDecrypt(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv, unsigned int ivLength,
|
||||
const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength)
|
||||
{
|
||||
void* handler = AESDecryptInit(chaining, key, keyLength, iv, ivLength);
|
||||
AESDecryptUpdate(handler, dataIn, dataInLength, dataOut, dataOutLength);
|
||||
AESDecryptFinalize(handler, dataOut+*dataOutLength, dataOutLength);
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::AESDecryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength)
|
||||
{
|
||||
EVP_DecryptUpdate((EVP_CIPHER_CTX*)handler, dataOut, (int*)dataOutLength, dataIn, dataInLength);
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::AESDecryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength)
|
||||
{
|
||||
int len;
|
||||
EVP_DecryptFinal_ex((EVP_CIPHER_CTX*)handler, dataOut, &len);
|
||||
*dataOutLength += len;
|
||||
EVP_CIPHER_CTX_free((EVP_CIPHER_CTX*)handler);
|
||||
}
|
||||
|
||||
void* DRMProcessorClientImpl::zipOpen(const std::string& path)
|
||||
{
|
||||
zip_t* handler = zip_open(path.c_str(), 0, 0);
|
||||
|
||||
if (!handler)
|
||||
EXCEPTION(gourou::CLIENT_BAD_ZIP_FILE, "Invalid zip file " << path);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
std::string DRMProcessorClientImpl::zipReadFile(void* handler, const std::string& path)
|
||||
{
|
||||
std::string res;
|
||||
unsigned char* buffer;
|
||||
zip_stat_t sb;
|
||||
|
||||
if (zip_stat((zip_t *)handler, path.c_str(), 0, &sb) < 0)
|
||||
EXCEPTION(gourou::CLIENT_ZIP_ERROR, "Zip error " << zip_strerror((zip_t *)handler));
|
||||
|
||||
if (!(sb.valid & (ZIP_STAT_INDEX|ZIP_STAT_SIZE)))
|
||||
EXCEPTION(gourou::CLIENT_ZIP_ERROR, "Required fields missing");
|
||||
|
||||
buffer = new unsigned char[sb.size];
|
||||
|
||||
zip_file_t *f = zip_fopen_index((zip_t *)handler, sb.index, ZIP_FL_COMPRESSED);
|
||||
|
||||
zip_fread(f, buffer, sb.size);
|
||||
zip_fclose(f);
|
||||
|
||||
res = std::string((char*)buffer, sb.size);
|
||||
delete[] buffer;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::zipWriteFile(void* handler, const std::string& path, const std::string& content)
|
||||
{
|
||||
zip_source_t* s = zip_source_buffer((zip_t*)handler, content.c_str(), content.length(), 0);
|
||||
if (zip_file_add((zip_t*)handler, path.c_str(), s, ZIP_FL_OVERWRITE|ZIP_FL_ENC_UTF_8) < 0)
|
||||
{
|
||||
zip_source_free(s);
|
||||
EXCEPTION(gourou::CLIENT_ZIP_ERROR, "Zip error " << zip_strerror((zip_t *)handler));
|
||||
}
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::zipDeleteFile(void* handler, const std::string& path)
|
||||
{
|
||||
zip_int64_t idx = zip_name_locate((zip_t*)handler, path.c_str(), 0);
|
||||
|
||||
if (idx < 0)
|
||||
EXCEPTION(gourou::CLIENT_ZIP_ERROR, "No such file " << path.c_str());
|
||||
|
||||
if (zip_delete((zip_t*)handler, idx))
|
||||
EXCEPTION(gourou::CLIENT_ZIP_ERROR, "Zip error " << zip_strerror((zip_t *)handler));
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::zipClose(void* handler)
|
||||
{
|
||||
zip_close((zip_t*)handler);
|
||||
}
|
110
utils/drmprocessorclientimpl.h
Normal file
110
utils/drmprocessorclientimpl.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (c) 2021, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DRMPROCESSORCLIENTIMPL_H_
|
||||
#define _DRMPROCESSORCLIENTIMPL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <drmprocessorclient.h>
|
||||
|
||||
class DRMProcessorClientImpl : public gourou::DRMProcessorClient
|
||||
{
|
||||
public:
|
||||
/* Digest interface */
|
||||
virtual void* createDigest(const std::string& digestName);
|
||||
virtual int digestUpdate(void* handler, unsigned char* data, unsigned int length);
|
||||
virtual int digestFinalize(void* handler,unsigned char* digestOut);
|
||||
virtual int digest(const std::string& digestName, unsigned char* data, unsigned int length, unsigned char* digestOut);
|
||||
|
||||
/* Random interface */
|
||||
virtual void randBytes(unsigned char* bytesOut, unsigned int length);
|
||||
|
||||
/* HTTP interface */
|
||||
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""));
|
||||
|
||||
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);
|
||||
|
||||
virtual void RSAPublicEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
||||
const RSA_KEY_TYPE keyType,
|
||||
const unsigned char* data, unsigned dataLength,
|
||||
unsigned char* res);
|
||||
|
||||
virtual void* generateRSAKey(int keyLengthBits);
|
||||
virtual void destroyRSAHandler(void* handler);
|
||||
|
||||
virtual void extractRSAPublicKey(void* RSAKeyHandler, unsigned char** keyOut, unsigned int* keyOutLength);
|
||||
virtual void extractRSAPrivateKey(void* RSAKeyHandler, unsigned char** keyOut, unsigned int* keyOutLength);
|
||||
|
||||
/* Crypto interface */
|
||||
virtual void AESEncrypt(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv, unsigned int ivLength,
|
||||
const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength);
|
||||
|
||||
virtual void* AESEncryptInit(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv=0, unsigned int ivLength=0);
|
||||
|
||||
|
||||
virtual void AESEncryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength);
|
||||
virtual void AESEncryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength);
|
||||
|
||||
virtual void AESDecrypt(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv, unsigned int ivLength,
|
||||
const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength);
|
||||
|
||||
virtual void* AESDecryptInit(CHAINING_MODE chaining,
|
||||
const unsigned char* key, unsigned int keyLength,
|
||||
const unsigned char* iv=0, unsigned int ivLength=0);
|
||||
|
||||
virtual void AESDecryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,
|
||||
unsigned char* dataOut, unsigned int* dataOutLength);
|
||||
virtual void AESDecryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength);
|
||||
|
||||
/* ZIP Interface */
|
||||
virtual void* zipOpen(const std::string& path);
|
||||
|
||||
virtual std::string zipReadFile(void* handler, const std::string& path);
|
||||
|
||||
virtual void zipWriteFile(void* handler, const std::string& path, const std::string& content);
|
||||
|
||||
virtual void zipDeleteFile(void* handler, const std::string& path);
|
||||
|
||||
virtual void zipClose(void* handler);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user