UNDO: enc

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34943 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Peter Kümmel 2010-07-17 16:09:26 +00:00
parent 72292b98a6
commit c09d33120d
17 changed files with 13 additions and 640 deletions

View File

@ -52,7 +52,6 @@ LYX_OPTION(STDLIB_DEBUG "Use debug stdlib" OFF GCC)
LYX_OPTION(CONCEPT_CHECKS "Enable concept-checks" OFF GCC)
LYX_OPTION(QUIET "Don't generate verbose makefiles" OFF ALL)
LYX_OPTION(SHARED_LIBRARIES "Build shared libraries" OFF ALL)
LYX_OPTION(ENCRYPTION "Build with encryption functionality" OFF ALL)
message(STATUS)
@ -89,9 +88,6 @@ if(LYX_INSTALL)
endif()
# Supress regeneration
set(CMAKE_SUPPRESS_REGENERATION TRUE)
@ -497,12 +493,6 @@ else()
add_subdirectory(boost)
endif()
if(LYX_ENCRYPTION)
#Ubuntu: libssl-dev
find_package(OpenSSL REQUIRED)
add_definitions(-DLYX_ENCRYPTION)
endif()
if(NOT LYX_USE_EXTERNAL_LIBINTL)
add_subdirectory(intl)

View File

@ -116,8 +116,7 @@ target_link_libraries(${_lyx}
${LIBINTL_LIBRARIES}
${ICONV_LIBRARY}
${QT_QTMAIN_LIBRARY}
${vld_dll}
${OPENSSL_LIBRARIES})
${vld_dll})
if (HUNSPELL_FOUND)
target_link_libraries(${_lyx} ${HUNSPELL_LIBRARY})

View File

@ -49,8 +49,7 @@ include_directories(${TOP_SRC_DIR}/src/support
${TOP_SRC_DIR}/src/support/mythes
${QT_INCLUDES}
${ICONV_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR})
${ZLIB_INCLUDE_DIR})
if(NOT LYX_MERGE_FILES)
@ -71,7 +70,7 @@ else()
${support_mythes_sources} ${support_linkback_sources} ${support_headers} ${dont_merge})
endif()
target_link_libraries(support ${Lyx_Boost_Libraries} ${QT_QTCORE_LIBRARY} ${ZLIB_LIBRARY} ${OPENSSL_LIBRARIES})
target_link_libraries(support ${Lyx_Boost_Libraries} ${QT_QTCORE_LIBRARY} ${ZLIB_LIBRARY})
lyx_add_gcc_pch(support)

View File

@ -43,8 +43,7 @@ target_link_libraries(${_tex2lyx}
${Lyx_Boost_Libraries}
${QT_QTCORE_LIBRARY}
${LIBINTL_LIBRARIES}
${ICONV_LIBRARY}
${OPENSSL_LIBRARIES})
${ICONV_LIBRARY})
if(WIN32)
target_link_libraries(${_tex2lyx} shlwapi ole32 psapi)

View File

@ -49,7 +49,6 @@ Menuset
Item "Close All" "buffer-close-all"
Item "Save|S" "buffer-write"
Item "Save As...|A" "buffer-write-as"
# Item "Save Encrypted" "buffer-write-encrypted"
Item "Save All|l" "buffer-write-all"
Item "Revert to Saved|R" "buffer-reload"
Submenu "Version Control|V" "file_vc"

View File

@ -448,9 +448,7 @@ enum FuncCode
LFUN_FORWARD_SEARCH,
LFUN_INSET_COPY_AS, // vfr, 20100419
LFUN_BUFFER_TOGGLE_OUTPUT_SYNC,
LFUN_BUFFER_WRITE_ENCRYPTED,
// 350
LFUN_LASTACTION // end of the table
};

View File

@ -3090,14 +3090,6 @@ void LyXAction::init()
* \endvar
*/
{ LFUN_BUFFER_WRITE, "buffer-write", ReadOnly, Buffer },
/*!
* \var lyx::FuncCode lyx::LFUN_BUFFER_WRITE_ENCRYPTED
* \li Action: Saves the current buffer encyrpted.
* \li Notion: Saves the current buffer encyrpted to disk, asks for a new filename
* \li Syntax: buffer-write-encyrypted
* \endvar
*/
{ LFUN_BUFFER_WRITE_ENCRYPTED, "buffer-write-encrypted", ReadOnly, Buffer },
/*!
* \var lyx::FuncCode lyx::LFUN_BUFFER_WRITE_AS
* \li Action: Rename and save current buffer.

View File

@ -1,64 +0,0 @@
// -*- C++ -*-
/**
* \file GuiEncryptionDialog.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "GuiEncryptionDialog.h"
#include "qt_i18n.h"
#include "support/qstring_helpers.h"
#include <QHBoxLayout>
#include <QGridLayout>
namespace lyx {
namespace frontend {
GuiEncryptionDialog::GuiEncryptionDialog(QWidget *parent) : QDialog(parent)
{
pwd_label_ = new QLabel(qt_("Password:"));
pwd_edit_ = new QLineEdit;
pwd_edit_->setEchoMode(QLineEdit::Password);
pwd_label_->setBuddy(pwd_edit_);
button_box_ = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(button_box_, SIGNAL(accepted()), this, SLOT(accept()));
connect(button_box_, SIGNAL(rejected()), this, SLOT(reject()));
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(pwd_label_);
hLayout->addWidget(pwd_edit_);
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
mainLayout->addLayout(hLayout, 0, 0);
mainLayout->addWidget(button_box_, 1, 0);
setLayout(mainLayout);
}
QString GuiEncryptionDialog::password() const
{
return pwd_edit_->text();
}
void GuiEncryptionDialog::clearPassword()
{
pwd_edit_->setText("");
}
} // namespace frontend
} // namespace lyx
#include "moc_GuiEncryptionDialog.cpp"

View File

@ -1,47 +0,0 @@
// -*- C++ -*-
/**
* \file GuiEncryptionDialog.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*/
#ifndef GUI_ENCRYPTION_DIALOG_H
#define GUI_ENCRYPTION_DIALOG_H
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QDialogButtonBox>
#include <QPushButton>
namespace lyx {
namespace frontend {
class GuiEncryptionDialog : public QDialog
{
Q_OBJECT
public:
GuiEncryptionDialog(QWidget *parent = 0);
void clearPassword();
QString password() const;
private:
QLabel * pwd_label_;
QLineEdit * pwd_edit_;
QDialogButtonBox * button_box_;
};
} // namespace frontend
} // namespace lyx
#endif

View File

@ -29,7 +29,7 @@
#include "LayoutBox.h"
#include "Menus.h"
#include "TocModel.h"
#include "GuiProgress.h"
#include "qt_helpers.h"
#include "frontends/alert.h"
@ -62,7 +62,6 @@
#include "Text.h"
#include "Toolbars.h"
#include "version.h"
#include "GuiEncryptionDialog.h"
#include "support/convert.h"
#include "support/debug.h"
@ -80,8 +79,7 @@
#include "support/Systemcall.h"
#include "support/Timeout.h"
#include "support/ProgressInterface.h"
#include "support/CryptographicEncryption.h"
#include "GuiProgress.h"
#include <QAction>
#include <QApplication>
@ -108,10 +106,8 @@
#include <QToolBar>
#include <QUrl>
#include <QScrollBar>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QDialog>
#include <QFile>
#define EXPORT_in_THREAD 1
@ -1484,10 +1480,6 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
break;
}
case LFUN_BUFFER_WRITE_ENCRYPTED:
enable = doc_buffer;
break;
case LFUN_BUFFER_WRITE_AS:
enable = doc_buffer;
break;
@ -1712,71 +1704,11 @@ static FileName selectTemplateFile()
return FileName(fromqstr(result.second));
}
/// checks if the file is encrypted and creates a decrypted tmp file
#define LYX_ENC_VERSION 1
static FileName decryptedFileName(FileName const & filename)
{
if (!filename.isEncryptedFile()) {
return filename;
}
int encVersion = filename.encryptionVersion();
if (encVersion < 0 || encVersion > LYX_ENC_VERSION) {
Alert::error(_("Encryption"), _("This LyX program is to old to read encrypted file."));
return filename;
}
QByteArray encrypted;
QFile file(toqstr(filename.absFileName()));
if (file.open(QIODevice::ReadOnly)) {
encrypted = file.readAll();
} else {
return filename;
}
QByteArray key;
CryptographicEncryption enc;
int keytype = filename.encryptionKeytype();
if (keytype == CryptographicEncryption::Password) {
GuiEncryptionDialog dlg;
dlg.setWindowTitle(qt_("Enter Password"));
dlg.exec();
QString pwd = dlg.password();
key = enc.stringToKey(pwd);
} else {
Alert::error(_("Encryption"), _("Don't know how to generate decryption key."));
return filename;
}
// remove the encryption prefix
encrypted.remove(0, FileName::encryptionPrefix(LYX_ENC_VERSION, 1).size());
QByteArray decrypted;
if (!enc.decyrpt(encrypted, &decrypted, key)) {
Alert::error(_("Encryption"), _("Error when decryting file."));
return filename;
}
// TODO decrypt in memory
// TODO find a better solution than showing the
// generated filename
FileName tempDecrypted = FileName::tempName();
QFile defile(toqstr(tempDecrypted.absFileName()));
if (defile.open(QIODevice::WriteOnly)) {
defile.write(decrypted);
}
return tempDecrypted;
}
Buffer * GuiView::loadDocument(FileName const & filenameIn, bool tolastfiles)
Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles)
{
setBusy(true);
FileName filename = decryptedFileName(filenameIn);
Buffer * newBuffer = checkAndLoadLyXFile(filename);
if (!newBuffer) {
@ -2246,7 +2178,7 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
}
bool GuiView::saveBuffer(Buffer & b, ostream* stream)
bool GuiView::saveBuffer(Buffer & b)
{
if (workArea(b) && workArea(b)->inDialogMode())
return true;
@ -2254,7 +2186,7 @@ bool GuiView::saveBuffer(Buffer & b, ostream* stream)
if (b.isUnnamed())
return renameBuffer(b, docstring());
if ( (stream ? b.write(*stream) : b.save()) ) {
if (b.save()) {
theSession().lastFiles().add(b.fileName());
return true;
}
@ -2280,126 +2212,10 @@ bool GuiView::saveBuffer(Buffer & b, ostream* stream)
return false;
}
return saveBuffer(b, stream);
return saveBuffer(b);
}
bool GuiView::saveBufferEncrypted(Buffer & b)
{
FileName fname = b.fileName();
// Switch to this Buffer.
setBuffer(&b);
// No argument? Ask user through dialog.
// FIXME UNICODE
FileDialog dlg(qt_("Choose a filename to export document"),
LFUN_BUFFER_WRITE_AS);
dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("Templates|#T#t"), toqstr(lyxrc.template_path));
if (!isLyXFileName(fname.absFileName()))
fname.changeExtension(".lyx");
FileDialog::Result result =
dlg.save(toqstr(fname.onlyPath().absFileName()),
QStringList(qt_("LyX Documents (*.lyx)")),
toqstr(fname.onlyFileName()));
if (result.first == FileDialog::Later)
return false;
fname.set(fromqstr(result.second));
if (fname.empty())
return false;
if (!isLyXFileName(fname.absFileName()))
fname.changeExtension(".lyx");
// fname is now the new Buffer location.
if (FileName(fname).exists()) {
docstring const file = makeDisplayPath(fname.absFileName(), 30);
docstring text = bformat(_("The document %1$s already "
"exists.\n\nDo you want to "
"overwrite that document?"),
file);
int const ret = Alert::prompt(_("Overwrite document?"),
text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel"));
switch (ret) {
case 0: break;
case 1: break;
case 2: return false;
}
}
FileName oldauto = b.getAutosaveFileName();
// bring the autosave file with us, just in case.
b.moveAutosaveFile(oldauto);
stringbuf stringBuffer(ios::out|ios::trunc);
ostream stream(&stringBuffer);
if (!saveBuffer(b, &stream)) {
return false;
}
// the file has now been saved to the new location.
// we need to check that the locations of child buffers
// are still valid.
b.checkChildBuffers();
// get password
GuiEncryptionDialog pwddlg;
pwddlg.setWindowTitle(qt_("Enter Password"));
pwddlg.exec();
if (pwddlg.result() != QDialog::Accepted)
return false;
QString pwd = pwddlg.password();
pwddlg.setWindowTitle(qt_("Enter Password again"));
pwddlg.clearPassword();
pwddlg.exec();
if (pwddlg.result() != QDialog::Accepted)
return false;
QString pwd2 = pwddlg.password();
if (pwd != pwd2) {
Alert::error(_("Password"), _("Passwords do not match"));
return false;
}
string fileString = stringBuffer.str();
QByteArray data(fileString.c_str(), fileString.size());
CryptographicEncryption enc;
QByteArray key = enc.stringToKey(pwd);
QByteArray encrypted;
if (!enc.encyrpt(data, &encrypted, key)) {
Alert::error(_("Encryption"), _("Error when encrypting file"));
return false;
}
// check
QByteArray decrypted;
if (!enc.decyrpt(encrypted, &decrypted, key) || data != decrypted) {
Alert::error(_("Encryption"), _("Error when verifying encrypted file"));
return false;
}
QString guessStr = toqstr(FileName::encryptionPrefix(LYX_ENC_VERSION, CryptographicEncryption::Password));
QByteArray bytestoSave = guessStr.toAscii() + encrypted;
QFile file(toqstr(fname.absFileName()));
if (file.open(QIODevice::WriteOnly)) {
file.write(bytestoSave);
}
return true;
}
bool GuiView::hideWorkArea(GuiWorkArea * wa)
{
return closeWorkArea(wa, false);
@ -3244,11 +3060,6 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
saveBuffer(*doc_buffer);
break;
case LFUN_BUFFER_WRITE_ENCRYPTED:
LASSERT(doc_buffer, break);
saveBufferEncrypted(*doc_buffer);
break;
case LFUN_BUFFER_WRITE_AS:
LASSERT(doc_buffer, break);
renameBuffer(*doc_buffer, cmd.argument());

View File

@ -363,9 +363,7 @@ private:
*/
bool renameBuffer(Buffer & b, docstring const & newname);
///
bool saveBuffer(Buffer & b, std::ostream* stream = 0);
/// Gets a new filename and saves the buffer encrypted
bool saveBufferEncrypted(Buffer & b);
bool saveBuffer(Buffer & b);
/// closes a workarea, if close_buffer is true the buffer will
/// also be released, otherwise the buffer will be hidden.
bool closeWorkArea(GuiWorkArea * wa, bool close_buffer);

View File

@ -78,7 +78,6 @@ SOURCEFILES = \
GuiDelimiter.cpp \
GuiDialog.cpp \
GuiDocument.cpp \
GuiEncryptionDialog.cpp \
GuiErrorList.cpp \
GuiERT.cpp \
GuiExternal.cpp \
@ -189,7 +188,6 @@ MOCHEADER = \
GuiDelimiter.h \
GuiDialog.h \
GuiDocument.h \
GuiEncryptionDialog.h \
GuiErrorList.h \
GuiERT.h \
GuiExternal.h \

View File

@ -1,182 +0,0 @@
// -*- C++ -*-
/**
* \file CryptographicEncryption.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "CryptographicEncryption.h"
#include <QDataStream>
#ifdef LYX_ENCRYPTION
#include <openssl/aes.h>
#include <openssl/evp.h>
#endif
namespace lyx {
namespace support {
CryptographicEncryption::CryptographicEncryption()
{
}
int CryptographicEncryption::blockAlign(int blockSize, QByteArray& bytes)
{
int pad = 2 * blockSize - (bytes.size() % blockSize); // pad at least one block
bytes.append(QByteArray(pad, (char)pad));
return pad;
}
int CryptographicEncryption::blockDealign(QByteArray& bytes)
{
int size = bytes.size();
if (size == 0)
return 0;
char padded = bytes.at(size - 1);
bytes.resize(size - padded);
return padded;
}
bool CryptographicEncryption::aesEnryption(QByteArray const & in, QByteArray* out, QByteArray const & key, bool encrypt)
{
#ifndef LYX_ENCRYPTION
(void) in;
(void) out;
(void) key;
(void) encrypt;
return false;
#else
if (!out)
return false;
int keySize = key.size();
if (keySize != 16 && keySize != 24 && keySize != 32) {
return false;
}
// AES needs aligned data, but we must not touch already encrypted data
QByteArray aligned = in;
if (encrypt) {
blockAlign(AES_BLOCK_SIZE, aligned);
}
if ((aligned.size() % AES_BLOCK_SIZE) != 0) {
return false;
}
*out = QByteArray(aligned.size(), 0);
AES_KEY aeskey;
if (encrypt)
AES_set_encrypt_key((unsigned char*)key.constData(), keySize * 8, &aeskey);
else
AES_set_decrypt_key((unsigned char*)key.constData(), keySize * 8, &aeskey);
// use some arbitrary start values
unsigned char iv[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
AES_cbc_encrypt((unsigned char*)aligned.constData(),
(unsigned char*)out->data(),
aligned.size(), &aeskey, iv,
(encrypt ? AES_ENCRYPT : AES_DECRYPT));
if (!encrypt)
blockDealign(*out);
return true;
#endif
}
QByteArray CryptographicEncryption::hash(QByteArray const & bytes, QCryptographicHash::Algorithm algorithm)
{
QCryptographicHash hashAlgo(algorithm);
hashAlgo.addData(bytes);
return hashAlgo.result();
}
bool CryptographicEncryption::encyrpt(QByteArray const & plain, QByteArray* encrypted, QByteArray const & key)
{
if (!encrypted)
return false;
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_4_6);
stream << plain;
stream << hash(plain, QCryptographicHash::Md5);
if (!aesEnryption(bytes, encrypted, key, true)) {
encrypted->clear();
return false;
}
return true;
}
bool CryptographicEncryption::decyrpt(QByteArray const & encrypted, QByteArray* plain, QByteArray const & key)
{
if (!plain)
return false;
QByteArray bytes;
if (!aesEnryption(encrypted, &bytes, key, false))
return false;
QByteArray decryptedHash;
QDataStream stream(bytes);
stream.setVersion(QDataStream::Qt_4_6);
stream >> *plain;
stream >> decryptedHash;
if (decryptedHash != hash(*plain, QCryptographicHash::Md5)) {
plain->clear();
return false;
}
return true;
}
QByteArray CryptographicEncryption::bytesToKey(QByteArray const & bytes)
{
#ifndef LYX_ENCRYPTION
(void) bytes;
return QByteArray();
#else
const char* in = bytes.constData();
int iterations = 10000; // here we could adjust our paranoija
unsigned char out[64];
PKCS5_PBKDF2_HMAC_SHA1(in, bytes.size(), 0, 0, iterations, 32, out);
return QByteArray((const char*) out, 32);
#endif
}
QByteArray CryptographicEncryption::stringToKey(QString const & str)
{
QByteArray utf8 = str.toUtf8();
return bytesToKey(utf8);
}
}
}

View File

@ -1,48 +0,0 @@
// -*- C++ -*-
/**
* \file CryptographicEncryption.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*/
#ifndef CRYPTOCRAPHIC_ENCYPTION_H
#define CRYPTOCRAPHIC_ENCYPTION_H
#include <QCryptographicHash>
namespace lyx {
namespace support {
class CryptographicEncryption
{
public:
CryptographicEncryption();
enum Keytype {
Password = 0,
KeytypeCount
};
bool encyrpt(QByteArray const & plain, QByteArray * encrypted, QByteArray const & key);
bool decyrpt(QByteArray const & encrypted, QByteArray * plain, QByteArray const & key);
QByteArray bytesToKey(QByteArray const &);
QByteArray stringToKey(QString const &);
private:
int blockAlign(int blockSize, QByteArray& bytes);
int blockDealign(QByteArray& bytes);
QByteArray hash(QByteArray const & bytes, QCryptographicHash::Algorithm);
bool aesEnryption(QByteArray const & in, QByteArray* out, QByteArray const & key, bool encrypt);
};
}
}
#endif

View File

@ -922,12 +922,6 @@ string FileName::guessFormatFromContents() const
else if (contains(str, "BITPIX"))
format = "fits";
else if (contains(str, encryptionGuessString())) {
string ver = token(str, '-', 1);
string key = token(str, '-', 2);
format = encryptionGuessString() + "-" + ver + "-" + key;
}
}
// Dia knows also compressed form
@ -952,57 +946,6 @@ bool FileName::isZippedFile() const
}
bool FileName::isEncryptedFile() const
{
string const type = guessFormatFromContents();
string const guess = encryptionGuessString();
return toqstr(type).contains(toqstr(guess));
}
std::string FileName::encryptionGuessString()
{
return "LyXEncrypted";
}
std::string FileName::encryptionPrefix(int version, int keytype)
{
// A encrypted file starts with the bytes "LyXEncrypted-001-001-"
// the first number describes the encryption version which could
// change with the time. the second number describes how the key
// is generated, ATM only passwords are supported.
QString guess = toqstr(encryptionGuessString());
QString vstr = QString::number(version);
QString kstr = QString::number(keytype);
vstr = vstr.rightJustified(3, '0');
kstr = kstr.rightJustified(3, '0');
return fromqstr(guess + "-" + vstr + "-" + kstr + "-");
}
int FileName::encryptionVersion() const
{
string const type = guessFormatFromContents();
string ver = token(type, '-', 1);
bool ok = false;
int version = toqstr(ver).toInt(&ok);
if (!ok)
return -1;
return version;
}
int FileName::encryptionKeytype() const
{
string const type = guessFormatFromContents();
string ver = token(type, '-', 2);
bool ok = false;
int keytype = toqstr(ver).toInt(&ok);
if (!ok)
return -1;
return keytype;
}
docstring const FileName::relPath(string const & path) const
{
// FIXME UNICODE

View File

@ -178,16 +178,6 @@ public:
/// check for zipped file
bool isZippedFile() const;
/// check for zipped file
bool isEncryptedFile() const;
/// string which encypted LyX files starts
static std::string encryptionGuessString();
static std::string encryptionPrefix(int version, int keytype);
/// get version from guessbytes
int encryptionVersion() const;
/// get method how the key is generated
int encryptionKeytype() const;
static FileName fromFilesystemEncoding(std::string const & name);
/// (securely) create a temporary file with the given mask.
/// \p mask must be in filesystem encoding, if it contains a

View File

@ -38,8 +38,6 @@ liblyxsupport_a_SOURCES = \
convert.cpp \
convert.h \
copied_ptr.h \
CryptographicEncryption.h \
CryptographicEncryption.cpp \
debug.cpp \
debug.h \
docstream.cpp \