mirror of
https://github.com/chris2511/xca.git
synced 2026-09-14 11:06:19 +05:00
SPKAC enhancement patch from W. Glas added
Mainwindow menu bar added
This commit is contained in:
parent
5cf00e9c80
commit
b49ee62e68
8
AUTHORS
8
AUTHORS
@ -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
|
||||
|
||||
@ -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 +")" );
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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&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>
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user