changeset 465:88dfe16a0bb9

Implement certificatelist saving
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 23 Apr 2014 15:34:53 +0000
parents 2e100d3e414a
children 0d71ce440bcc
files ui/createcertlistdialog.cpp ui/createcertlistdialog.h ui/l10n/administrator_de_DE.ts ui/l10n/trustbridge_de_DE.ts
diffstat 4 files changed, 264 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/ui/createcertlistdialog.cpp	Wed Apr 23 15:33:42 2014 +0000
+++ b/ui/createcertlistdialog.cpp	Wed Apr 23 15:34:53 2014 +0000
@@ -30,7 +30,11 @@
     setWindowTitle(tr("Save certificate list"));
     setupGUI();
     resize(500, 200);
-    mCertFile->setText(mAdminWindow->settings()->value("LastCert", QString()).toString());
+    mKeyFile->setText(mAdminWindow->settings()->value("LastKey", QString()).toString());
+    mSaveDir->setText(mAdminWindow->settings()->value("LastOutputDir", QString()).toString());
+    if (!mKeyFile->text().isEmpty()) {
+        loadKeyFile(mKeyFile->text());
+    }
 }
 
 void CreateCertListDialog::setupGUI()
@@ -58,15 +62,15 @@
     headerLayout->addWidget(headerSeparator);
     headerLayout->insertSpacing(3, 10);
 
-    QLabel *certLabel = new QLabel("Select signature certificate (secret key):");
+    QLabel *certLabel = new QLabel("Select signing key:");
     QLabel *saveLabel = new QLabel("Select output folder:");
     labelLayout->addWidget(certLabel);
     labelLayout->addWidget(saveLabel);
 
-    mCertFile = new QLineEdit();
-    mSaveFile = new QLineEdit();
-    fieldLayout->addWidget(mCertFile);
-    fieldLayout->addWidget(mSaveFile);
+    mKeyFile = new QLineEdit();
+    mSaveDir = new QLineEdit();
+    fieldLayout->addWidget(mKeyFile);
+    fieldLayout->addWidget(mSaveDir);
 
     QPushButton *certSelect = new QPushButton("...");
     certSelect->setFixedWidth(30);
@@ -117,15 +121,8 @@
     QMessageBox::warning(this, tr("Error!"), msg);
 }
 
-void CreateCertListDialog::openCertificateSelect()
+void CreateCertListDialog::loadKeyFile(const QString& fileName)
 {
-    QString certFile = QFileDialog::getOpenFileName(
-        this, tr("Select certificate"), mCertFile->text().isEmpty() ?
-        QDir::homePath() : mCertFile->text(), "*.pem");
-    mCertFile->setText(certFile);
-
-    mAdminWindow->settings()->setValue("LastCert", certFile);
-
     if (mPk != NULL) {
         pk_free(mPk);
         delete mPk;
@@ -134,29 +131,118 @@
 
     mPk = new pk_context;
     pk_init(mPk);
-    int ret = pk_parse_keyfile(mPk, mCertFile->text().toLocal8Bit().constData(), "");
+    int ret = pk_parse_keyfile(mPk, mKeyFile->text().toLocal8Bit().constData(), "");
 
     if (ret != 0) {
         showErrorMessage(tr("Failed to load certificate: %1")
                 .arg(getPolarSSLErrorMsg(ret)));
+        pk_free(mPk);
+        delete mPk;
+        mPk = NULL;
         return;
     }
+
+    /* Check that it is a 3072 bit RSA key as specified */
+    if (!mPk->pk_info || pk_get_size(mPk) != 3072 ||
+            mPk->pk_info->type != POLARSSL_PK_RSA) {
+        showErrorMessage(tr("Only 3072 bit RSA keys are supported by the current format."));
+        pk_free(mPk);
+        delete mPk;
+        mPk = NULL;
+        return;
+    }
+}
+
+void CreateCertListDialog::openCertificateSelect()
+{
+    QString keyFile = QFileDialog::getOpenFileName(
+        this, tr("Select certificate"), mKeyFile->text().isEmpty() ?
+        QDir::homePath() : mKeyFile->text(), "*.pem");
+    mKeyFile->setText(keyFile);
+
+    mAdminWindow->settings()->setValue("LastKey", keyFile);
+    loadKeyFile(keyFile);
+
+    return;
 }
 
 void CreateCertListDialog::openSaveLocation()
 {
-    QString saveFile = QFileDialog::getExistingDirectory(
-        this, tr("Select target location"), QDir::homePath());
-    mSaveFile->setText(saveFile);
+    QString saveDir = QFileDialog::getExistingDirectory(
+        this, tr("Select target location"),
+        mSaveDir->text().isEmpty() ? QDir::homePath() : mSaveDir->text());
+    mAdminWindow->settings()->setValue("LastOutputDir", saveDir);
+    mSaveDir->setText(saveDir);
+}
+
+CreateCertListDialog::~CreateCertListDialog()
+{
+    if (mPk) {
+        pk_free(mPk);
+        delete mPk;
+        mPk = NULL;
+    }
 }
 
 void CreateCertListDialog::createList()
 {
-    //entropy_context mEntropy;
-    //ctr_drbg_context mCtr_drbg;
+    if (!mPk) {
+        showErrorMessage(tr("Please select a valid rsa key."));
+    }
+    if (mSaveDir->text().isEmpty()) {
+        showErrorMessage(tr("Please select an output location first."));
+    }
 
-    qDebug() << "and now create the certificate list using:";
-    qDebug() << "certificate: " << mCertFile->text();
-    qDebug() << "target" << mSaveFile->text();
-    // TODO
+    QDateTime currentDateTimeUtc = QDateTime::currentDateTimeUtc();
+
+    /* Build up the list data */
+    QByteArray listData("F:1\r\n");
+    listData.append(currentDateTimeUtc.toString(Qt::ISODate) + "\r\n");
+
+    foreach (const Certificate& cert, mAdminWindow->certificates()) {
+        listData.append(QString::fromLatin1("D:") + cert.base64Line() + "\r\n");
+    }
+
+    QByteArray signature = rsaSignSHA256Hash(sha256sum(listData), mPk);
+    listData.prepend("\r\n");
+    listData.prepend(signature.toBase64());
+    listData.prepend("S:");
+
+    QString fileName = QString::fromLatin1("certificates-")
+            .append(currentDateTimeUtc.toString(("yyyyMMddHHmmss")))
+            .append(".txt");
+
+    QString filePath = mSaveDir->text().append("/").append(fileName);
+
+    QFile outputFile(filePath);
+
+    if (!outputFile.open(QIODevice::WriteOnly)) {
+        showErrorMessage(tr("Failed to open output file %1").arg(filePath));
+        return;
+    }
+
+    if (outputFile.write(listData) != listData.size()) {
+        showErrorMessage(tr("Failed to write certificate list."));
+        return;
+    }
+
+    /* Archive the list */
+    QDir archiveDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
+    if (!archiveDir.mkpath(archiveDir.path())) {
+        showErrorMessage(tr("Failed to create archive location."));
+        return;
+    }
+
+    if (!outputFile.copy(archiveDir.filePath(fileName))) {
+        showErrorMessage(tr("Failed Archive a copy."));
+        return;
+    }
+
+    if (!outputFile.copy(archiveDir.filePath("current_certificates.txt"))) {
+        showErrorMessage(tr("Failed to write current_certificates file."));
+        return;
+    }
+
+    QMessageBox::information(this, "", tr("Saved certificate list:\n%1").arg(fileName));
+    close();
 }
--- a/ui/createcertlistdialog.h	Wed Apr 23 15:33:42 2014 +0000
+++ b/ui/createcertlistdialog.h	Wed Apr 23 15:34:53 2014 +0000
@@ -29,16 +29,32 @@
      * process
      * */
     CreateCertListDialog(AdministratorWindow *parent);
+    ~CreateCertListDialog();
 
 private:
     void setupGUI();
 
-    QLineEdit *mCertFile;
-    QLineEdit *mSaveFile;
+    QLineEdit *mKeyFile;
+    QLineEdit *mSaveDir;
     AdministratorWindow *mAdminWindow;
 
     pk_context *mPk;
 
+    /** @brief show an error message with QMessageBox
+     *
+     * @param [in] msg The message to show
+     */
+    void showErrorMessage(const QString &msg);
+
+    /** @brief load a file into mPk
+     *
+     * If the file is not a valid key or an error
+     * occurs mPk will be NULL after a call to this function.
+     *
+     * @param [in] the file to load
+     */
+    void loadKeyFile(const QString& fileName);
+
 private slots:
     /** @brief Open the certificate selection dialog and parse the certificate
      *
@@ -49,14 +65,11 @@
     void openSaveLocation();
     /** @brief create a valid certificate list file
      *
-     * The contents of the certificate list is the certificatelist
-     * of the adminWindow. It is signed with the currently
+     * The contents of the certificate list are the certificates
+     * shown in the adminWindow. It is signed with the currently
      * loaded certificate in mPk. On errors the user is
      * informed with showErrorMessage */
     void createList();
-
-    /** @brief show an error message with QMessageBox */
-    void showErrorMessage(const QString&msg);
 };
 
 #endif // CREATECERTLISTDIALOG_H
--- a/ui/l10n/administrator_de_DE.ts	Wed Apr 23 15:33:42 2014 +0000
+++ b/ui/l10n/administrator_de_DE.ts	Wed Apr 23 15:34:53 2014 +0000
@@ -79,7 +79,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../administratorwindow.cpp" line="144"/>
+        <location filename="../administratorwindow.cpp" line="142"/>
         <source>Select certificate list file</source>
         <translation type="unfinished"></translation>
     </message>
@@ -117,7 +117,7 @@
         <translation type="vanished">Zertifikatslistendatei auswählen</translation>
     </message>
     <message>
-        <location filename="../administratorwindow.cpp" line="165"/>
+        <location filename="../administratorwindow.cpp" line="161"/>
         <source>Select certificate</source>
         <translation>Zertifikat auswählen</translation>
     </message>
@@ -177,7 +177,7 @@
     <name>CreateCertListDialog</name>
     <message>
         <location filename="../createcertlistdialog.cpp" line="30"/>
-        <location filename="../createcertlistdialog.cpp" line="48"/>
+        <location filename="../createcertlistdialog.cpp" line="52"/>
         <source>Save certificate list</source>
         <translation>Zertifikatsliste speichern</translation>
     </message>
@@ -195,46 +195,92 @@
         <translation type="obsolete">Liste signieren</translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="50"/>
+        <location filename="../createcertlistdialog.cpp" line="54"/>
         <source>Save all managed root certificates in a new, signed certificate list.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="80"/>
+        <location filename="../createcertlistdialog.cpp" line="84"/>
         <source>In addition, each certificate list will be saved automatically in the archive directory:
 </source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="90"/>
+        <location filename="../createcertlistdialog.cpp" line="94"/>
         <source>Save list</source>
         <translation type="unfinished">Liste speichern</translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="92"/>
+        <location filename="../createcertlistdialog.cpp" line="96"/>
         <source>Cancel</source>
         <translation>Abbrechen</translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="117"/>
+        <location filename="../createcertlistdialog.cpp" line="121"/>
         <source>Error!</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="123"/>
+        <location filename="../createcertlistdialog.cpp" line="159"/>
         <source>Select certificate</source>
         <translation type="unfinished">Zertifikat auswählen</translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="140"/>
+        <location filename="../createcertlistdialog.cpp" line="137"/>
         <source>Failed to load certificate: %1</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../createcertlistdialog.cpp" line="149"/>
+        <location filename="../createcertlistdialog.cpp" line="148"/>
+        <source>Only 3072 bit RSA keys are supported by the current format.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="172"/>
         <source>Select target location</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="190"/>
+        <source>Please select a valid rsa key.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="193"/>
+        <source>Please select an output location first.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="220"/>
+        <source>Failed to open output file %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="225"/>
+        <source>Failed to write certificate list.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="232"/>
+        <source>Failed to create archive location.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="237"/>
+        <source>Failed Archive a copy.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="242"/>
+        <source>Failed to write current_certificates file.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../createcertlistdialog.cpp" line="246"/>
+        <source>Saved certificate list:
+%1</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>CreateInstallerDialog</name>
--- a/ui/l10n/trustbridge_de_DE.ts	Wed Apr 23 15:33:42 2014 +0000
+++ b/ui/l10n/trustbridge_de_DE.ts	Wed Apr 23 15:34:53 2014 +0000
@@ -48,40 +48,40 @@
 <context>
     <name>Downloader</name>
     <message>
-        <location filename="../downloader.cpp" line="80"/>
+        <location filename="../downloader.cpp" line="82"/>
         <source>Invalid response</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../downloader.cpp" line="115"/>
-        <location filename="../downloader.cpp" line="123"/>
-        <location filename="../downloader.cpp" line="162"/>
-        <location filename="../downloader.cpp" line="174"/>
+        <location filename="../downloader.cpp" line="117"/>
+        <location filename="../downloader.cpp" line="125"/>
+        <location filename="../downloader.cpp" line="164"/>
+        <location filename="../downloader.cpp" line="176"/>
         <source>Connection lost</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../downloader.cpp" line="137"/>
+        <location filename="../downloader.cpp" line="139"/>
         <source>Invalid response from the server</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../downloader.cpp" line="200"/>
+        <location filename="../downloader.cpp" line="202"/>
         <source>Failed to initialize SSL Module.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../downloader.cpp" line="207"/>
+        <location filename="../downloader.cpp" line="209"/>
         <source>Failed to connect.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../downloader.cpp" line="212"/>
+        <location filename="../downloader.cpp" line="214"/>
         <source>Connected</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../downloader.cpp" line="262"/>
+        <location filename="../downloader.cpp" line="274"/>
         <source>Closing</source>
         <translation type="unfinished"></translation>
     </message>
@@ -162,119 +162,161 @@
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="230"/>
+        <source>New Software version is available.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="231"/>
+        <source>Do you want to install the new Version?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="249"/>
         <source>Check for Updates</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="232"/>
-        <location filename="../mainwindow.cpp" line="267"/>
-        <location filename="../mainwindow.cpp" line="332"/>
+        <location filename="../mainwindow.cpp" line="251"/>
+        <location filename="../mainwindow.cpp" line="286"/>
+        <location filename="../mainwindow.cpp" line="358"/>
         <source>Quit</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="250"/>
+        <location filename="../mainwindow.cpp" line="269"/>
         <source>TrustBridge</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="258"/>
+        <location filename="../mainwindow.cpp" line="277"/>
         <source>Menu</source>
         <translation>Menü</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="260"/>
+        <location filename="../mainwindow.cpp" line="279"/>
         <source>Force Update</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="261"/>
-        <location filename="../mainwindow.cpp" line="318"/>
+        <location filename="../mainwindow.cpp" line="280"/>
+        <location filename="../mainwindow.cpp" line="344"/>
         <source>Settings</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="262"/>
+        <location filename="../mainwindow.cpp" line="281"/>
         <source>Statusdialog</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="264"/>
+        <location filename="../mainwindow.cpp" line="283"/>
         <source>Help</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="265"/>
+        <location filename="../mainwindow.cpp" line="284"/>
         <source>About</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="295"/>
+        <location filename="../mainwindow.cpp" line="315"/>
         <source>Managed Certificates</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="319"/>
+        <location filename="../mainwindow.cpp" line="321"/>
+        <location filename="../mainwindow.cpp" line="442"/>
+        <location filename="../mainwindow.cpp" line="472"/>
+        <source>Current List Date: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="345"/>
         <source>Autoupdate</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="320"/>
+        <location filename="../mainwindow.cpp" line="346"/>
         <source>Autostart</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="328"/>
+        <location filename="../mainwindow.cpp" line="354"/>
         <source>Install selected</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="342"/>
+        <location filename="../mainwindow.cpp" line="368"/>
         <source>Details</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="343"/>
+        <location filename="../mainwindow.cpp" line="369"/>
         <source>Subject Common Name:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="344"/>
+        <location filename="../mainwindow.cpp" line="370"/>
         <source>Subject Organisation:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="345"/>
+        <location filename="../mainwindow.cpp" line="371"/>
         <source>Issuer Common Name:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="346"/>
+        <location filename="../mainwindow.cpp" line="372"/>
         <source>Issuer Organisation:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="347"/>
+        <location filename="../mainwindow.cpp" line="373"/>
         <source>Valid from:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="348"/>
+        <location filename="../mainwindow.cpp" line="374"/>
         <source>Valid to:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="349"/>
+        <location filename="../mainwindow.cpp" line="375"/>
         <source>Fingerprint:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="496"/>
+        <location filename="../mainwindow.cpp" line="474"/>
+        <source>New List Date: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="478"/>
+        <source>New certificates to install</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="483"/>
+        <source>New certificates to remove</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="488"/>
+        <source>Old certificates to install</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="493"/>
+        <source>Old certificates to remove</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="579"/>
         <source>Error executing update</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="538"/>
+        <location filename="../mainwindow.cpp" line="621"/>
         <source>Installing certificates...</source>
         <translation type="unfinished"></translation>
     </message>

http://wald.intevation.org/projects/trustbridge/