SPKAC enhancement patch from W. Glas added

Mainwindow menu bar added
This commit is contained in:
chris2511 2003-11-27 15:39:29 +00:00
parent 5cf00e9c80
commit b49ee62e68
7 changed files with 203 additions and 199 deletions

View File

@ -1,10 +1,12 @@
Christian Hohnstädt <christian@hohnstaedt.de>
Programming, translation, testing
Kerstin Steinhauff <tine@kerstine.de>
Arts, graphics, testing, SuSE rpm building
Arts, Graphics
Ilya Kozhevnikov <ilya@ef.unn.ru>
Compiling and testing the WIN32-port
implementing the W32 registry stuff
Wolfgang Glas <wolfgang.glas@ev-i.at>
Adding SPKAC support and testing

View File

@ -149,6 +149,13 @@ x509name pki_x509req::getSubject() const
return x;
}
void pki_x509req::setSubject(const x509name &n)
{
if (request->req_info->subject != NULL)
X509_NAME_free(request->req_info->subject);
request->req_info->subject = n.get();
}
bool pki_x509req::isSpki() const
{
return spki != NULL;
@ -241,156 +248,174 @@ QString pki_x509req::getSigAlg()
return alg;
}
int pki_x509req::fix_data(int nid, int *type)
{
if (nid == NID_pkcs9_emailAddress)
*type=V_ASN1_IA5STRING;
if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
*type=V_ASN1_T61STRING;
if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
*type=V_ASN1_T61STRING;
if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
return(0);
if (nid == NID_pkcs9_unstructuredName)
*type=V_ASN1_IA5STRING;
return(1);
}
/*!
Sets the public key of this request to the public key of the
DER-encoded Netscape SPKI structure contained in the supplied
raw data array.
*/
void pki_x509req::setSPKIFromData(unsigned char *p, int size)
{
NETSCAPE_SPKI *spki = NULL;
/*
* function for making a x509 request out of a spkac netscape request.
* The spkac file is parsed and the information assembled to the x509 format
*/
spki = d2i_NETSCAPE_SPKI(NULL,&p,size);
if (spki == NULL) goto err;
set_spki (spki);
err:
openssl_error();
}
/*!
Sets the public key of this request to the public key of the
base64-encoded Netscape SPKI structure contained in the supplied
null-terminated string.
*/
void pki_x509req::setSPKIBase64(const char *p)
{
NETSCAPE_SPKI *spki = NULL;
spki = NETSCAPE_SPKI_b64_decode(p, -1);
if (spki == NULL) goto err;
set_spki (spki);
err:
openssl_error();
}
/*!
Sets the public key of this request to the public key of the
given Netscape SPKI structure. Throws an error exception, if the
verification of the signature contained in the SPKI structure fails.
The SPKI structure is implicitly freed by this internal function upon
error. On success, the internally stored SPKI structure is replaced.
*/
void pki_x509req::set_spki(NETSCAPE_SPKI *_spki)
{
EVP_PKEY *pktmp=NULL;
/*
Now extract the key from the SPKI structure and
check the signature.
*/
pktmp=NETSCAPE_SPKI_get_pubkey(_spki);
if (pktmp == NULL) goto err;
if (NETSCAPE_SPKI_verify(_spki, pktmp) <= 0) goto err;
X509_REQ_set_pubkey(request,pktmp);
// replace the internally stored spki structure.
if (spki)
NETSCAPE_SPKI_free(spki);
spki=_spki;
return;
err:
NETSCAPE_SPKI_free(_spki);
if (pktmp != NULL) EVP_PKEY_free(pktmp);
openssl_error();
}
/*!
Load a spkac FILE into this request structure.
The file format follows the conventions understood by the 'openssl ca'
command. (see: 'man ca')
Indeed, this function is derived from the original sources in ca.c
of the openssl package.
*/
void pki_x509req::load_spkac(const QString filename)
{
STACK_OF(CONF_VALUE) *sk=NULL;
LHASH *parms=NULL;
CONF_VALUE *cv=NULL;
X509_REQ_INFO *ri;
x509name subject;
char *type,*buf;
EVP_PKEY *pktmp=NULL;
X509_NAME *n=NULL;
X509_NAME_ENTRY *ne=NULL;
int i,j;
int i;
long errline;
int nid;
QString eerror;
bool spki_found =false;
// if we are called from a contructor, we should leave
// with the request structure cleaned up upon error.
bool ctor_excursion = (request == NULL);
parms=CONF_load(NULL,filename,&errline);
if (parms == NULL)
{
eerror.sprintf("error on line %ld", errline);
goto err;
}
try { // be aware of any expections
parms=CONF_load(NULL,filename.latin1(),&errline);
if (parms == NULL)
openssl_error(QString("error on line %1 of %2\n")
.arg(errline).arg(filename));
sk=CONF_get_section(parms, "default");
if (sk_CONF_VALUE_num(sk) == 0)
{
eerror = "no name/value pairs found";
goto err;
}
/*
* Create the request structure, parsing the spkac file
*/
sk=CONF_get_section(parms, "default");
if (sk_CONF_VALUE_num(sk) == 0)
openssl_error(QString("no name/value pairs found in %1\n").arg(filename));
request = X509_REQ_new();
openssl_error();
/*
* Build up the subject name set.
*/
ri=request->req_info;
n = ri->subject;
for (i = 0; ; i++)
{
if (sk_CONF_VALUE_num(sk) <= i) break;
cv=sk_CONF_VALUE_value(sk,i);
type=cv->name;
/* Skip past any leading X. X: X, etc to allow for
* multiple instances
/*
Create the request structure, if we are called from
inside a constructor
*/
if (ctor_excursion) request = X509_REQ_new();
if (request == NULL)
openssl_error();
/*
* Build up the subject name set.
*/
for (buf = cv->name; *buf ; buf++)
if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
{
buf++;
if (*buf) type = buf;
break;
}
buf=cv->value;
if ((nid=OBJ_txt2nid(type)) == NID_undef)
for (i = 0; ; i++)
{
if (strcmp(type, "SPKAC") == 0)
{
spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
if (spki == NULL)
if (sk_CONF_VALUE_num(sk) <= i) break;
cv=sk_CONF_VALUE_value(sk,i);
type=cv->name;
/* Skip past any leading X. X: X, etc to allow for
* multiple instances
*/
for (buf = cv->name; *buf ; buf++)
if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
{
eerror = "unable to load Netscape SPKAC structure";
goto err;
buf++;
if (*buf) type = buf;
break;
}
buf=cv->value;
// check for a valid DN component.
if ((nid=OBJ_txt2nid(type)) == NID_undef)
{
// ... or a SPKAC tag.
if (strcmp(type, "SPKAC") == 0)
setSPKIBase64(cv->value);
else
// ... or throw an error.
openssl_error(QString("Unknown name tag %1 found in %2\n").arg(type).arg(filename));
spki_found=true;
}
continue;
else
// gather all values in the x509name subject.
subject.addEntryByNid(nid,cv->value);
}
if (!spki_found)
openssl_error(QString("No Netscape SPKAC structure found in %1\n").arg(filename));
j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
if (fix_data(nid, &j) == 0)
{
eerror.sprintf("invalid characters in string %s",buf);
goto err;
}
if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,(unsigned char *)buf,strlen(buf))) == NULL)
{
eerror.sprintf("failed to create Name entry %s",buf);
goto err;
}
if (!X509_NAME_add_entry(n,ne,-1, 0))
{
eerror.sprintf("failed to add Name entry %s",buf);
goto err;
}
}
if (spki == NULL)
/*
* Now set the subject.
*/
setSubject(subject);
if (parms != NULL) CONF_free(parms);
}
catch (errorEx &e)
{
eerror = "Netscape SPKAC structure not found";
goto err;
// clean up the request pointer since we are called from within
// the ctor.
if (request != NULL){
X509_REQ_free(request);
request=NULL;
}
/*
* Now extract the key from the SPKI structure.
*/
if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
{
eerror = "error unpacking SPKAC public key";
goto err;
if (spki){
NETSCAPE_SPKI_free(spki);
spki=NULL;
}
j = NETSCAPE_SPKI_verify(spki, pktmp);
if (j <= 0)
{
eerror = "signature verification failed on SPKAC public key";
goto err;
if (parms != NULL) CONF_free(parms);
throw e;
}
X509_REQ_set_pubkey(request,pktmp);
EVP_PKEY_free(pktmp);
return;
err:
if (request != NULL){
X509_REQ_free(request);
request=NULL;
}
if (parms != NULL) CONF_free(parms);
if (spki != NULL) {
NETSCAPE_SPKI_free(spki);
spki = NULL;
}
if (ne != NULL) X509_NAME_ENTRY_free(ne);
openssl_error(QString::fromLatin1("SPKAC Error: ") + eerror + "(" + filename +")" );
}

View File

@ -88,6 +88,10 @@ class pki_x509req : public pki_x509super
void createReq(pki_key *key, const x509name &dn, const EVP_MD *md);
void updateView();
QString getSigAlg();
void setSubject(const x509name &n);
void setSPKIFromData(unsigned char *p, int size);
void setSPKIBase64(const char *p);
void set_spki(NETSCAPE_SPKI *_spki);
};
#endif

View File

@ -41,5 +41,7 @@ rm -rf $RPM_BUILD_ROOT
/usr/bin/xca
/usr/share/xca/*.png
/usr/share/xca/xca_??.qm
/usr/share/applications/xca.desktop
/usr/share/pixmaps/xca.xpm
%changelog

View File

@ -12,8 +12,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>804</width>
<height>534</height>
<width>822</width>
<height>521</height>
</rect>
</property>
<property stdset="1">
@ -29,6 +29,27 @@
<name>spacing</name>
<number>6</number>
</property>
<spacer>
<property>
<name>name</name>
<cstring>Spacer8_2</cstring>
</property>
<property stdset="1">
<name>orientation</name>
<enum>Vertical</enum>
</property>
<property stdset="1">
<name>sizeType</name>
<enum>Minimum</enum>
</property>
<property>
<name>sizeHint</name>
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget>
<class>QTabWidget</class>
<property stdset="1">
@ -840,66 +861,6 @@
</hbox>
</widget>
</widget>
<widget>
<class>QLayoutWidget</class>
<property stdset="1">
<name>name</name>
<cstring>Layout1</cstring>
</property>
<hbox>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>6</number>
</property>
<widget>
<class>QLabel</class>
<property stdset="1">
<name>name</name>
<cstring>copyright</cstring>
</property>
<property stdset="1">
<name>text</name>
<string>(c) 2002 by christian@hohnstaedt.de</string>
</property>
</widget>
<spacer>
<property>
<name>name</name>
<cstring>Spacer2</cstring>
</property>
<property stdset="1">
<name>orientation</name>
<enum>Horizontal</enum>
</property>
<property stdset="1">
<name>sizeType</name>
<enum>Expanding</enum>
</property>
<property>
<name>sizeHint</name>
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget>
<class>QPushButton</class>
<property stdset="1">
<name>name</name>
<cstring>quitApp</cstring>
</property>
<property stdset="1">
<name>text</name>
<string>E&amp;xit</string>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<customwidgets>
@ -1007,6 +968,5 @@
<tabstop>BNserverTemp</tabstop>
<tabstop>BNchangeTemp</tabstop>
<tabstop>BNdeleteTemp</tabstop>
<tabstop>quitApp</tabstop>
</tabstops>
</UI>

View File

@ -95,9 +95,9 @@ extern void initOIDs(void);
MainWindow::MainWindow(QWidget *parent, const char *name )
:MainWindow_UI(parent, name)
{
connect( (QObject *)quitApp, SIGNAL(clicked()), (QObject *)qApp, SLOT(quit()) );
QString cpr = "(c) 2002 by Christian@Hohnstaedt.de - Version: ";
copyright->setText(cpr + VER);
//connect( (QObject *)quitApp, SIGNAL(clicked()), (QObject *)qApp, SLOT(quit()) );
//QString cpr = "(c) 2002 by Christian@Hohnstaedt.de - Version: ";
//copyright->setText(cpr + VER);
setCaption(tr(XCA_TITLE));
dbfile="xca.db";
dbenv = NULL;
@ -109,7 +109,16 @@ MainWindow::MainWindow(QWidget *parent, const char *name )
QMessageBox::warning(this,tr(XCA_TITLE), QString::fromLatin1("Could not create ") + baseDir);
qFatal( QString::fromLatin1("Couldnt create: ") + baseDir );
}
QPopupMenu *file = new QPopupMenu( this );
file->insertItem( "&Open", this, SLOT(open()), CTRL+Key_O );
file->insertItem( "&New", this, SLOT(news()), CTRL+Key_N );
file->insertItem( "&Save", this, SLOT(save()), CTRL+Key_S );
file->insertItem( "&Close", this, SLOT(closeDoc()), CTRL+Key_W );
file->insertSeparator();
file->insertItem( "E&xit", qApp, SLOT(quit()), CTRL+Key_Q );
mb = new QMenuBar( this );
mb->insertItem( "&File", file );
init_images();
connect( keyList, SIGNAL(init_database()), this, SLOT(init_database()));

View File

@ -62,6 +62,7 @@
#include "lib/exception.h"
#include <qpixmap.h>
#include <qfiledialog.h>
#include <qmenubar.h>
#define DBFILE "xca.db"
@ -75,7 +76,8 @@ class MainWindow: public MainWindow_UI
void read_cmdline();
QString getBaseDir();
DbTxn *global_tid;
QMenuBar *mb;
friend class pki_key;
public: