patch from Mikael Magnusson

change of key handling started (DSA dupport and stronger security)
This commit is contained in:
chris2511 2004-09-21 22:10:52 +00:00
parent 41b3585d07
commit 1c6bfca323
15 changed files with 322 additions and 149 deletions

View File

@ -11,6 +11,7 @@ export TOPDIR=$(shell pwd)
SUBDIRS=lib widgets view ui
OBJECTS=$(patsubst %, %/target.obj, $(SUBDIRS))
INSTDIR=img misc lang doc
CLEANDIRS=lang doc
bindir=bin
@ -32,10 +33,13 @@ clean:
for x in $(SUBDIRS); do \
$(MAKE) -C $${x} clean; \
done
for x in $(CLEANDIRS); do \
$(MAKE) -C $${x} clean; \
done
rm -f *~ xca
distclean: clean
rm -f Local.mak
rm -f Local.mak conftest conftest.log
dist:
test ! -z "$(TVERSION)"
@ -52,7 +56,7 @@ dist:
tar zcf $(TARGET).tar.gz $(TARGET) && \
(cd $(TARGET) && dpkg-buildpackage -rfakeroot )
#rm -rf ../$(TARGET)
install: xca
$(STRIP) xca
install -m 755 -d $(destdir)$(prefix)/$(bindir)

View File

@ -46,7 +46,7 @@ clean:
rm -f *~ *.o *.obj $(DELFILES)
distclean: clean
rm -f .depend
rm -f -r .depend
.depend: $(SRCS)
$(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) > $@

40
debian/changelog vendored
View File

@ -1,3 +1,9 @@
xca (0.5.1-1.0) unstable; urgency=low
* NMU
-- Mikael Magnusson <mikma@users.sourceforge.net> Tue, 7 Sep 2004 20:01:50 +0200
xca (0.5.1-1) unstable; urgency=low
* support for different languages on WIN platform (Thanks Ilya)
@ -66,7 +72,7 @@ xca (0.4.6) unstable; urgency=low
- Support for UTF8 in x509name
- Netscape SPKAC support added
-- Christian Hohnstädt <chris@trinity.local> Tue, 25 Nov 2003 18:28:02 +0100
-- Christian Hohnstädt <chris@trinity.local> Tue, 25 Nov 2003 18:28:02 +0100
xca (0.4.5) unstable; urgency=low
@ -78,14 +84,14 @@ xca (0.4.5) unstable; urgency=low
editable to enter arbitrary key sizes.
* [ 765774 ] change password for database
-- Christian Hohnstädt <chris@trinity.local> Wed, 13 Aug 2003 22:10:43 +0200
-- Christian Hohnstädt <chris@trinity.local> Wed, 13 Aug 2003 22:10:43 +0200
xca (0.4.4) unstable; urgency=low
* [ 783853 ] renewal uses 'notBefore' as 'notAfter' date
* [ 783830 ] GeneralizedTime-format breaks browsers
-- Christian Hohnstädt <chris@trinity.local> Wed, 6 Aug 2003 18:42:58 +0200
-- Christian Hohnstädt <chris@trinity.local> Wed, 6 Aug 2003 18:42:58 +0200
xca (0.4.3) unstable; urgency=low
@ -99,7 +105,7 @@ xca (0.4.3) unstable; urgency=low
* some segmentation faults removed
* VPN OIDs added to Ext. Keyusage
-- Christian Hohnstädt <chris@trinity.local> Tue, 5 Aug 2003 21:51:20 +0200
-- Christian Hohnstädt <chris@trinity.local> Tue, 5 Aug 2003 21:51:20 +0200
xca (0.4.2) unstable; urgency=low
@ -114,7 +120,7 @@ xca (0.4.2) unstable; urgency=low
reconnected.
* Authority Key identifier repaired
-- Christian Hohnstädt <chris@trinity.local> Sun, 20 Jul 2003 23:38:38 +0200
-- Christian Hohnstädt <chris@trinity.local> Sun, 20 Jul 2003 23:38:38 +0200
xca (0.4.1) unstable; urgency=low
@ -145,7 +151,7 @@ xca (0.4.0) unstable; urgency=low
key.xpm will be installed as xca.xpm in pixmaps
([ 763954 ] xca.desktop file) Thanks to Enrico Scholz
-- Christian Hohnstädt <chris@trinity.local> Tue, 8 Jul 2003 23:31:37 +0200
-- Christian Hohnstädt <chris@trinity.local> Tue, 8 Jul 2003 23:31:37 +0200
xca (0.3.2) unstable; urgency=low
@ -154,14 +160,14 @@ xca (0.3.2) unstable; urgency=low
* Support for PKCS#7 certs (im/export)
* small UI changes
-- Christian Hohnstädt <chris@trinity.local> Thu, 15 May 2003 00:46:07 +0200
-- Christian Hohnstädt <chris@trinity.local> Thu, 15 May 2003 00:46:07 +0200
xca (0.3.1) unstable; urgency=low
* Tool Tips added
* CRL handling (import, export, details) added
-- Christian Hohnstädt <chris@trinity.local> Thu, 24 Apr 2003 19:29:36 +0200
-- Christian Hohnstädt <chris@trinity.local> Thu, 24 Apr 2003 19:29:36 +0200
xca (0.3.0) unstable; urgency=low
@ -177,7 +183,7 @@ xca (0.3.0) unstable; urgency=low
* changes in configure
* The wizard invokes the key generation process only if really needed
-- Christian Hohnstädt <chris@trinity.local> Wed, 5 Mar 2003 23:56:56 +0100
-- Christian Hohnstädt <chris@trinity.local> Wed, 5 Mar 2003 23:56:56 +0100
xca (0.2.12) unstable; urgency=low
@ -186,7 +192,7 @@ xca (0.2.12) unstable; urgency=low
* Several export targets added
* Certificate renewal repaired
-- Christian Hohnstädt <chris@trinity.local> Mon, 6 Jan 2003 21:40:28 +0100
-- Christian Hohnstädt <chris@trinity.local> Mon, 6 Jan 2003 21:40:28 +0100
xca (0.2.11) unstable; urgency=low
@ -195,7 +201,7 @@ xca (0.2.11) unstable; urgency=low
* configure continues even if qt lib is absent.
* $HOME/xca is created if it does not exist.
-- Christian Hohnstädt <chris@trinity.local> Wed, 4 Dec 2002 21:38:28 +0100
-- Christian Hohnstädt <chris@trinity.local> Wed, 4 Dec 2002 21:38:28 +0100
xca (0.2.10) unstable; urgency=low
@ -207,7 +213,7 @@ xca (0.2.10) unstable; urgency=low
* create request from certificate
* FreeBSD paths and libs recognized by configure
-- Christian Hohnstädt <chris@trinity.local> Wed, 4 Dec 2002 21:34:41 +0100
-- Christian Hohnstädt <chris@trinity.local> Wed, 4 Dec 2002 21:34:41 +0100
xca (0.2.9) unstable; urgency=low
@ -219,7 +225,7 @@ xca (0.2.9) unstable; urgency=low
* database transactions activated
* exception-handling completed
-- Christian Hohnstädt <chris@trinity.local> Mon, 21 Oct 2002 21:05:59 +0200
-- Christian Hohnstädt <chris@trinity.local> Mon, 21 Oct 2002 21:05:59 +0200
xca (0.2.8) unstable; urgency=low
@ -230,14 +236,14 @@ xca (0.2.8) unstable; urgency=low
* package-builder do build without printf-debugging
* key-use counter works now well
-- Christian Hohnstädt <chris@trinity.local> Sun, 13 Oct 2002 23:28:29 +0200
-- Christian Hohnstädt <chris@trinity.local> Sun, 13 Oct 2002 23:28:29 +0200
xca (0.2.7) unstable; urgency=low
* segfaults removed
* minor wizard changes
-- Christian Hohnstädt <chris@trinity.local> Mon, 7 Oct 2002 23:32:19 +0200
-- Christian Hohnstädt <chris@trinity.local> Mon, 7 Oct 2002 23:32:19 +0200
xca (0.2.6) unstable; urgency=low
@ -247,7 +253,7 @@ xca (0.2.6) unstable; urgency=low
* signing-template, CRL date and CRL time interval adjustable
* Fix for windows filenames
-- Christian Hohnstädt <chris@trinity.local> Mon, 30 Sep 2002 22:02:01 +0200
-- Christian Hohnstädt <chris@trinity.local> Mon, 30 Sep 2002 22:02:01 +0200
xca (0.2.5) unstable; urgency=low
@ -260,7 +266,7 @@ xca (0.2.5) unstable; urgency=low
* Files for MS Visual C++ added (yes, it compiles on MS Windows)
* Windows Installer added (Nullsoft)
-- Christian Hohnstädt <chris@trinity.local> Tue, 24 Sep 2002 02:18:51 +0200
-- Christian Hohnstädt <chris@trinity.local> Tue, 24 Sep 2002 02:18:51 +0200
xca (0.2.4) unstable; urgency=low

19
debian/control vendored
View File

@ -2,16 +2,19 @@ Source: xca
Section: x11
Priority: optional
Maintainer: Christian Hohnstaedt <christian@hohnstaedt.de>
Build-Depends: debhelper (>> 3.0.0), libdb3++-dev, libqt-dev, libssl-dev
Build-Depends: debhelper (>> 3.0.0), libdb4.2++-dev | libdb3++-dev, libqt3-mt-dev, libssl-dev, libqt3-compat-headers
Standards-Version: 3.6.1.0
Package: xca
Architecture: any
Depends: ${shlibs:Depends}
Description: A GUI for handling X509 certificates, RSA keys, PKCS#10 Requests and CRLs.
The Program uses a Berkeley db for storage and supports RSA keys,
Certificate signing requests (PKCS#10) and Certificates (X509v3)
The signing of requests, and the creation of selfsigned certificates
is supported. Both can use templates for simplicity.
The PKI structures can be imported and exported in several formats
like PKCS#12, PEM, DER, PKCS#8, PKCS#7.
Description: GUI for handling X509 certificates, RSA keys, PKCS#10 Requests and CRLs
XCA is a GUI for handling X509 certificates, RSA keys, PKCS#10
Requests and CRLs. The program uses a Berkeley db for storage and
supports RSA keys, Certificate signing requests (PKCS#10) and
Certificates (X509v3) The signing of requests, and the creation of
selfsigned certificates is supported. Both can use templates for
simplicity. The PKI structures can be imported and exported in
several formats like PKCS#12, PEM, DER, PKCS#8, PKCS#7.
.
Homepage: http://www.hohnstaedt.de/xca

2
debian/copyright vendored
View File

@ -17,3 +17,5 @@
mail: christian@hohnstaedt.de
http: www.hohnstaedt.de/xca
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.

2
debian/docs vendored
View File

@ -1 +1,3 @@
README
AUTHORS
CREDITS

4
debian/menu vendored
View File

@ -1,2 +1,2 @@
?package(xca):needs=X11 section=Apps/Tools\
title="xca" command="/usr/bin/xca"
?package(xca):needs="X11" section="Apps/Tools"\
title="xca" command="/usr/bin/xca" icon="/usr/share/pixmaps/xca.xpm"

31
debian/rules vendored
View File

@ -8,19 +8,31 @@
# This is the debhelper compatability version to use.
export DH_COMPAT=2
CFLAGS = -Wall -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
Local.mak:
dh_testdir
# Add here commands to configure the package.
# prefix=/usr ./configure
cat debian/debian.mak > Local.mak
prefix=/usr CFLAGS="$(CFLAGS)" QTDIR="/usr/share/qt3" ./configure
# Don't use scripts
-test -f debian/postinst && mv debian/postinst debian/postinst.bak
-test -f debian/postrm && mv debian/postrm debian/postrm.bak
build: build-stamp
build-stamp: Local.mak
dh_testdir
# Add here commands to compile the package.
$(MAKE) -j 4
# $(MAKE) -j 4
$(MAKE)
touch build-stamp
clean:
@ -28,8 +40,9 @@ clean:
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
-test -f debian/postinst.bak && mv debian/postinst.bak debian/postinst
-test -f debian/postrm.bak && mv debian/postrm.bak debian/postrm
dh_clean
install: build
@ -38,8 +51,7 @@ install: build
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/xca.
$(MAKE) install
$(MAKE) install destdir=$(CURDIR)/debian/tmp
# Build architecture-independent files here.
binary-indep: build install
@ -49,6 +61,7 @@ binary-indep: build install
binary-arch: build install
dh_testdir
dh_testroot
dh_install --list-missing
# dh_installdebconf
dh_installdocs
# dh_installexamples
@ -59,7 +72,7 @@ binary-arch: build install
# dh_installmime
# dh_installinit
# dh_installcron
dh_installmanpages
dh_installman
# dh_installinfo
# dh_undocumented
dh_installchangelogs

View File

@ -18,5 +18,8 @@ install: xca.1.gz
install -m 644 xca*.html $(destdir)$(prefix)/share/xca
install xca.1.gz $(destdir)$(prefix)/$(mandir)/man1
clean:
$(RM) xca.1.gz
include $(TOPDIR)/Local.mak

View File

@ -1,9 +1,17 @@
QM_FILES=xca_de.qm xca_es.qm
all:
.SUFFIXES: .ts .qm
install:
.ts.qm:
lrelease $< -qm $@
all: $(QM_FILES)
install: $(QM_FILES)
install -m 755 -d $(destdir)$(prefix)/share/xca
install -m 644 lang/xca_??.qm $(destdir)$(prefix)/share/xca || true
install -m 644 $(QM_FILES) $(destdir)$(prefix)/share/xca
clean:
$(RM) $(QM_FILES)
include $(TOPDIR)/Local.mak

View File

@ -179,8 +179,11 @@ void pki_crl::addV3ext(const x509v3ext &e)
void pki_crl::sign(pki_key *key, const EVP_MD *md)
{
EVP_PKEY *pkey;
if (!key || key->isPubKey()) return;
X509_CRL_sign(crl, key->key, md);
pkey = key->decryptKey();
X509_CRL_sign(crl, pkey, md);
EVP_PKEY_free(pkey);
openssl_error();
}
@ -252,7 +255,7 @@ bool pki_crl::verify(pki_key *key)
{
bool ret=false;
if (crl && crl->crl && key) {
ret = (X509_CRL_verify(crl , key->key) == 1);
ret = (X509_CRL_verify(crl , key->getKey()) == 1);
ign_openssl_error();
}
return ret ;

View File

@ -58,7 +58,7 @@
#include <qapplication.h>
#include <widgets/MainWindow.h>
char pki_key::passwd[40]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
char pki_key::passwd[40]={0,};
QPixmap *pki_key::icon[2]= { NULL, NULL };
@ -73,6 +73,8 @@ void pki_key::init(int type)
key = EVP_PKEY_new();
key->type = type;
class_name = "pki_key";
encKey = NULL;
encKey_len = 0;
}
void pki_key::incProgress(int a, int b, void *progress)
@ -81,9 +83,10 @@ void pki_key::incProgress(int a, int b, void *progress)
((QProgressDialog *)progress)->setProgress(++i);
}
void pki_key::generate(int bits)
void pki_key::generate(int bits, int type)
{
RSA *rsakey=NULL;
RSA *rsakey = NULL;
DSA *dsakey = NULL;
QProgressDialog *progress = new QProgressDialog(
qApp->tr("Please wait, Key generation is in progress"),
qApp->tr("Cancel"),90, 0, 0, true);
@ -91,12 +94,20 @@ void pki_key::generate(int bits)
progress->setProgress(0);
progress->setCaption(XCA_TITLE);
rsakey = RSA_generate_key(bits, 0x10001, &incProgress, progress);
if (type == EVP_PKEY_RSA) {
rsakey = RSA_generate_key(bits, 0x10001, &incProgress, progress);
if (rsakey) EVP_PKEY_set1_RSA(key, rsakey);
} else if (type == EVP_PKEY_DSA) {
dsakey = DSA_generate_parameters(bits,NULL,0,NULL,NULL,&incProgress, progress);
DSA_generate_key(dsakey);
if(dsakey) EVP_PKEY_set1_DSA(key,dsakey);
}
progress->cancel();
delete progress;
EVP_PKEY_assign_RSA(key, rsakey);
openssl_error();
openssl_error();
encryptKey();
}
pki_key::pki_key(const pki_key *pk)
@ -107,10 +118,15 @@ pki_key::pki_key(const pki_key *pk)
if (pk == NULL) return;
key->type = pk->key->type;
if (key->type == EVP_PKEY_RSA) {
//rsakey = RSA_dup(pk->key->pkey.rsa);
key->pkey.rsa=((RSA *)ASN1_dup( (int (*)())i2d_RSAPrivateKey, (char *(*)())d2i_RSAPrivateKey,(char *)pk->key->pkey.rsa));
}
// TODO add DSA support.....
if (key->type == EVP_PKEY_DSA) {
key->pkey.dsa=((DSA *)ASN1_dup( (int(*)())i2d_DSAPrivateKey, (char *(*)())d2i_DSAPrivateKey,(char *)pk->key->pkey.dsa));
}
openssl_error();
encryptKey();
}
pki_key::pki_key(const QString name, int type )
@ -136,9 +152,12 @@ void pki_key::fload(const QString fname)
+ "\n'" + fname + "'");
pem_password_cb *cb = &MainWindow::passRead;
FILE *fp = fopen(fname.latin1(), "r");
RSA *rsakey = NULL;
RSA *rsakey = NULL, *rsapub = NULL;
EVP_PKEY *evkey = NULL;
if (fp != NULL) {
rsakey = PEM_read_RSAPrivateKey(fp, NULL, cb, &p);
if (!rsakey) {
ign_openssl_error();
rewind(fp);
@ -147,23 +166,26 @@ void pki_key::fload(const QString fname)
if (!rsakey) {
ign_openssl_error();
rewind(fp);
rsakey = PEM_read_RSA_PUBKEY(fp, NULL, cb, &p);
rsapub = PEM_read_RSA_PUBKEY(fp, NULL, cb, &p);
}
if (!rsakey) {
if (!rsapub) {
ign_openssl_error();
rewind(fp);
rsakey = d2i_RSA_PUBKEY_fp(fp, NULL);
rsapub = d2i_RSA_PUBKEY_fp(fp, NULL);
}
if (!rsakey) {
if (!rsapub) {
ign_openssl_error();
rewind(fp);
p.setTitle(tr("Password for PKCS#8 private key"));
p.setDescription(tr("Please enter the password to decrypt the PKCS#8 private key.")
+ "\n'" + fname + "'");
d2i_PKCS8PrivateKey_fp(fp, &key, cb, &p);
d2i_PKCS8PrivateKey_fp(fp, &evkey, cb, &p);
}
else {
EVP_PKEY_assign_RSA(key, rsakey);
if (rsakey) {
encryptKey();
}
else if (rsapub) {
EVP_PKEY_assign_RSA(key, rsapub);
openssl_error();
}
setIntName(rmslashdot(fname));
@ -173,8 +195,37 @@ void pki_key::fload(const QString fname)
fclose(fp);
}
void pki_key::fromData(unsigned char *p, int size )
{
unsigned char *p1;
EVP_PKEY *pkey1;
int version, type;
p1 = p;
pkey1 = key;
version = intFromData(&p1);
if (version != 1) { // backward compatibility
oldFromData(p, size);
return;
}
if (key)
EVP_PKEY_free(key);
type = intFromData(&p1);
d2i_PublicKey(type, &pkey1, &p1, size);
openssl_error();
encKey_len = size - (p1-p) - (2*sizeof(int));
if (encKey_len) {
encKey = (unsigned char *)OPENSSL_malloc(encKey_len);
memcpy(encKey, p1 ,encKey_len);
}
}
void pki_key::oldFromData(unsigned char *p, int size )
{
unsigned char *sik, *pdec, *pdec1, *sik1;
int outl, decsize;
@ -227,66 +278,124 @@ void pki_key::fromData(unsigned char *p, int size )
openssl_error();
}
EVP_PKEY *pki_key::decryptKey()
{
unsigned char *p, *p1;
int outl, decsize;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char ckey[EVP_MAX_KEY_LENGTH];
memset(iv, 0, EVP_MAX_IV_LENGTH);
RSA *rsakey;
EVP_PKEY *tmpkey;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
p = (unsigned char *)OPENSSL_malloc(encKey_len);
p1 = p;
openssl_error();
memcpy(iv, encKey, 8); /* recover the iv */
/* generate the key */
EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)passwd,
strlen(passwd), 1, ckey,NULL);
/* we use sha1 as message digest,
* because an md5 version of the password is
* stored in the database...
*/
EVP_CIPHER_CTX_init (&ctx);
EVP_DecryptInit( &ctx, cipher, ckey, iv);
EVP_DecryptUpdate( &ctx, p , &outl, encKey + 8, encKey_len - 8 );
decsize = outl;
EVP_DecryptFinal( &ctx, encKey + decsize , &outl );
decsize += outl;
openssl_error();
if (key->type == EVP_PKEY_RSA) {
#if OPENSSL_VERSION_NUMBER >= 0x0090700fL
rsakey = d2i_RSAPrivateKey(NULL, (const unsigned char **)&p, decsize);
#else
rsakey = d2i_RSAPrivateKey(NULL, &p, decsize);
#endif
openssl_error();
tmpkey = EVP_PKEY_new();
if (rsakey) EVP_PKEY_assign_RSA(tmpkey, rsakey);
}
OPENSSL_free(p1);
EVP_CIPHER_CTX_cleanup(&ctx);
openssl_error();
return tmpkey;
}
unsigned char *pki_key::toData(int *size)
{
unsigned char *p, *p1, *penc;
int outl, encsize=0;
unsigned char *p, *p1;
int pubsize;
pubsize = i2d_PublicKey(key, NULL);
*size = pubsize + encKey_len + (2*sizeof(int));
p = (unsigned char *)OPENSSL_malloc(*size);
openssl_error();
p1 = p;
intToData(&p1, 1);
intToData(&p1, key->type);
i2d_PublicKey(key, &p1);
openssl_error();
memcpy(p1, encKey, encKey_len);
return p;
}
void pki_key::encryptKey()
{
int outl, keylen;
EVP_PKEY *pkey1 = NULL;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH], *punenc, *punenc1;
unsigned char ckey[EVP_MAX_KEY_LENGTH];
/* 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 *)passwd,
strlen(passwd), 1, ckey,NULL);
strlen(passwd), 1, ckey, NULL);
EVP_CIPHER_CTX_init (&ctx);
EVP_EncryptInit( &ctx, cipher, ckey, iv);
openssl_error();
//if (key->type == EVP_PKEY_RSA) {
if (true) {
if (isPubKey()) {
*size = i2d_RSA_PUBKEY(key->pkey.rsa, NULL);
p = (unsigned char *)OPENSSL_malloc(*size);
openssl_error();
penc = (unsigned char *)OPENSSL_malloc(*size + EVP_MAX_KEY_LENGTH + 8);
if (!penc) {
OPENSSL_free(p);
openssl_error();
}
p1 = p;
memcpy(penc,iv,8); /* store the iv */
i2d_RSA_PUBKEY(key->pkey.rsa, &p1);
EVP_EncryptUpdate( &ctx, penc + 8, &outl, p, *size );
encsize = outl;
openssl_error();
}
else {
*size = i2d_RSAPrivateKey(key->pkey.rsa, NULL);
openssl_error();
p = (unsigned char *)OPENSSL_malloc(*size);
openssl_error();
penc = (unsigned char *)OPENSSL_malloc(*size + EVP_MAX_KEY_LENGTH + 8);
if (!penc) {
OPENSSL_free(p);
openssl_error();
}
p1 = p;
memcpy(penc, iv, 8); /* store the iv */
i2d_RSAPrivateKey(key->pkey.rsa, &p1);
EVP_EncryptUpdate( &ctx, penc + 8, &outl, p, *size ); /* store key right after the iv */
encsize = outl;
openssl_error();
}
}
EVP_EncryptFinal( &ctx, penc + encsize + 8, &outl );
encsize += outl ;
OPENSSL_free(p);
/* reserve space for unencrypted and encrypted key */
keylen = i2d_PrivateKey(key, NULL);
encKey = (unsigned char *)OPENSSL_malloc(keylen + EVP_MAX_KEY_LENGTH + 8);
punenc = (unsigned char *)OPENSSL_malloc(keylen);
openssl_error();
punenc1 = punenc;
memcpy(encKey, iv, 8); /* store the iv */
/* copy the public part */
i2d_PublicKey(key, &punenc1);
punenc1 = punenc;
d2i_PublicKey(key->type, &pkey1, &punenc1, keylen);
punenc1 = punenc;
openssl_error();
i2d_PrivateKey(key, &punenc1);
/* do the encryption */
/* store key right after the iv */
EVP_EncryptInit( &ctx, cipher, ckey, iv);
EVP_EncryptUpdate( &ctx, encKey + 8, &outl, punenc, keylen );
encKey_len = outl;
EVP_EncryptFinal( &ctx, encKey + encKey_len + 8, &outl );
encKey_len += outl + 8;
/* Cleanup */
EVP_CIPHER_CTX_cleanup(&ctx);
openssl_error();
*size = encsize + 8;
return penc;
/* convert rsa/dsa to Pubkey */
/* punenc is big enough, because it held the privkey before. */
EVP_PKEY_free(key);
key = pkey1;
openssl_error();
OPENSSL_free(punenc);
return;
}
@ -295,6 +404,8 @@ pki_key::~pki_key()
{
if (key)
EVP_PKEY_free(key);
if (encKey)
OPENSSL_free(encKey);
}
@ -321,16 +432,16 @@ void pki_key::writeKey(const QString fname, const EVP_CIPHER *enc,
writePublic(fname, PEM);
return;
}
FILE *fp = fopen(fname.latin1(),"w");
FILE *fp = fopen(fname.latin1(), "w");
if (fp != NULL) {
if (key){
if (PEM)
PEM_write_PrivateKey(fp, key, enc, NULL, 0, cb, &p);
else {
i2d_RSAPrivateKey_fp(fp, key->pkey.rsa);
if (key){
if (PEM) {
PEM_write_PrivateKey(fp, key, enc, NULL, 0, cb, &p);
} else {
i2d_PrivateKey_fp(fp, key);
}
openssl_error();
}
openssl_error();
}
}
else fopen_error(fname);
fclose(fp);
@ -341,11 +452,11 @@ void pki_key::writePublic(const QString fname, bool PEM)
{
FILE *fp = fopen(fname.latin1(),"w");
if (fp != NULL) {
if (key->type == EVP_PKEY_RSA) {
if (PEM)
PEM_write_RSA_PUBKEY(fp, key->pkey.rsa);
else
i2d_RSA_PUBKEY_fp(fp, key->pkey.rsa);
if (key->type == EVP_PKEY_RSA) {
if (PEM)
PEM_write_PUBKEY(fp, key);
else
i2d_PUBKEY_fp(fp, key);
openssl_error();
}
}
@ -397,18 +508,32 @@ QString pki_key::privEx() {
bool pki_key::compare(pki_base *ref)
{
pki_key *kref = (pki_key *)ref;
if (kref == NULL) return false;
if (kref->key == NULL) return false;
if (kref->key->pkey.rsa->n == NULL) return false;
if (key == NULL) return false;
if (key->pkey.rsa->n == NULL) return false;
if (
BN_cmp(key->pkey.rsa->n, kref->key->pkey.rsa->n) ||
BN_cmp(key->pkey.rsa->e, kref->key->pkey.rsa->e)
){
openssl_error();
return false;
}
if(key->type==EVP_PKEY_RSA) {
if (kref==NULL || kref->key==NULL || kref->key->pkey.rsa->n==NULL)
return false;
if (key == NULL || key->pkey.rsa->n == NULL)
return false;
if (
BN_cmp(key->pkey.rsa->n, kref->key->pkey.rsa->n) ||
BN_cmp(key->pkey.rsa->e, kref->key->pkey.rsa->e)
){
openssl_error();
return false;
}
} else if(key->type==EVP_PKEY_DSA) {
if(kref==NULL || kref->key==NULL || kref->key->pkey.dsa->p==NULL)
return false;
if(key==NULL || key->pkey.rsa->p==NULL)
return false;
if(
BN_cmp(key->pkey.dsa->q,kref->key->pkey.dsa->q) ||
BN_cmp(key->pkey.dsa->g,kref->key->pkey.dsa->g) ||
BN_cmp(key->pkey.dsa->pub_key,kref->key->pkey.dsa->pub_key)
){
openssl_error();
return false;
}
}
openssl_error();
return true;
}
@ -416,20 +541,15 @@ bool pki_key::compare(pki_base *ref)
bool pki_key::isPubKey()
{
if (key == NULL) {
return false;
if (encKey_len == 0 || encKey == NULL) {
return true;
}
if (key->pkey.rsa == 0) {
return false;
}
return (key->pkey.rsa->d == NULL);
return false;
}
bool pki_key::isPrivKey()
{
return ! isPubKey();
}
int pki_key::verify()

View File

@ -66,22 +66,23 @@
class pki_key: public pki_base
{
friend class pki_x509req;
friend class pki_x509;
friend class pki_crl;
protected:
EVP_PKEY *key;
QString BN2QString(BIGNUM *bn);
unsigned char *encKey;
int encKey_len;
int ucount; // usage counter
QString BN2QString(BIGNUM *bn);
void init(int type = EVP_PKEY_RSA);
static void incProgress(int a, int b, void *progress);
void encryptKey();
public:
static QPixmap *icon[2];
static char passwd[MAX_PASS_LENGTH];
static void erasePasswd();
void generate(int bits);
void generate(int bits, int type = EVP_PKEY_RSA);
pki_key(const QString name = "", int type = EVP_PKEY_RSA);
pki_key(EVP_PKEY *pkey);
EVP_PKEY *decryptKey();
// copy constructor
pki_key::pki_key(const pki_key *pk);
/* destructor */
@ -89,6 +90,7 @@ class pki_key: public pki_base
void fload(const QString fname);
void fromData(unsigned char *p, int size);
void oldFromData(unsigned char *p, int size);
unsigned char *toData(int *size);
bool compare(pki_base *ref);
QString length();

View File

@ -248,11 +248,15 @@ bool pki_x509::hasSubAltName()
void pki_x509::sign(pki_key *signkey, const EVP_MD *digest)
{
EVP_PKEY *tkey;
if (!signkey) {
openssl_error("There is no key for signing !");
}
X509_sign(cert, signkey->key, digest);
tkey=signkey->decryptKey();
X509_sign(cert, tkey, digest);
EVP_PKEY_free(tkey);
openssl_error();
}
@ -408,7 +412,7 @@ bool pki_x509::verify(pki_x509 *signer)
return false;
}
pki_key *pkey = signer->getPubKey();
int i = X509_verify(cert,pkey->key);
int i = X509_verify(cert,pkey->getKey());
ign_openssl_error();
if (pkey) delete(pkey);
if (i>0) {

View File

@ -82,6 +82,7 @@ pki_x509req::~pki_x509req()
void pki_x509req::createReq(pki_key *key, const x509name &dn, const EVP_MD *md)
{
EVP_PKEY *privkey = NULL;
if (key->isPubKey()) {
openssl_error("key not valid");
return;
@ -91,8 +92,10 @@ void pki_x509req::createReq(pki_key *key, const x509name &dn, const EVP_MD *md)
X509_REQ_set_pubkey(request, key->getKey());
setSubject(dn);
openssl_error();
X509_REQ_sign(request,key->getKey(), md);
privkey = key->decryptKey();
X509_REQ_sign(request, privkey, md);
openssl_error();
EVP_PKEY_free(privkey);
}
void pki_x509req::fload(const QString fname)