Fix Password input and key encryption

Add CA properties
This commit is contained in:
Christian 2006-06-05 23:14:38 +02:00
parent a08bb6a542
commit dae20bc28e
12 changed files with 438 additions and 102 deletions

View File

@ -268,10 +268,6 @@ void db_base::insertSortChild(pki_base *parent, pki_base *child)
int row;
QModelIndex idx = QModelIndex();
if (parent == NULL)
printf("Parent is null !!??\n");
if (child == NULL)
printf("Parent is null !!??\n");
if (parent == child || parent == NULL)
parent = rootItem;

View File

@ -218,6 +218,7 @@ void db_key::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
QMenu *menu = new QMenu(mainwin);
currentIdx = index;
pki_key *key = static_cast<pki_key*>(currentIdx.internalPointer());
menu->addAction(tr("New Key"), this, SLOT(newItem()));
menu->addAction(tr("Import"), this, SLOT(load()));
@ -225,8 +226,10 @@ void db_key::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
menu->addAction(tr("Show Details"), this, SLOT(showItem()));
menu->addAction(tr("Export"), this, SLOT(store()));
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
menu->addAction(tr("Change password"), this, SLOT(setOwnPass()));
menu->addAction(tr("Reset password"), this, SLOT(resetOwnPass()));
if (!key->getOwnPass())
menu->addAction(tr("Change password"), this, SLOT(setOwnPass()));
else
menu->addAction(tr("Reset password"), this, SLOT(resetOwnPass()));
}
menu->exec(e->globalPos());
delete menu;

View File

@ -54,6 +54,7 @@
#include "widgets/CertExtend.h"
#include "widgets/ExportCert.h"
#include "ui/TrustState.h"
#include "ui/CaProperties.h"
#include <Qt/qmessagebox.h>
#include <Qt/qevent.h>
#include <Qt/qaction.h>
@ -573,10 +574,7 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
itemTrust = menu->addAction(tr("Trust"), this, SLOT(setTrust()));
menu->addSeparator();
subCa = menu->addMenu(tr("CA"));
subCa->addAction(tr("Serial"), this, SLOT(setSerial()));
subCa->addAction(tr("CRL days"), this, SLOT(setCrlDays()));
itemTemplate = subCa->addAction(tr("Signing Template"),
this, SLOT(setTemplate()));
subCa->addAction(tr("Properties"), this, SLOT(caProperties()));
subCa->addAction(tr("Generate CRL"), this, SLOT(genCrl()));
subP7 = menu->addMenu(tr("PKCS#7"));
@ -585,29 +583,26 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
menu->addSeparator();
itemExtend = menu->addAction(tr("Renewal"),
this, SLOT(extendCert()));
if (cert) {
if (cert->isRevoked()) {
itemRevoke = menu->addAction(tr("Unrevoke"),
this, SLOT(unRevoke()));
itemTrust->setEnabled(false);
} else {
itemRevoke = menu->addAction(tr("Revoke"),
this, SLOT(revoke()));
}
parentCanSign = (cert->getSigner() && cert->getSigner()->canSign()
&& (cert->getSigner() != cert));
canSign = cert->canSign();
#warning templates
hasTemplates = mainwin->temps->getDesc().count() > 0 ;
hasPrivkey = cert->getRefKey();
if (cert->isRevoked()) {
itemRevoke = menu->addAction(tr("Unrevoke"),
this, SLOT(unRevoke()));
itemTrust->setEnabled(false);
} else {
itemRevoke = menu->addAction(tr("Revoke"),
this, SLOT(revoke()));
}
itemExtend->setEnabled(parentCanSign);
parentCanSign = (cert->getSigner() && cert->getSigner()->canSign()
&& (cert->getSigner() != cert));
canSign = cert->canSign();
#warning templates
hasTemplates = mainwin->temps->getDesc().count() > 0 ;
hasPrivkey = cert->getRefKey();
itemRevoke->setEnabled(parentCanSign);
itemExtend->setEnabled(parentCanSign);
subCa->setEnabled(canSign);
itemReq->setEnabled(hasPrivkey);
itemtca->setEnabled(canSign);
subP7->setEnabled(hasPrivkey);
itemTemplate->setEnabled(hasTemplates);
}
menu->exec(e->globalPos());
@ -949,7 +944,8 @@ void db_x509::extendCert()
void db_x509::revoke()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert) return;
if (!cert)
return;
cert->setRevoked(true);
updatePKI(cert);
}
@ -957,7 +953,8 @@ void db_x509::revoke()
void db_x509::unRevoke()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert) return;
if (!cert)
return;
cert->setRevoked(false);
updatePKI(cert);
}
@ -968,6 +965,25 @@ void db_x509::genCrl()
mainwin->crls->newItem(cert);
}
void db_x509::toRequest()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
try {
pki_x509req *req = new pki_x509req();
req->setIntName(cert->getIntName());
req->createReq(cert->getRefKey(), cert->getSubject(),
cert->getRefKey()->getDefaultMD(), cert->getExt());
mainwin->reqs->insert(req);
}
catch (errorEx &err) {
mainwin->Error(err);
}
}
#if 0
void db_x509::setSerial()
{
@ -1002,6 +1018,7 @@ void db_x509::setCrlDays()
tr("Please enter the CRL renewal periode in days"),
crlDays, 1, 2147483647, 1, &ok, this );
if (ok && (crlDays != nCrlDays)) {
int crlDays = cert->getCrlDays();
cert->setCrlDays(nCrlDays);
db->updatePKI(cert);
}
@ -1029,3 +1046,38 @@ void db_x509::setTemplate()
}
}
#endif
void db_x509::caProperties()
{
Ui::CaProperties ui;
int i;
printf("CA Prop UI\n");
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
QDialog *dlg = new QDialog(mainwin);
ui.setupUi(dlg);
ui.serial->setText(cert->getCaSerial().toHex());
ui.days->setValue(cert->getCrlDays());
ui.image->setPixmap(*MainWindow::certImg);
QString templ = cert->getTemplate();
QStringList tempList = mainwin->temps->getDesc();
for (i=0; i<tempList.count(); i++) {
if (tempList[i] == templ)
break;
}
ui.temp->addItems(tempList);
ui.temp->setCurrentIndex(i);
ui.certName->setText(cert->getIntName());
if (dlg->exec()) {
a1int nserial;
cert->setCrlDays(ui.days->value());
nserial.setHex(ui.serial->text());
if (nserial > cert->getCaSerial())
cert->setCaSerial(nserial);
cert->setTemplate(ui.temp->currentText());
updatePKI(cert);
}
delete dlg;
}

View File

@ -106,6 +106,8 @@ class db_x509: public db_x509super
void revoke();
void unRevoke();
void genCrl();
void caProperties();
void toRequest();
signals:
void connNewX509(NewX509 *dlg);
};

View File

@ -59,6 +59,7 @@
#include <widgets/MainWindow.h>
char pki_key::passwd[40]={0,};
QString pki_key::passHash = QString();
QPixmap *pki_key::icon[2]= { NULL, NULL };
@ -127,7 +128,7 @@ QString pki_key::removeTypeFromIntName(QString n)
void pki_key::setOwnPass(int x)
{
EVP_PKEY *pk;
EVP_PKEY *pk, *pk_back;
printf("Set own pass: %d -> %d\n",ownPass,x);
if (x) x=1;
if (ownPass == x) return;
@ -135,10 +136,19 @@ void pki_key::setOwnPass(int x)
pk = decryptKey();
if (pk == NULL) return;
EVP_PKEY_free(key);
pk_back = key;
key = pk;
ownPass = x;
encryptKey();
try {
encryptKey();
}
catch (errorEx &err) {
EVP_PKEY_free(key);
key = pk_back;
ownPass ^= 1;
throw(err);
}
EVP_PKEY_free(pk_back);
}
void pki_key::generate(int bits, int type, QProgressBar *progress)
@ -339,24 +349,34 @@ EVP_PKEY *pki_key::decryptKey()
EVP_PKEY *tmpkey;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
char ownPassBuf[MAX_PASS_LENGTH];
char ownPassBuf[MAX_PASS_LENGTH] = "";
/* This key has its own password */
if (ownPass == 1) {
pass_info pi(XCA_TITLE, qApp->translate("MainWindow", "Please enter the password to decrypt the private key: '") + getIntName() + "'");
MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &pi);
int ret;
pass_info pi(XCA_TITLE, qApp->translate("MainWindow",
"Please enter the password to decrypt the private key: '") +
getIntName() + "'");
ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &pi);
if (ret < 0)
throw errorEx("Password input aborted", class_name);
}
else {
printf("Orig password: '%s' len:%d\n",passwd, strlen(passwd));
if (strlen(passwd) == 0) {
int retlen = 0;
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
"Please enter the default password"));
while (strlen(passwd) == 0 && retlen == 0) {
retlen = MainWindow::passRead(passwd, MAX_PASS_LENGTH, 0, &p);
if (md5passwd(passwd) != passHash) {
printf("Orig password: '%s' len:%d\n", passwd, strlen(passwd));
while (md5passwd(ownPassBuf) != passHash) {
int ret;
printf("Passhash= '%s', new hash= '%s', passwd= '%s'\n",
CCHAR(passHash), CCHAR(md5passwd(ownPassBuf)), ownPassBuf);
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
"Please enter the default password"));
ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &p);
if (ret < 0)
throw errorEx("Password input aborted", class_name);
}
} else {
memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
}
memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
}
printf("Using decrypt Pass: %s\n", ownPassBuf);
p = (unsigned char *)OPENSSL_malloc(encKey_len);
@ -422,19 +442,27 @@ void pki_key::encryptKey()
/* This key has its own, private password ? */
if (ownPass == 1) {
int ret;
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
"Please enter the password to protect the private key: '") +
getIntName() + "'");
while (!MainWindow::passWrite(ownPassBuf, MAX_PASS_LENGTH, 0, &p) );
ret = MainWindow::passWrite(ownPassBuf, MAX_PASS_LENGTH, 0, &p);
if (ret < 0)
throw errorEx("Password input aborted", class_name);
}
else {
int retlen = 0;
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
"Please enter the default password for encrypting keys"));
while (retlen >= 0) {
retlen = MainWindow::passWrite(passwd, MAX_PASS_LENGTH, 0, &p);
if (md5passwd(passwd) != passHash) {
int ret = 0;
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
"Please enter the database password for encrypting the key"));
while (md5passwd(ownPassBuf) != passHash) {
ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0,&p);
if (ret < 0)
throw errorEx("Password input aborted", class_name);
}
} else {
memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
}
memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
}
/* Prepare Encryption */
@ -707,7 +735,7 @@ int pki_key::getUcount()
const EVP_MD *pki_key::getDefaultMD(){
const EVP_MD *md;
switch (key->type) {
case EVP_PKEY_RSA: md = EVP_md5(); break;
case EVP_PKEY_RSA: md = EVP_sha1(); break;
case EVP_PKEY_DSA: md = EVP_dss1(); break;
default: md = NULL; break;
}
@ -735,3 +763,26 @@ QVariant pki_key::getIcon()
return QVariant(*icon[pixnum]);
}
QString pki_key::md5passwd(const char *pass, char *md5, int *len)
{
EVP_MD_CTX mdctx;
QString str;
unsigned int n;
int j;
char zs[4];
unsigned char m[EVP_MAX_MD_SIZE];
EVP_DigestInit(&mdctx, EVP_md5());
EVP_DigestUpdate(&mdctx, pass, strlen(pass));
EVP_DigestFinal(&mdctx, m, &n);
for (j=0; j<(int)n; j++) {
sprintf(zs, "%02X%c",m[j], (j+1 == (int)n) ?'\0':':');
str += zs;
}
if (md5 && len) {
*len = (*len>n) ? n : *len;
memcpy(md5, m, *len);
}
return str;
}

View File

@ -67,10 +67,10 @@ class pki_key: public pki_base
{
protected:
int ownPass; // if we have our own private password
EVP_PKEY *key;
unsigned char *encKey;
int encKey_len;
int ownPass; // if we have our own private password
int ucount; // usage counter
QString BN2QString(BIGNUM *bn);
void init(int type = EVP_PKEY_RSA);
@ -78,10 +78,14 @@ class pki_key: public pki_base
void encryptKey();
public:
static QPixmap *icon[2];
static QString passHash;
static char passwd[MAX_PASS_LENGTH];
static void erasePasswd();
static QString md5passwd(const char *pass,
char *md5 = NULL, int *len = NULL);
void generate(int bits, int type, QProgressBar *progress);
void setOwnPass(int x);
int getOwnPass(void) {return ownPass;};
pki_key(const QString name = "", int type = EVP_PKEY_RSA);
pki_key(EVP_PKEY *pkey);
EVP_PKEY *decryptKey();

257
ui/CaProperties.ui Normal file
View File

@ -0,0 +1,257 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>CaProperties</class>
<widget class="QDialog" name="CaProperties" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>484</width>
<height>375</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="image" >
<property name="minimumSize" >
<size>
<width>200</width>
<height>94</height>
</size>
</property>
<property name="scaledContents" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="certName" >
<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>
<property name="text" >
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>CA properties</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="1" >
<widget class="QLineEdit" name="serial" />
</item>
<item row="0" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Next serial for signing</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QSpinBox" name="days" />
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Days until next CRL issuing</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QComboBox" name="temp" />
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Default template</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>131</width>
<height>31</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="okButton" >
<property name="text" >
<string>OK</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton" >
<property name="text" >
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<pixmapfunction></pixmapfunction>
<resources/>
<connections>
<connection>
<sender>okButton</sender>
<signal>clicked()</signal>
<receiver>CaProperties</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>278</x>
<y>253</y>
</hint>
<hint type="destinationlabel" >
<x>96</x>
<y>254</y>
</hint>
</hints>
</connection>
<connection>
<sender>cancelButton</sender>
<signal>clicked()</signal>
<receiver>CaProperties</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>369</x>
<y>253</y>
</hint>
<hint type="destinationlabel" >
<x>179</x>
<y>282</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -304,16 +304,6 @@
</layout>
</item>
</layout>
<widget class="QWidget" name="widget" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>100</width>
<height>30</height>
</rect>
</property>
</widget>
</widget>
<pixmapfunction></pixmapfunction>
<customwidgets>

View File

@ -133,12 +133,17 @@ void MainWindow::dump_database()
void MainWindow::close_database()
{
keyView->setModel(NULL);
reqView->setModel(NULL);
certView->setModel(NULL);
tempView->setModel(NULL);
crlView->setModel(NULL);
delete(crls);
delete(reqs);
delete(certs);
delete(temps);
delete(keys);
//delete(settings);
crls = NULL;
reqs = NULL;

View File

@ -79,27 +79,29 @@ void MainWindow::init_menu()
void MainWindow::load_database()
{
load_key l;
load_db l;
QString fname;
QFileDialog *dlg = new QFileDialog(this);
dlg->setWindowTitle(l.caption);
dlg->setFilters(l.filter);
dlg->setFileMode( QFileDialog::AnyFile );
dlg->setDirectory(baseDir);
dlg->setDirectory(getPath());
if (dlg->exec()) {
fname = dlg->selectedFiles()[0];
setPath(dlg->directory().path());
}
delete dlg;
if (fname.isEmpty()) return;
if (fname.isEmpty())
return;
dbfile = fname;
close_database();
fprintf(stderr, "Dir: %s, File: %s\n", baseDir.data(), dbfile.data() );
emit init_database();
fprintf(stderr, "Dir: %s, File: %s\n", CCHAR(baseDir), CCHAR(dbfile));
init_database();
}
void MainWindow::load_def_database()
{
dbfile = DBFILE;
close_database();
emit init_database();
init_database();
}

View File

@ -345,28 +345,28 @@ int MainWindow::initPass()
{
db mydb(dbfile);
char *pass;
pki_key::passHash = QString();
pass_info p(tr("New Password"),
tr("Please enter a password, that will be used to encrypt your private keys in the database-file"));
QString passHash;
if (!mydb.find(setting, "pwhash")) {
if ((pass = (char *)mydb.load(NULL))) {
passHash = pass;
pki_key::passHash = pass;
free(pass);
}
}
if (passHash.isEmpty()) {
if (pki_key::passHash.isEmpty()) {
int keylen = passWrite((char *)pki_key::passwd, 25, 0, &p);
if (keylen < 0)
return 0;
pki_key::passwd[keylen]='\0';
passHash = md5passwd(pki_key::passwd);
mydb.set((const unsigned char *)CCHAR(passHash),
passHash.length()+1, 1, setting, "pwhash");
pki_key::passHash = pki_key::md5passwd(pki_key::passwd);
mydb.set((const unsigned char *)CCHAR(pki_key::passHash),
pki_key::passHash.length()+1, 1, setting, "pwhash");
}
else {
int keylen=0;
while (md5passwd(pki_key::passwd) != passHash) {
while (pki_key::md5passwd(pki_key::passwd) != pki_key::passHash) {
if (keylen !=0) QMessageBox::warning(this,tr(XCA_TITLE),
tr("Password verify error, please try again"));
p.setTitle(tr("Password"));
@ -386,7 +386,6 @@ int MainWindow::passRead(char *buf, int size, int rwflag, void *userdata)
{
int ret = -1;
pass_info *p = (pass_info *)userdata;
printf("Userdata called\n");
Ui::PassRead ui;
QDialog *dlg = new QDialog(qApp->activeWindow());
ui.setupUi(dlg);
@ -437,29 +436,6 @@ int MainWindow::passWrite(char *buf, int size, int rwflag, void *userdata)
return ret;
}
QString MainWindow::md5passwd(const char *pass, char *md5, int *len)
{
EVP_MD_CTX mdctx;
QString str;
unsigned int n;
int j;
char zs[4];
unsigned char m[EVP_MAX_MD_SIZE];
EVP_DigestInit(&mdctx, EVP_md5());
EVP_DigestUpdate(&mdctx, pass, strlen(pass));
EVP_DigestFinal(&mdctx, m, &n);
for (j=0; j<(int)n; j++) {
sprintf(zs, "%02X%c",m[j], (j+1 == (int)n) ?'\0':':');
str += zs;
}
if (md5 && len) {
*len = (*len>n) ? n : *len;
memcpy(md5, m, *len);
}
return str;
}
void MainWindow::Error(errorEx &err)
{
if (err.isEmpty()) return;

View File

@ -103,8 +103,6 @@ class MainWindow: public QMainWindow, private Ui::MainWindow
static int passRead(char *buf, int size, int rwflag, void *userdata);
static int passWrite(char *buf, int size, int rwflag, void *userdata);
static NewX509 *newX509();
static QString md5passwd(const char *pass,
char *md5 = NULL, int *len = NULL);
//static void Qt::SocketError(errorEx &err);
static void Error(errorEx &err);
void cmd_help(const char* msg);