xca/lib/pki_multi.cpp
Christian Hohnstaedt de851ed3a9 Changed all header includes to QT4 names and included the correct component name
By Andreas Piesk. Thanks!

adapt to HEAD since the patch is based on 0.6.4

drop qt4/Qt include in list of includes during configuration
2010-06-13 11:49:38 +02:00

180 lines
3.7 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2001 - 2009 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "pki_multi.h"
#include "pki_x509.h"
#include "pki_key.h"
#include "pki_x509req.h"
#include "pki_pkcs7.h"
#include "pki_pkcs12.h"
#include "pki_crl.h"
#include "load_obj.h"
#include "exception.h"
#include "func.h"
#include "widgets/MainWindow.h"
#include <QtCore/QList>
pki_multi::pki_multi(const QString name)
:pki_base(name)
{
multi.clear();
class_name="pki_multi";
}
pki_multi::~pki_multi()
{
pki_base *pki;
while ((pki = pull()))
delete pki;
}
pki_base *pki_multi::pull()
{
if (multi.isEmpty())
return NULL;
return multi.takeFirst();
}
/* General PEM loader */
static pki_base *pkiByPEM(QString text, int *skip)
{
int pos;
#define D5 "-----"
#define BEGIN D5 "BEGIN "
pos = text.indexOf(BEGIN);
if (pos <0) {
if (skip)
*skip = text.length() - (sizeof(BEGIN)-1);
return NULL;
}
if (skip) {
*skip = pos;
if (pos) /* if we are not at the beginning, retry */
return NULL;
}
text = text.remove(0, pos + sizeof(BEGIN)-1);
if (text.startsWith(PEM_STRING_X509_OLD D5) ||
text.startsWith(PEM_STRING_X509 D5) ||
text.startsWith(PEM_STRING_X509_TRUSTED D5))
return new pki_x509();
if (text.startsWith(PEM_STRING_PKCS7 D5))
return new pki_pkcs7();
if (text.startsWith(PEM_STRING_X509_REQ_OLD D5) ||
text.startsWith(PEM_STRING_X509_REQ D5))
return new pki_x509req();
if (text.startsWith(PEM_STRING_X509_CRL D5))
return new pki_crl();
if (text.startsWith(PEM_STRING_EVP_PKEY D5) ||
text.startsWith(PEM_STRING_PUBLIC D5) ||
text.startsWith(PEM_STRING_RSA D5) ||
text.startsWith(PEM_STRING_RSA_PUBLIC D5) ||
text.startsWith(PEM_STRING_DSA D5) ||
text.startsWith(PEM_STRING_DSA_PUBLIC D5) ||
text.startsWith(PEM_STRING_ECDSA_PUBLIC D5) ||
text.startsWith(PEM_STRING_ECPRIVATEKEY D5) ||
text.startsWith(PEM_STRING_PKCS8 D5) ||
text.startsWith(PEM_STRING_PKCS8INF D5))
return new pki_evp();
return NULL;
}
void pki_multi::fload(const QString fname)
{
FILE * fp;
BIO *bio = NULL;
fp = fopen(QString2filename(fname), "r");
if (!fp) {
fopen_error(fname);
return;
}
bio = BIO_new_fp(fp, BIO_CLOSE);
fromPEM_BIO(bio, fname);
BIO_free(bio);
};
#define BUFLEN 1024
void pki_multi::fromPEM_BIO(BIO *bio, QString name)
{
QString text;
pki_base *item = NULL;
char buf[BUFLEN];
int len, startpos;
for (;;) {
try {
int pos = BIO_tell(bio);
len = BIO_read(bio, buf, BUFLEN-1);
buf[len] = '\0';
text = buf;
item = pkiByPEM(text, &startpos);
if (!item) {
if (startpos <= 0)
break;
if (BIO_seek(bio, pos + startpos) == -1)
throw errorEx(tr("Seek failed"));
continue;
}
pos += startpos;
if (BIO_seek(bio, pos))
throw errorEx(tr("Seek failed"));
item->fromPEM_BIO(bio, name);
if (pos == BIO_tell(bio)) {
/* No progress, do it manually */
if (BIO_seek(bio, pos + 1))
throw errorEx(tr("Seek failed"));
printf("Could not load: %s\n",
CCHAR(item->getClassName()));
delete item;
continue;
}
openssl_error();
multi.append(item);
} catch (errorEx &err) {
MainWindow::Error(err);
if (item)
delete item;
item = NULL;
}
}
}
void pki_multi::probeAnything(const QString fname)
{
pki_base *item = NULL;
load_base *lb;
QList<load_base *> lbs;
lbs << new load_cert() << new load_pkcs7() << new load_pkcs12() <<
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);
if (item) {
multi.append(item);
break;
}
} catch (errorEx &err) {
; // ignore
}
}
while (!lbs.isEmpty())
delete lbs.takeFirst();
}