consolidate Password and Pin input dialogs

change storage type of passwords from char[] to QByteArray
Create PwDialog class and drop passWrite and passRead
Create Passwd class derived from QBytearray
move PKCS12 password input to PwDialog
This commit is contained in:
Christian Hohnstaedt 2011-04-19 07:09:08 +02:00
parent 257641be16
commit b622e64209
27 changed files with 501 additions and 537 deletions

View File

@ -8,7 +8,7 @@ MOCNAMES=db_crl db_key db_temp db_x509 db_x509req db_x509super db_base db_token\
pki_base pki_multi pki_evp pki_scard pass_info pki_pkcs7
NAMES=$(MOCNAMES) asn1int oid x509rev asn1time \
x509v3ext func load_obj main x509name db import \
pk11_attribute pkcs11 pkcs11_lib
pk11_attribute pkcs11 pkcs11_lib Passwd
OBJS=$(patsubst %, %.o, $(NAMES)) $(patsubst %, moc_%.o, $(MOCNAMES))

24
lib/Passwd.cpp Normal file
View File

@ -0,0 +1,24 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2011 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include <QtCore/QByteArray>
#include "Passwd.h"
void Passwd::cleanse()
{
memset(data(), 0, size());
}
Passwd::~Passwd()
{
Passwd::cleanse();
}
unsigned char *Passwd::constUchar() const
{
return size() ? (unsigned char *)constData() : NULL;
}

29
lib/Passwd.h Normal file
View File

@ -0,0 +1,29 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2011 Christian Hohnstaedt.
*
* All rights reserved.
*/
#ifndef __PASSWD_H
#define __PASSWD_H
#include <QtCore/QByteArray>
class Passwd: public QByteArray
{
public:
void cleanse();
~Passwd();
unsigned char *constUchar() const;
Passwd & operator= (const char *p)
{
return (Passwd&)QByteArray::operator=(p);
}
Passwd & operator= (const QByteArray &other)
{
return (Passwd&)QByteArray::operator=(other);
}
};
#endif

View File

@ -23,7 +23,7 @@
#include "ui_NewKey.h"
#include "pkcs11.h"
#include "widgets/MainWindow.h"
#include "widgets/PwDialog.h"
#include "widgets/ExportKey.h"
#include "widgets/KeyDetail.h"
#include "widgets/NewKey.h"
@ -301,9 +301,9 @@ void db_key::store()
if (dlg->exportPrivate->isChecked() && !targetKey->isToken()) {
pki_evp *evpKey = (pki_evp *)targetKey;
if (dlg->exportPkcs8->isChecked()) {
evpKey->writePKCS8(fname, enc, &MainWindow::passWrite, pem);
evpKey->writePKCS8(fname, enc, PwDialog::pwCallback, pem);
} else {
evpKey->writeKey(fname, enc, &MainWindow::passWrite, pem);
evpKey->writeKey(fname, enc, PwDialog::pwCallback, pem);
}
} else {
targetKey->writePublic(fname, pem);

View File

@ -10,13 +10,14 @@
#include "pki_pkcs7.h"
#include "pki_evp.h"
#include "pki_scard.h"
#include "pass_info.h"
#include "widgets/CertDetail.h"
#include "widgets/CertExtend.h"
#include "widgets/ExportDialog.h"
#include "widgets/MainWindow.h"
#include "widgets/PwDialog.h"
#include "ui_TrustState.h"
#include "ui_CaProperties.h"
#include "ui_PassWrite.h"
#include "ui_About.h"
#include "ui_Revoke.h"
#include <QtGui/QMessageBox>
@ -484,34 +485,19 @@ void db_x509::newCert(NewX509 *dlg)
cert->setTrust(1);
#ifdef WG_QA_SERIAL
} else if (dlg->selfQASignRB->isChecked()){
Ui::PassWrite ui;
QDialog *dlg1 = new QDialog(mainwin);
ui.setupUi(dlg1);
ui.image->setPixmap( *MainWindow::keyImg );
ui.description->setText(tr("Please enter the new hexadecimal secret number for the QA process."));
dlg1->setWindowTitle(XCA_TITLE);
ui.passA->setFocus();
Passwd pass;
pass_info p(XCA_TITLE, tr("Please enter the new hexadecimal secret number for the QA process."));
#if 0
ui.passA->setValidator(new QRegExpValidator(QRegExp("[0-9a-fA-F]*"),
ui.passA));
ui.passB->setValidator(new QRegExpValidator(QRegExp("[0-9a-fA-F]*"),
ui.passB));
QString A = "x", B="";
while (dlg1->exec()) {
A = ui.passA->text();
B = ui.passB->text();
if (A==B)
break;
else
QMessageBox::warning(mainwin, XCA_TITLE,
tr("The two secret numbers don't match."));
}
delete dlg1;
if (A!=B)
#endif
if (PwDialog::execute(&p, &pass, true) != 1)
throw errorEx(tr("The QA process has been terminated by the user."));
signcert = cert;
signkey = clientkey;
serial.setHex(A);
serial.setHex(pass);
cert->setTrust(2);
#endif
} else {
@ -824,8 +810,7 @@ void db_x509::writePKCS12(pki_x509 *cert, QString s, bool chain)
if (s.isEmpty())
return;
s = QDir::convertSeparators(s);
pki_pkcs12 *p12 = new pki_pkcs12(cert->getIntName(), cert, privkey,
MainWindow::passWrite);
pki_pkcs12 *p12 = new pki_pkcs12(cert->getIntName(), cert, privkey);
pki_x509 *signer = cert->getSigner();
while ((signer != NULL ) && (signer != cert) && chain) {
p12->addCaCert(signer);

View File

@ -12,20 +12,25 @@
#include <QtCore/QObject>
#include "base.h"
#define E_PASSWD 1
class errorEx
{
private:
QString msg;
public:
errorEx(QString txt = "", QString className = "")
int info;
errorEx(QString txt = "", QString className = "", int inf = 0)
{
msg = txt;
if (!className.isEmpty())
msg += " (" + className + ")";
info = inf;
}
errorEx(const errorEx &e)
{
msg = e.msg;
info = e.info;
}
void appendString(QString s)
{

View File

@ -13,6 +13,8 @@
#include <openssl/objects.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#if defined(Q_WS_MAC)
#include <QtGui/QDesktopServices>
@ -336,8 +338,9 @@ void _openssl_error(const QString txt, const char *file, int line)
while (int i = ERR_get_error() ) {
error += QString(ERR_error_string(i, NULL)) + "\n";
fprintf(stderr, CCHAR(QString("OpenSSL error (%1:%2) : %3\n").
arg(file).arg(line).arg(ERR_error_string(i, NULL))));
fputs(CCHAR(QString("OpenSSL error (%1:%2) : %3\n").
arg(file).arg(line).arg(ERR_error_string(i, NULL))),
stderr);
}
if (!error.isEmpty()) {
if (!txt.isEmpty())
@ -378,3 +381,45 @@ void inc_progress_bar(int, int, void *p)
}
}
static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BUF_MEM *bm = (BUF_MEM *)b->ptr;
if (!bm->data || !(b->flags & BIO_FLAGS_MEM_RDONLY))
return BIO_s_mem()->ctrl(b, cmd, num, ptr);
switch (cmd) {
case BIO_C_FILE_SEEK:
if (num > bm->max)
num = bm->max;
bm->data -= (bm->max - bm->length) - num;
bm->length = bm->max - num;
case BIO_C_FILE_TELL:
return bm->max - bm->length;
}
return BIO_s_mem()->ctrl(b, cmd, num, ptr);
}
void BIO_seekable_romem(BIO *b)
{
static BIO_METHOD *mymeth = NULL;
static BIO_METHOD _meth;
if (!(b->flags & BIO_FLAGS_MEM_RDONLY) ||
(b->method->type != BIO_TYPE_MEM))
{
return;
}
if (!mymeth) {
_meth = *BIO_s_mem();
_meth.ctrl = mem_ctrl;
mymeth = &_meth;
}
b->method = mymeth;
}
BIO *BIO_QBA_mem_buf(QByteArray &a)
{
BIO *b = BIO_new_mem_buf(a.data(), a.size());
BIO_seekable_romem(b);
return b;
}

View File

@ -45,6 +45,7 @@ bool _ign_openssl_error(const QString txt, const char *file, int line);
QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char**), const void*);
void *d2i_bytearray(void *(*d2i)(void*, unsigned char**, long),
QByteArray &ba);
BIO *BIO_QBA_mem_buf(QByteArray &a);
#define I2D_VOID(a) ((int (*)(const void *, unsigned char **))(a))
#define D2I_VOID(a) ((void *(*)(void *, unsigned char **, long))(a))

View File

@ -12,7 +12,8 @@
#include "pki_pkcs7.h"
#include "pki_pkcs12.h"
#include "pki_multi.h"
#include "widgets/MainWindow.h"
#include "pki_temp.h"
#include "pki_crl.h"
load_base::load_base()
{
@ -108,7 +109,7 @@ load_pkcs12::load_pkcs12()
pki_base * load_pkcs12::loadItem(QString s)
{
pki_base *p12 = new pki_pkcs12(s, MainWindow::passRead);
pki_base *p12 = new pki_pkcs12(s);
return p12;
}

View File

@ -91,9 +91,10 @@ int main( int argc, char *argv[] )
a.setMainwin(mw);
mw->read_cmdline();
if (mw->exitApp == 0) {
mw->open_default_db();
mw->show();
ret = a.exec();
if (mw->open_default_db() != 2) {
mw->show();
ret = a.exec();
}
}
} catch (errorEx &ex) {
mw->Error(ex);

View File

@ -12,6 +12,7 @@
#include "db_base.h"
#include "func.h"
#include "pass_info.h"
#include "Passwd.h"
#include <openssl/rand.h>
#include <QtGui/QMessageBox>
@ -19,6 +20,7 @@
#include <ltdl.h>
#include "ui_SelectToken.h"
#include "widgets/PwDialog.h"
pkcs11_lib_list pkcs11::libs;
@ -238,8 +240,7 @@ static QDialog *newPinPadBox()
QString pkcs11::tokenLogin(QString name, bool so, bool force)
{
char _pin[256], *pin = _pin;
int pinlen;
Passwd pin;
bool need_login;
QString text = so ?
@ -253,8 +254,7 @@ QString pkcs11::tokenLogin(QString name, bool so, bool force)
if (!need_login)
logout();
if (tokenInfo().protAuthPath()) {
pin[0] = '\0';
pinlen = 0;
pin.clear();
QDialog *pinpadbox = newPinPadBox();
pinpadbox->show();
pinPadLoginThread ppt(this, so);
@ -267,15 +267,14 @@ QString pkcs11::tokenLogin(QString name, bool so, bool force)
if (!ppt.err.isEmpty())
throw errorEx(ppt.err);
} else {
pinlen = MainWindow::passRead(pin, 256, 0, &p);
if (pinlen == -1)
if (PwDialog::execute(&p, &pin, false) != 1)
return QString();
}
login((unsigned char*)pin, pinlen, so);
login(pin.constUchar(), pin.size(), so);
} else {
return QString("");
}
return QString::fromLocal8Bit(pin, pinlen);
return QString(pin);
}
bool pkcs11::selectToken(slotid *slot, QWidget *w)
@ -331,7 +330,7 @@ static QString newPinTxt = QObject::tr(
void pkcs11::changePin(slotid slot, bool so)
{
char newPin[MAX_PASS_LENGTH], *pinp;
Passwd newPin, pinp;
QString pin;
startSession(slot, true);
@ -350,20 +349,18 @@ void pkcs11::changePin(slotid slot, bool so)
pass_info p(XCA_TITLE, msg.arg(ti.label()) + "\n" + ti.pinInfo());
p.setPin();
int newPinLen = MainWindow::passWrite(newPin, MAX_PASS_LENGTH, 0, &p);
pinp = strdup(CCHAR(pin));
if (newPinLen != -1) {
setPin((unsigned char*)pinp, pin.length(),
(unsigned char*)newPin, newPinLen);
if (PwDialog::execute(&p, &newPin, true) == 1) {
pinp = pin.toAscii();
setPin(pinp.constUchar(), pinp.size(),
newPin.constUchar(), newPin.size());
}
free(pinp);
logout();
}
void pkcs11::initPin(slotid slot)
{
char newPin[MAX_PASS_LENGTH], *pinp = NULL;
int newPinLen = 0;
Passwd newPin, pinp;
int ret = 1;
QString pin;
startSession(slot, true);
@ -377,15 +374,14 @@ void pkcs11::initPin(slotid slot)
p.setPin();
if (!ti.protAuthPath()) {
newPinLen = MainWindow::passWrite(newPin,
MAX_PASS_LENGTH, 0, &p);
ret = PwDialog::execute(&p, &newPin, true);
pinp = newPin;
}
p11slot.isValid();
if (newPinLen != -1) {
if (ret == 1) {
WAITCURSOR_START;
CK_RV rv = p11slot.p11()->C_InitPIN(session,
(unsigned char*)pinp, newPinLen);
pinp.constUchar(), pinp.size());
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_InitPIN", rv);

View File

@ -8,9 +8,10 @@
#include "pki_evp.h"
#include "pass_info.h"
#include "Passwd.h"
#include "func.h"
#include "db.h"
#include "widgets/MainWindow.h"
#include "widgets/PwDialog.h"
#include <openssl/rand.h>
#include <openssl/evp.h>
@ -20,8 +21,8 @@
#include <QtGui/QApplication>
#include <QtCore/QDir>
char pki_evp::passwd[MAX_PASS_LENGTH]={0,};
char pki_evp::oldpasswd[MAX_PASS_LENGTH]={0,};
Passwd pki_evp::passwd;
Passwd pki_evp::oldpasswd;
QString pki_evp::passHash = QString();
@ -33,28 +34,6 @@ size_t pki_evp::num_curves = 0;
unsigned char *pki_evp::curve_flags = NULL;
#endif
void pki_evp::erasePasswd()
{
memset(passwd, 0, MAX_PASS_LENGTH);
}
void pki_evp::eraseOldPasswd()
{
memset(oldpasswd, 0, MAX_PASS_LENGTH);
}
void pki_evp::setPasswd(const char *pass)
{
strncpy(passwd, pass, MAX_PASS_LENGTH);
passwd[MAX_PASS_LENGTH-1] = '\0';
}
void pki_evp::setOldPasswd(const char *pass)
{
strncpy(oldpasswd, pass, MAX_PASS_LENGTH);
oldpasswd[MAX_PASS_LENGTH-1] = '\0';
}
void pki_evp::init(int type)
{
key->type = type;
@ -207,18 +186,32 @@ QList<int> pki_evp::possibleHashNids()
return nids;
};
void pki_evp::openssl_pw_error(QString fname)
{
switch (ERR_peek_error() & 0xff000fff) {
case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT):
case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_PASSWORD_READ):
case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT):
pki_ign_openssl_error();
throw errorEx(tr("Failed to decrypt the key (bad password) ")+
fname, class_name, E_PASSWD);
}
}
void pki_evp::fromPEM_BIO(BIO *bio, QString name)
{
EVP_PKEY *pkey;
int pos;
pass_info p(XCA_TITLE, QObject::tr(
"Please enter the password to decrypt the private key."));
pass_info p(XCA_TITLE,
tr("Please enter the password to decrypt the private key.") +
" " + name);
pos = BIO_tell(bio);
pkey = PEM_read_bio_PrivateKey(bio, NULL, MainWindow::passRead, &p);
pkey = PEM_read_bio_PrivateKey(bio, NULL, PwDialog::pwCallback, &p);
openssl_pw_error(name);
if (!pkey){
pki_ign_openssl_error();
pos = BIO_seek(bio, pos);
pkey = PEM_read_bio_PUBKEY(bio, NULL, MainWindow::passRead, &p);
pkey = PEM_read_bio_PUBKEY(bio, NULL, PwDialog::pwCallback, &p);
}
if (pkey){
if (key)
@ -267,7 +260,7 @@ void pki_evp::fload(const QString fname)
{
pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the private key from file:\n%1").
arg(compressFilename(fname)));
pem_password_cb *cb = MainWindow::passRead;
pem_password_cb *cb = PwDialog::pwCallback;
FILE *fp = fopen(QString2filename(fname), "r");
EVP_PKEY *pkey;
@ -277,13 +270,11 @@ void pki_evp::fload(const QString fname)
return;
}
pkey = PEM_read_PrivateKey(fp, NULL, cb, &p);
if (!pkey) {
if (ERR_get_error() == 0x06065064) {
fclose(fp);
pki_ign_openssl_error();
throw errorEx(tr("Failed to decrypt the key (bad password) ") +
fname, class_name);
}
try {
openssl_pw_error(fname);
} catch (errorEx &err) {
fclose(fp);
throw err;
}
if (!pkey) {
pki_ign_openssl_error();
@ -368,7 +359,8 @@ EVP_PKEY *pki_evp::decryptKey() const
EVP_PKEY *tmpkey;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
char ownPassBuf[MAX_PASS_LENGTH] = "";
Passwd ownPassBuf;
int ret;
if (isPubKey()) {
unsigned char *q;
@ -383,29 +375,23 @@ EVP_PKEY *pki_evp::decryptKey() const
}
/* This key has its own password */
if (ownPass == ptPrivate) {
int ret;
pass_info pi(XCA_TITLE, tr("Please enter the password to decrypt the private key: '%1'").arg(getIntName()));
ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &pi);
if (ret < 0)
ret = PwDialog::execute(&pi, &ownPassBuf, false);
if (ret != 1)
throw errorEx(tr("Password input aborted"), class_name);
} else if (ownPass == ptBogus) { // BOGUS pass
ownPassBuf[0] = '\0';
ownPassBuf = "Bogus";
} else {
memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
//printf("Orig password: '%s' len:%d\n", passwd, strlen(passwd));
ownPassBuf = passwd;
while (md5passwd(ownPassBuf) != passHash &&
sha512passwd(ownPassBuf, passHash) != passHash)
{
int ret;
//printf("Passhash= '%s', new hash= '%s', passwd= '%s'\n",
//CCHAR(passHash), CCHAR(md5passwd(ownPassBuf)), ownPassBuf);
pass_info p(XCA_TITLE, tr("Please enter the database password for decrypting the key '%1'").arg(getIntName()));
ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &p);
if (ret < 0)
ret = PwDialog::execute(&p, &ownPassBuf, false);
if (ret != 1)
throw errorEx(tr("Password input aborted"), class_name);
}
}
//printf("Using decrypt Pass: %s\n", ownPassBuf);
p = (unsigned char *)OPENSSL_malloc(encKey.count());
check_oom(p);
pki_openssl_error();
@ -414,8 +400,9 @@ EVP_PKEY *pki_evp::decryptKey() const
memcpy(iv, encKey.constData(), 8); /* recover the iv */
/* generate the key */
EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)ownPassBuf,
strlen(ownPassBuf), 1, ckey,NULL);
EVP_BytesToKey(cipher, EVP_sha1(), iv,
ownPassBuf.constUchar(),
ownPassBuf.size(), 1, ckey, NULL);
/* we use sha1 as message digest,
* because an md5 version of the password is
* stored in the database...
@ -428,7 +415,7 @@ EVP_PKEY *pki_evp::decryptKey() const
decsize = outl;
EVP_DecryptFinal(&ctx, p + decsize , &outl);
decsize += outl;
//printf("Decrypt decsize=%d, encKey_len=%d\n", decsize, encKey_len);
//printf("Decrypt decsize=%d, encKey_len=%d\n", decsize, encKey.count() -8);
pki_openssl_error();
tmpkey = d2i_PrivateKey(key->type, NULL, &p1, decsize);
pki_openssl_error();
@ -479,30 +466,31 @@ void pki_evp::encryptKey(const char *password)
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
unsigned char iv[EVP_MAX_IV_LENGTH], *punenc, *punenc1;
unsigned char ckey[EVP_MAX_KEY_LENGTH];
char ownPassBuf[MAX_PASS_LENGTH];
Passwd ownPassBuf;
/* This key has its own, private password */
if (ownPass == ptPrivate) {
int ret;
pass_info p(XCA_TITLE, tr("Please enter the password to protect the private key: '%1'").
arg(getIntName()));
ret = MainWindow::passWrite(ownPassBuf, MAX_PASS_LENGTH, 0, &p);
if (ret < 0)
ret = PwDialog::execute(&p, &ownPassBuf, true);
if (ret != 1)
throw errorEx("Password input aborted", class_name);
} else if (ownPass == ptBogus) { // BOGUS password
ownPassBuf[0] = '\0';
ownPassBuf = "Bogus";
} else {
if (password) {
/* use the password parameter if this is a common password */
strncpy(ownPassBuf, password, MAX_PASS_LENGTH);
/* use the password parameter
* if this is a common password */
ownPassBuf = password;
} else {
int ret = 0;
memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
ownPassBuf = passwd;
pass_info p(XCA_TITLE, tr("Please enter the database password for encrypting the key"));
while (md5passwd(ownPassBuf) != passHash &&
sha512passwd(ownPassBuf, passHash) != passHash )
{
ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0,&p);
ret = PwDialog::execute(&p, &ownPassBuf, true);
if (ret < 0)
throw errorEx("Password input aborted", class_name);
}
@ -512,8 +500,9 @@ void pki_evp::encryptKey(const char *password)
/* Prepare Encryption */
memset(iv, 0, EVP_MAX_IV_LENGTH);
RAND_pseudo_bytes(iv,8); /* Generate a salt */
EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)ownPassBuf,
strlen(ownPassBuf), 1, ckey, NULL);
EVP_BytesToKey(cipher, EVP_sha1(), iv,
ownPassBuf.constUchar(),
ownPassBuf.size(), 1, ckey, NULL);
EVP_CIPHER_CTX_init (&ctx);
pki_openssl_error();
@ -702,7 +691,7 @@ QVariant pki_evp::getIcon(int id)
return QVariant(*icon[pixnum]);
}
QString pki_evp::md5passwd(const char *pass)
QString pki_evp::md5passwd(QByteArray pass)
{
EVP_MD_CTX mdctx;
@ -711,7 +700,7 @@ QString pki_evp::md5passwd(const char *pass)
int j;
unsigned char m[EVP_MAX_MD_SIZE];
EVP_DigestInit(&mdctx, EVP_md5());
EVP_DigestUpdate(&mdctx, pass, strlen(pass));
EVP_DigestUpdate(&mdctx, pass.constData(), pass.size());
EVP_DigestFinal(&mdctx, m, (unsigned*)&n);
for (j=0; j<n; j++) {
char zs[4];
@ -721,7 +710,7 @@ QString pki_evp::md5passwd(const char *pass)
return str;
}
QString pki_evp::sha512passwd(QString pass, QString salt)
QString pki_evp::sha512passwd(QByteArray pass, QString salt)
{
EVP_MD_CTX mdctx;
@ -734,10 +723,10 @@ QString pki_evp::sha512passwd(QString pass, QString salt)
abort();
str = salt.left(5);
pass = str + pass;
pass = str.toAscii() + pass;
EVP_DigestInit(&mdctx, EVP_sha512());
EVP_DigestUpdate(&mdctx, CCHAR(pass), pass.size());
EVP_DigestUpdate(&mdctx, pass.constData(), pass.size());
EVP_DigestFinal(&mdctx, m, (unsigned*)&n);
for (j=0; j<n; j++) {
@ -770,8 +759,8 @@ void pki_evp::veryOldFromData(unsigned char *p, int size )
sik1=sik;
memcpy(iv, p, 8); /* recover the iv */
/* generate the key */
EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)oldpasswd,
strlen(oldpasswd), 1, ckey,NULL);
EVP_BytesToKey(cipher, EVP_sha1(), iv, oldpasswd.constUchar(),
oldpasswd.size(), 1, ckey, NULL);
/* we use sha1 as message digest,
* because an md5 version of the password is
* stored in the database...

View File

@ -15,6 +15,7 @@
#include <openssl/pem.h>
#include <openssl/evp.h>
#include "pki_key.h"
#include "Passwd.h"
#define CURVE_X962 1
#define CURVE_OTHER 2
@ -26,17 +27,14 @@ class pki_evp: public pki_key
QByteArray encKey;
void init(int type = EVP_PKEY_RSA);
void veryOldFromData(unsigned char *p, int size);
void openssl_pw_error(QString fname);
public:
static QPixmap *icon[2];
static QString passHash;
static char passwd[MAX_PASS_LENGTH];
static char oldpasswd[MAX_PASS_LENGTH];
static void erasePasswd();
static void eraseOldPasswd();
static void setPasswd(const char *pass);
static void setOldPasswd(const char *pass);
static QString md5passwd(const char *pass);
static QString sha512passwd(QString pass, QString salt);
static Passwd passwd;
static Passwd oldpasswd;
static QString md5passwd(QByteArray pass);
static QString sha512passwd(QByteArray pass, QString salt);
#ifndef OPENSSL_NO_EC
static EC_builtin_curve *curves;
static size_t num_curves;

View File

@ -13,7 +13,7 @@
#include <QtGui/QProgressDialog>
#include <QtGui/QApplication>
#include <QtCore/QDir>
#include <widgets/MainWindow.h>
#include "widgets/PwDialog.h"
pki_key::pki_key(const QString name)
:pki_base(name)

View File

@ -16,7 +16,6 @@
#include "pki_base.h"
#define MAX_KEY_LENGTH 4096
#define MAX_PASS_LENGTH 128
class pki_key: public pki_base
{

View File

@ -126,7 +126,7 @@ void pki_multi::fromPEM_BIO(BIO *bio, QString name)
continue;
}
pos += startpos;
if (BIO_seek(bio, pos))
if (BIO_seek(bio, pos) == -1)
throw errorEx(tr("Seek failed"));
item->fromPEM_BIO(bio, name);
if (pos == BIO_tell(bio)) {
@ -159,10 +159,6 @@ void pki_multi::probeAnything(const QString fname)
new load_crl() << new load_req() << new load_key() <<
new load_temp();
fload(fname);
if (multi.count() > 0)
return;
foreach(lb, lbs) {
try {
item = lb->loadItem(fname);
@ -171,7 +167,10 @@ void pki_multi::probeAnything(const QString fname)
break;
}
} catch (errorEx &err) {
; // ignore
if (err.info == E_PASSWD) {
MainWindow::Error(err);
break;
}
}
}
while (!lbs.isEmpty())

View File

@ -10,30 +10,29 @@
#include "pass_info.h"
#include "exception.h"
#include "func.h"
#include "widgets/PwDialog.h"
#include <openssl/err.h>
#include <QtGui/QMessageBox>
pki_pkcs12::pki_pkcs12(const QString d, pki_x509 *acert, pki_evp *akey, pem_password_cb *cb):
pki_base(d)
pki_pkcs12::pki_pkcs12(const QString d, pki_x509 *acert, pki_evp *akey)
:pki_base(d)
{
class_name="pki_pkcs12";
key = new pki_evp(akey);
cert = new pki_x509(acert);
certstack = sk_X509_new_null();
passcb = cb;
openssl_error();
}
pki_pkcs12::pki_pkcs12(const QString fname, pem_password_cb *cb)
pki_pkcs12::pki_pkcs12(const QString fname)
:pki_base(fname)
{
FILE *fp;
char pass[MAX_PASS_LENGTH];
Passwd pass;
EVP_PKEY *mykey = NULL;
X509 *mycert = NULL;
key=NULL; cert=NULL;
passcb = cb;
class_name="pki_pkcs12";
certstack = sk_X509_new_null();
pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the PKCS#12 file:\n%1").arg(compressFilename(fname)));
@ -47,18 +46,18 @@ pki_pkcs12::pki_pkcs12(const QString fname, pem_password_cb *cb)
throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname));
}
if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0))
pass[0] = '\0';
else if (passcb(pass, MAX_PASS_LENGTH, 0, &p) < 0) {
pass.clear();
else if (PwDialog::execute(&p, &pass) != 1) {
/* cancel pressed */
PKCS12_free(pkcs12);
throw errorEx("","");
throw errorEx("","", E_PASSWD);
}
PKCS12_parse(pkcs12, pass, &mykey, &mycert, &certstack);
PKCS12_parse(pkcs12, pass.constData(), &mykey, &mycert, &certstack);
int error = ERR_peek_error();
if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) {
ign_openssl_error();
PKCS12_free(pkcs12);
throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error)));
throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error)), E_PASSWD);
}
ign_openssl_error();
if (mycert) {
@ -109,7 +108,7 @@ void pki_pkcs12::addCaCert(pki_x509 *ca)
void pki_pkcs12::writePKCS12(const QString fname)
{
char pass[MAX_PASS_LENGTH];
Passwd pass;
pass_info p(XCA_TITLE, tr("Please enter the password to encrypt the PKCS#12 file"));
if (cert == NULL || key == NULL) {
my_error(tr("No key or no Cert and no pkcs12"));
@ -117,14 +116,17 @@ void pki_pkcs12::writePKCS12(const QString fname)
FILE *fp = fopen(QString2filename(fname), "wb");
if (fp != NULL) {
passcb(pass, MAX_PASS_LENGTH, 0, &p);
PKCS12 *pkcs12 = PKCS12_create(pass,
if (PwDialog::execute(&p, &pass, true) != 1) {
fclose(fp);
return;
}
PKCS12 *pkcs12 = PKCS12_create(pass.data(),
getIntName().toUtf8().data(),
key->decryptKey(),
cert->getCert(), certstack, 0, 0, 0, 0, 0);
i2d_PKCS12_fp(fp, pkcs12);
openssl_error();
fclose (fp);
openssl_error();
PKCS12_free(pkcs12);
}
else fopen_error(fname);

View File

@ -28,12 +28,10 @@ class pki_pkcs12: public pki_base
pki_x509 *cert;
pki_evp *key;
STACK_OF(X509) *certstack;
pem_password_cb *passcb;
public:
pki_pkcs12(const QString d, pki_x509 *acert, pki_evp *akey,
pem_password_cb *cb);
pki_pkcs12(const QString fname, pem_password_cb *cb);
pki_pkcs12(const QString d, pki_x509 *acert, pki_evp *akey);
pki_pkcs12(const QString fname);
~pki_pkcs12();
void addCaCert(pki_x509 *acert);

View File

@ -1,182 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PassRead</class>
<widget class="QDialog" name="PassRead">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>220</height>
</rect>
</property>
<property name="windowTitle">
<string>Password</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="title">
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>false</underline>
<strikeout>false</strikeout>
</font>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="description">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="pass">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="takeHex">
<property name="toolTip">
<string>The password is parsed as 2-digit hex code. It must have an equal number of digits (0-9 and a-f)</string>
</property>
<property name="text">
<string>Take as HEX string</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>pass</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>pass</sender>
<signal>returnPressed()</signal>
<receiver>PassRead</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>148</x>
<y>123</y>
</hint>
<hint type="destinationlabel">
<x>158</x>
<y>157</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PassRead</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>144</x>
<y>195</y>
</hint>
<hint type="destinationlabel">
<x>5</x>
<y>171</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PassRead</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>241</x>
<y>197</y>
</hint>
<hint type="destinationlabel">
<x>275</x>
<y>78</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PassWrite</class>
<widget class="QDialog" name="PassWrite">
<class>PwDialog</class>
<widget class="QDialog" name="PwDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -144,7 +144,7 @@
<connection>
<sender>passB</sender>
<signal>returnPressed()</signal>
<receiver>PassWrite</receiver>
<receiver>PwDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -159,35 +159,22 @@
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PassWrite</receiver>
<slot>accept()</slot>
<signal>clicked(QAbstractButton*)</signal>
<receiver>PwDialog</receiver>
<slot>buttonPress(QAbstractButton*)</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>219</y>
<x>113</x>
<y>231</y>
</hint>
<hint type="destinationlabel">
<x>6</x>
<y>202</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PassWrite</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>294</x>
<y>214</y>
</hint>
<hint type="destinationlabel">
<x>66</x>
<y>198</y>
<x>125</x>
<y>53</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>buttonPress(QAbstractButton*)</slot>
</slots>
</ui>

View File

@ -17,16 +17,18 @@
#include "lib/func.h"
#include "widgets/ImportMulti.h"
void MainWindow::init_database()
int MainWindow::init_database()
{
int ret = 2;
fprintf(stderr, "Opening database: %s\n", QString2filename(dbfile));
keys = NULL; reqs = NULL; certs = NULL; temps = NULL; crls = NULL;
certView->setRootIsDecorated(db_x509::treeview);
try {
if (!initPass())
return;
ret = initPass();
if (ret == 2)
return ret;
keys = new db_key(dbfile, this);
reqs = new db_x509req(dbfile, this);
certs = new db_x509(dbfile, this);
@ -36,7 +38,7 @@ void MainWindow::init_database()
catch (errorEx &err) {
Error(err);
dbfile = "";
return;
return ret;
}
connect( keys, SIGNAL(newKey(pki_key *)),
@ -136,16 +138,17 @@ void MainWindow::init_database()
}
} catch (errorEx &err) {
Error(err);
return;
return ret;
}
setWindowTitle(tr(XCA_TITLE));
setItemEnabled(true);
if (pki_evp::passwd[0] == '\0')
if (pki_evp::passwd.isEmpty())
QMessageBox::information(this, XCA_TITLE,
tr("Using or exporting private keys will not be possible without providing the correct password"));
dbindex->setText(tr("Database") + ":" + dbfile);
load_engine();
return ret;
}
void MainWindow::dump_database()
@ -218,14 +221,14 @@ void MainWindow::undelete()
delete dlgi;
}
void MainWindow::open_default_db()
int MainWindow::open_default_db()
{
if (!dbfile.isEmpty())
return;
return 0;
FILE *fp = fopen(QString2filename(getUserSettingsDir() +
QDir::separator() + "defaultdb"), "r");
if (!fp)
return;
return 0;
char buff[256];
size_t len = fread(buff, 1, 255, fp);
@ -233,7 +236,8 @@ void MainWindow::open_default_db()
buff[len] = 0;
dbfile = filename2QString(buff).trimmed();
if (QFile::exists(dbfile))
init_database();
return init_database();
return 0;
}
void MainWindow::default_database()
@ -291,7 +295,7 @@ void MainWindow::close_database()
temps = NULL;
keys = NULL;
pki_evp::erasePasswd();
pki_evp::passwd.cleanse();
if (!crls)
return;

View File

@ -7,6 +7,7 @@
#include "MainWindow.h"
#include "PwDialog.h"
#include "Options.h"
#include "lib/load_obj.h"
#include "lib/pass_info.h"
@ -89,14 +90,14 @@ void MainWindow::init_menu()
scardList += token;
}
void MainWindow::changeDB(QString fname)
int MainWindow::changeDB(QString fname)
{
if (fname.isEmpty())
return;
return 1;
close_database();
homedir = fname.mid(0, fname.lastIndexOf(QDir::separator()));
dbfile = fname;
init_database();
return init_database();
}
void MainWindow::new_database()
@ -123,12 +124,12 @@ void MainWindow::load_database()
void MainWindow::import_dbdump()
{
extern int read_dump(const char *, db_base **, char *, int);
Passwd pass;
char buf[50];
db_base *dbl[] = { keys, reqs, certs, temps, crls };
if (!keys)
return;
QString pass;
QString file = QFileDialog::getOpenFileName(this, tr(XCA_TITLE), homedir,
tr("Database dump ( *.dump );;All files ( * )"));
@ -137,21 +138,20 @@ void MainWindow::import_dbdump()
pass_info p(tr("Import password"),
tr("Please enter the password of the old database"), this);
if (passRead(buf, 50, 0, &p) <0)
if (PwDialog::execute(&p, &pass) != 1)
return;
pass = buf;
try {
read_dump(CCHAR(file), dbl, buf, 50);
if (pki_evp::md5passwd(CCHAR(pass)) != buf) {
read_dump(CCHAR(file), dbl, buf, sizeof(buf));
if (pki_evp::md5passwd(pass) != buf) {
int ret = QMessageBox::warning(this, tr(XCA_TITLE),
tr("Password verification error. Ignore keys ?"),
tr("Import anyway"), tr("Cancel"));
if (ret)
return;
}
pki_evp::setOldPasswd(CCHAR(pass));
pki_evp::oldpasswd = pass;
read_dump(CCHAR(file), dbl, NULL, 0);
pki_evp::eraseOldPasswd();
pki_evp::oldpasswd.cleanse();
} catch (errorEx &err) {
Error(err);
}

View File

@ -9,6 +9,7 @@
//#define MDEBUG
#include "MainWindow.h"
#include "ImportMulti.h"
#include "lib/Passwd.h"
#include <openssl/rand.h>
@ -22,7 +23,6 @@
#include <QtGui/QTextBrowser>
#include <QtGui/QStatusBar>
#include <QtCore/QList>
#include <QtCore/QTemporaryFile>
#include <QtGui/QInputDialog>
#include "lib/exception.h"
@ -34,10 +34,8 @@
#include "lib/pass_info.h"
#include "lib/func.h"
#include "lib/pkcs11.h"
#include "ui_PassRead.h"
#include "ui_PassWrite.h"
#include "ui_About.h"
#include "PwDialog.h"
QPixmap *MainWindow::keyImg = NULL, *MainWindow::csrImg = NULL,
*MainWindow::certImg = NULL, *MainWindow::tempImg = NULL,
@ -347,10 +345,14 @@ void MainWindow::read_cmdline()
}
QString file = filename2QString(arg);
if (force_load) {
changeDB(file);
if (changeDB(file) == 2)
exitApp = 1;
force_load = 0;
} else {
pki_multi *pki = probeAnything(file);
int ret;
pki_multi *pki = probeAnything(file, &ret);
if (!pki && ret == 2)
exitApp = 1;
if (pki && !pki->count())
failed << file;
dlgi->addItem(pki);
@ -382,24 +384,27 @@ void MainWindow::pastePem()
ui.button->setText(tr("Import PEM data"));
input->setWindowTitle(tr(XCA_TITLE));
if (input->exec()) {
QString txt = textbox->toPlainText();
QTemporaryFile f;
f.open();
f.write(textbox->toPlainText().toAscii());
f.flush();
QByteArray pemdata = textbox->toPlainText().toAscii();
BIO *b = BIO_QBA_mem_buf(pemdata);
check_oom(b);
pki_multi *pem = NULL;
ImportMulti *dlgi = NULL;
try {
pem = new pki_multi();
dlgi = new ImportMulti(this);
pem->fload(f.fileName());
pem->fromPEM_BIO(b, QString("paste"));
dlgi->addItem(pem);
pem = NULL;
dlgi->execute(1);
}
catch (errorEx &err) {
Error(err);
}
delete dlgi;
if (dlgi)
delete dlgi;
if (pem)
delete pem;
BIO_free(b);
}
delete input;
}
@ -412,8 +417,8 @@ void MainWindow::initToken()
try {
pkcs11 p11;
slotid slot;
char pin[MAX_PASS_LENGTH];
int pinlen;
Passwd pin;
int ret;
if (!p11.selectToken(&slot, this))
return;
@ -427,20 +432,20 @@ void MainWindow::initToken()
arg(slotname) + "\n" + ti.pinInfo());
p.setPin();
if (ti.tokenInitialized()) {
pinlen = passRead(pin, MAX_PASS_LENGTH, 0, &p);
ret = PwDialog::execute(&p, &pin, false);
} else {
p.setDescription(tr("Please enter the new SO PIN (PUK) of the token '%1'").
arg(slotname) + "\n" + ti.pinInfo());
pinlen = passWrite(pin, MAX_PASS_LENGTH, 0, &p);
ret = PwDialog::execute(&p, &pin, true);
}
if (pinlen < 0)
if (ret != 1)
return;
QString label = QInputDialog::getText(this, XCA_TITLE,
tr("The new label of the token '%1'").
arg(slotname), QLineEdit::Normal, QString(), &ok);
if (!ok)
return;
p11.initToken(slot, (unsigned char*)pin, pinlen, label);
p11.initToken(slot, pin.constUchar(), pin.size(), label);
} catch (errorEx &err) {
Error(err);
}
@ -593,17 +598,14 @@ QString makeSalt(void)
void MainWindow::changeDbPass()
{
char pass[MAX_PASS_LENGTH] = { 0, };
int keylen;
Passwd pass;
pass_info p(tr("New Password"), tr("Please enter the new password "
"to encrypt your private keys in the database-file"),
this);
keylen = passWrite(pass, MAX_PASS_LENGTH-1, 0, &p);
if (keylen < 0)
if (PwDialog::execute(&p, &pass, true) != 1)
return;
pass[keylen] = '\0';
QString tempn = dbfile + "{new}";
try {
if (!QFile::copy(dbfile, tempn))
@ -616,7 +618,7 @@ void MainWindow::changeDbPass()
mydb.mv(new_file);
close_database();
pki_evp::passHash = passhash;
strncpy(pki_evp::passwd, pass, MAX_PASS_LENGTH);
pki_evp::passwd = pass;
init_database();
} catch (errorEx &ex) {
QFile::remove(tempn);
@ -624,7 +626,7 @@ void MainWindow::changeDbPass()
}
}
QString MainWindow::updateDbPassword(QString newdb, char *pass)
QString MainWindow::updateDbPassword(QString newdb, Passwd pass)
{
db mydb(newdb);
@ -674,7 +676,7 @@ QString MainWindow::updateDbPassword(QString newdb, char *pass)
{
EVP_PKEY *evp = key->decryptKey();
key->set_evp_key(evp);
key->encryptKey(pass);
key->encryptKey(pass.constData());
klist << key;
} else if (key)
delete key;
@ -698,10 +700,13 @@ int MainWindow::initPass()
char *pass;
pki_evp::passHash = QString();
QString salt;
int ret;
pass_info p(tr("New Password"), tr("Please enter a password, "
"that will be used to encrypt your private keys "
"in the database file:\n%1").arg(compressFilename(dbfile)), this);
"in the database file:\n%1").
arg(compressFilename(dbfile)), this);
if (!mydb.find(setting, "pwhash")) {
if ((pass = (char *)mydb.load(NULL))) {
pki_evp::passHash = pass;
@ -709,28 +714,28 @@ int MainWindow::initPass()
}
}
if (pki_evp::passHash.isEmpty()) {
int keylen = passWrite((char *)pki_evp::passwd,
MAX_PASS_LENGTH-1, 0, &p);
if (keylen < 0)
return 0;
pki_evp::passwd[keylen]='\0';
ret = PwDialog::execute(&p, &pki_evp::passwd, true, true);
if (ret != 1)
return ret;
salt = makeSalt();
pki_evp::passHash = pki_evp::sha512passwd(pki_evp::passwd,salt);
mydb.set((const unsigned char *)CCHAR(pki_evp::passHash),
pki_evp::passHash.length()+1, 1, setting, "pwhash");
} else {
int keylen=0;
ret = 0;
while (pki_evp::sha512passwd(pki_evp::passwd, pki_evp::passHash)
!= pki_evp::passHash)
{
if (keylen !=0) QMessageBox::warning(this,tr(XCA_TITLE),
if (ret)
QMessageBox::warning(this, XCA_TITLE,
tr("Password verify error, please try again"));
p.setTitle(tr("Password"));
p.setDescription(tr("Please enter the password for unlocking the database:\n%1").arg(compressFilename(dbfile)));
keylen = passRead(pki_evp::passwd, MAX_PASS_LENGTH-1, 0, &p);
if (keylen < 0)
return 1;
pki_evp::passwd[keylen]='\0';
ret = PwDialog::execute(&p, &pki_evp::passwd,
false, true);
printf("RET: %d\n", ret);
if (ret != 1)
return ret;
if (pki_evp::passHash.left(1) == "S")
continue;
/* Start automatic update from md5 to salted sha512
@ -752,102 +757,6 @@ int MainWindow::initPass()
return 1;
}
static int hex2bin(QString &x, char *buf, int buflen)
{
int len = x.length();
bool ok = false;
if (len % 2)
return -1;
len /= 2;
if (len > buflen)
return -1;
for (int i=0; i<len; i++) {
buf[i] = x.mid(i*2, 2).toInt(&ok, 16);
if (!ok)
return -1;
}
return len;
}
static const QString hexwarn = MainWindow::tr("Hex password must only contain the characters '0' - '9' and 'a' - 'f' and it must consist of an even number of characters");
// Static Password Callback functions
int MainWindow::passRead(char *buf, int size, int, void *userdata)
{
int ret = -1;
pass_info *p = (pass_info *)userdata;
Ui::PassRead ui;
QDialog *dlg = new QDialog(p->getWidget());
ui.setupUi(dlg);
if (p != NULL) {
ui.image->setPixmap(p->getImage());
ui.description->setText(p->getDescription());
ui.title->setText(p->getType());
ui.label->setText(p->getType());
dlg->setWindowTitle(p->getTitle());
if (p->getType() != "PIN")
ui.takeHex->hide();
}
while (dlg->exec()) {
QString x = ui.pass->text();
if (ui.takeHex->isChecked()) {
ret = hex2bin(x, buf, size);
if (ret != -1)
break;
} else {
strncpy(buf, x.toAscii(), size);
ret = x.length();
break;
}
QMessageBox::warning(p->getWidget(), XCA_TITLE, hexwarn);
}
delete dlg;
return ret;
}
int MainWindow::passWrite(char *buf, int size, int, void *userdata)
{
int ret = -1;
pass_info *p = (pass_info *)userdata;
Ui::PassWrite ui;
QDialog *dlg = new QDialog(p->getWidget());
ui.setupUi(dlg);
if (p != NULL) {
ui.image->setPixmap(p->getImage()) ;
ui.description->setText(p->getDescription());
ui.title->setText(p->getType());
ui.label->setText(p->getType());
ui.repeatLabel->setText(tr("Repeat %1").arg(p->getType()));
dlg->setWindowTitle(p->getTitle());
if (p->getType() != "PIN")
ui.takeHex->hide();
}
while (dlg->exec()) {
QString A = ui.passA->text();
QString B = ui.passB->text();
if (A == B) {
if (ui.takeHex->isChecked()) {
ret = hex2bin(A, buf, size);
if (ret != -1)
break;
} else {
strncpy(buf, A.toAscii(), size);
ret = A.length();
break;
}
QMessageBox::warning(p->getWidget(), XCA_TITLE,
hexwarn);
} else {
QMessageBox::warning(p->getWidget(), XCA_TITLE,
tr("%1 missmatch").arg(p->getType()));
}
}
delete dlg;
return ret;
}
void MainWindow::Error(errorEx &err)
{
if (err.isEmpty())
@ -893,17 +802,20 @@ void MainWindow::importAnything(QString file)
delete dlgi;
}
pki_multi *MainWindow::probeAnything(QString file)
pki_multi *MainWindow::probeAnything(QString file, int *ret)
{
pki_multi *pki = new pki_multi();
try {
if (file.endsWith(".xdb")) {
try {
int r;
db mydb(file);
mydb.verify_magic();
changeDB(file);
r = changeDB(file);
delete pki;
if (ret)
*ret = r;
return NULL;
} catch (errorEx &err) {
}

View File

@ -17,6 +17,7 @@
#include "lib/db_crl.h"
#include "lib/exception.h"
#include "lib/oid.h"
#include "lib/Passwd.h"
#include <QtGui/QPixmap>
#include <QtGui/QFileDialog>
#include <QtGui/QMenuBar>
@ -47,7 +48,7 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
NIDlist *read_nidlist(QString name);
QLabel *statusLabel;
QString homedir;
void changeDB(QString fname);
int changeDB(QString fname);
public:
static db_x509 *certs;
@ -71,9 +72,6 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
int initPass();
void read_cmdline();
void load_engine();
static int passRead(char *buf, int size, int rwflag, void *userdata);
static int passWrite(char *buf, int size, int rwflag, void *userdata);
//static void Qt::SocketError(errorEx &err);
static void Error(errorEx &err);
void cmd_version();
void cmd_help(const char* msg);
@ -82,16 +80,16 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
void setPath(QString path);
bool mkDir(QString dir);
void setItemEnabled(bool enable);
QString updateDbPassword(QString newdb, char *pass);
QString updateDbPassword(QString newdb, Passwd pass);
void enableTokenMenu(bool enable);
pki_multi *probeAnything(QString file);
pki_multi *probeAnything(QString file, int *ret = NULL);
void importAnything(QString file);
void dropEvent(QDropEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void open_default_db();
int open_default_db();
public slots:
void init_database();
int init_database();
void new_database();
void load_database();
void close_database();

View File

@ -4,7 +4,7 @@ TOPDIR=..
endif
MOC_NAMES=MainWindow KeyDetail clicklabel XcaTreeView ExportKey NewX509 \
validity v3ext distname CertDetail CertExtend \
validity v3ext distname CertDetail CertExtend PwDialog \
ImportMulti CrlDetail ExportDialog hashBox Options NewKey kvView NewCrl
NAMES=$(MOC_NAMES) NewX509_ext MW_menu MW_help MW_database

131
widgets/PwDialog.cpp Normal file
View File

@ -0,0 +1,131 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2011 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "PwDialog.h"
#include "lib/base.h"
#include "lib/Passwd.h"
#include "widgets/MainWindow.h"
#include <QtGui/QLabel>
#include <QtGui/QMessageBox>
static int hex2bin(QString &x, Passwd *final)
{
bool ok = false;
int len = x.length();
if (len % 2)
return -1;
len /= 2;
final->clear();
for (int i=0; i<len; i++) {
final->append((x.mid(i*2, 2).toInt(&ok, 16)) & 0xff);
if (!ok)
return -1;
}
return len;
}
int PwDialog::execute(pass_info *p, Passwd *passwd, bool write, bool abort)
{
PwDialog *dlg;
int ret;
dlg = new PwDialog(p, write);
if (abort)
dlg->addAbortButton();
ret = dlg->exec();
*passwd = dlg->getPass();
delete dlg;
return ret;
}
int PwDialog::pwCallback(char *buf, int size, int rwflag, void *userdata)
{
int ret;
pass_info *p = (pass_info *)userdata;
PwDialog *dlg = new PwDialog(p, rwflag);
ret = dlg->exec();
QByteArray pw = dlg->getPass();
size = MIN(size, pw.size());
memcpy(buf, pw.constData(), size);
delete dlg;
return ret == 1 ? size : 0;
}
PwDialog::PwDialog(pass_info *p, bool write)
:QDialog(p->getWidget())
{
pi = p;
setupUi(this);
setWindowTitle(XCA_TITLE);
image->setPixmap(pi->getImage());
description->setText(pi->getDescription());
title->setText(pi->getType());
setWindowTitle(pi->getTitle());
if (pi->getType() != "PIN")
takeHex->hide();
setRW(write);
}
void PwDialog::setRW(bool write)
{
wrDialog = write;
if (write) {
label->setText(pi->getType());
repeatLabel->setText(tr("Repeat %1").arg(pi->getType()));
label->show();
passA->show();
} else {
repeatLabel->setText(pi->getType());
label->hide();
passA->hide();
}
}
void PwDialog::accept()
{
if (wrDialog && (passA->text() != passB->text())) {
QMessageBox::warning(this, XCA_TITLE,
tr("%1 missmatch").arg(pi->getType()));
return;
}
QString pw = passB->text();
if (takeHex->isChecked()) {
int ret = hex2bin(pw, &final);
if (ret == -1) {
QMessageBox::warning(this, XCA_TITLE, tr("Hex password must only contain the characters '0' - '9' and 'a' - 'f' and it must consist of an even number of characters"));
return;
}
} else {
final = pw.toAscii();
}
QDialog::accept();
}
void PwDialog::buttonPress(QAbstractButton *but)
{
switch (buttonBox->standardButton(but)) {
case QDialogButtonBox::Ok:
accept();
break;
case QDialogButtonBox::Cancel:
reject();
break;
case QDialogButtonBox::Abort:
default:
done(2);
}
}
void PwDialog::addAbortButton()
{
buttonBox->addButton(tr("E&xit"), QDialogButtonBox::ResetRole);
}

42
widgets/PwDialog.h Normal file
View File

@ -0,0 +1,42 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2011 Christian Hohnstaedt.
*
* All rights reserved.
*/
#ifndef __PWDIALOG_H
#define __PWDIALOG_H
#include <QtCore/QByteArray>
#include "ui_PwDialog.h"
#include "lib/Passwd.h"
#include "lib/pki_x509.h"
#include "lib/pass_info.h"
class PwDialog: public QDialog, public Ui::PwDialog
{
Q_OBJECT
private:
bool wrDialog;
Passwd final;
pass_info *pi;
public:
PwDialog(pass_info *p, bool write = false);
Passwd getPass() {
return final;
}
void addAbortButton();
void setRW(bool write);
static int execute(pass_info *p, Passwd *passwd,
bool write = false, bool abort = false);
static int pwCallback(char *buf, int size, int rwflag, void *userdata);
public slots:
void accept();
void buttonPress(QAbstractButton *but);
};
#endif