Support for PKCS#7 files completed. Extension *.p7b added

Certificate stack export in PKCS7 format added
BUG #737031 solved
This commit is contained in:
chris2511 2003-05-14 12:16:12 +00:00
parent e5b7e4ab54
commit 1739747e7b
8 changed files with 122 additions and 30 deletions

View File

@ -63,7 +63,9 @@ ExportCert::ExportCert(QString fname, bool hasKey, QString dpath,
exportFormat->insertItem("PEM all trusted Certificates");
exportFormat->insertItem("PEM all Certificates");
exportFormat->insertItem("DER");
// exportFormat->insertItem("Signed PKCS#7");
exportFormat->insertItem("PKCS #7");
exportFormat->insertItem("PKCS #7 with Certificate chain");
exportFormat->insertItem("PKCS #7 all trusted Certificates");
if (hasKey) {
exportFormat->insertItem("PKCS #12");
exportFormat->insertItem("PKCS #12 with Certificate chain");
@ -98,7 +100,7 @@ void ExportCert::chooseFile()
void ExportCert::formatChanged()
{
CERR("Export format changed");
char *suffix[] = {"crt", "crt", "crt", "crt", "cer", "p12", "p12"};
char *suffix[] = {"crt", "crt", "crt", "crt", "cer", "p7b", "p7b", "p7b", "p12", "p12"};
int selected = exportFormat->currentItem();
QString fn = filename->text();
QString nfn = fn.left(fn.findRev('.')+1) + suffix[selected];

View File

@ -238,6 +238,7 @@
<name>text</name>
<string>DER is a binary format of the Certificate
PEM is a base64 encoded Certificate
PKCS#7 is an official Certificate exchange format</string>
PKCS#12 is an encrypted official Key-Certificate exchange format</string>
</property>
<property stdset="1">

View File

@ -169,6 +169,7 @@ class MainWindow: public MainWindow_UI
bool alterTemp(pki_temp *temp);
void Error(errorEx &err);
void writePKCS12(QString s, bool chain);
void writePKCS7(QString s, int type);
void setPath(QFileDialog *dlg);
QString getPath();
void newPath(QFileDialog *dlg);

View File

@ -554,9 +554,7 @@ void MainWindow::deleteCert()
void MainWindow::loadCert()
{
QStringList filt;
filt.append(tr("Certificates ( *.pem *.der *.crt *.cer)"));
filt.append(tr("PKCS#12 Certificates ( *.p12 )"));
//filt.append(tr("PKCS#7 Signatures ( *.p7s )"));
filt.append(tr("Certificates ( *.pem *.der *.crt *.cer )"));
filt.append(tr("All files ( *.* )"));
QStringList slist;
QString s="";
@ -591,7 +589,7 @@ void MainWindow::loadPKCS12()
{
pki_pkcs12 *pk12;
QStringList filt;
filt.append(tr("PKCS#12 Certificates ( *.p12 )"));
filt.append(tr("PKCS#12 Certificates ( *.p12 *.pfx )"));
filt.append(tr("All files ( *.* )"));
QStringList slist;
QString s="";
@ -658,10 +656,10 @@ void MainWindow::insertP12(pki_pkcs12 *pk12)
void MainWindow::loadPKCS7()
{
pki_pkcs7 *pk7;
pki_pkcs7 *pk7 = NULL;
pki_x509 *acert;
QStringList filt;
filt.append(tr("PKCS#7 data ( *.p7s *.p7m )"));
filt.append(tr("PKCS#7 data ( *.p7s *.p7m *.p7b )"));
filt.append(tr("All files ( *.* )"));
QStringList slist;
QString s="";
@ -680,17 +678,21 @@ void MainWindow::loadPKCS7()
s = QDir::convertSeparators(s);
try {
pk7 = new pki_pkcs7(s.latin1());
MARK
pk7->readP7(s.latin1());
MARK
for (int i=0; i<pk7->numCert(); i++) {
acert = pk7->getCert(i);
showDetailsCert(acert, true);
}
delete pk7;
keys->updateView();
}
catch (errorEx &err) {
Error(err);
}
MARK
if (pk7) delete pk7;
MARK
}
}
@ -736,6 +738,10 @@ pki_x509 *MainWindow::insertCert(pki_x509 *cert)
return cert;
}
#define P7_ONLY 0
#define P7_CHAIN 1
#define P7_TRUSTED 2
void MainWindow::writeCert()
{
QStringList filt;
@ -779,10 +785,19 @@ void MainWindow::writeCert()
case 4: // DER
crt->writeCert(fname.latin1(),false,false);
break;
case 5: // P12
case 5: // P7 lonely
writePKCS7(fname, P7_ONLY);
break;
case 6: // P12
writePKCS7(fname, P7_CHAIN);
break;
case 7: // P12
writePKCS7(fname, P7_TRUSTED);
break;
case 8: // P12
writePKCS12(fname,false);
break;
case 6: // P12 + cert chain
case 9: // P12 + cert chain
writePKCS12(fname,true);
break;
@ -829,6 +844,39 @@ void MainWindow::writePKCS12(QString s, bool chain)
}
}
void MainWindow::writePKCS7(QString s, int type) {
pki_pkcs7 *p7 = NULL;
QList<pki_x509> list;
pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
try {
p7 = new pki_pkcs7("");
if ( type == P7_CHAIN ) {
while (cert != NULL) {
p7->addCert(cert);
if (cert->getSigner() == cert) cert = NULL;
else cert = cert->getSigner();
}
}
if ( type == P7_ONLY ) {
p7->addCert(cert);
}
if (type == P7_TRUSTED) {
list = certs->getCerts(true);
if (!list.isEmpty()) {
for ( cert = list.first(); cert != NULL; cert = list.next() ) {
p7->addCert(cert);
}
}
}
p7->writeP7(s.latin1(), false);
}
catch (errorEx &err) {
Error(err);
}
if (p7 != NULL ) delete p7;
}
void MainWindow::signP7()
{
QStringList filt;

View File

@ -396,6 +396,18 @@ void db_x509::writeAllCerts(QString fname, bool onlyTrusted)
}
}
QList<pki_x509> db_x509::getCerts(bool onlyTrusted)
{
QList<pki_x509> c;
c.clear();
pki_x509 *cert = NULL;
for ( cert = (pki_x509 *)container.first(); cert != 0; cert = (pki_x509 *)container.next() ) {
if (onlyTrusted && cert->getTrust() != 2) continue;
c.append(cert);
}
return c;
}
int db_x509::searchSerial(pki_x509 *signer)
{
if (!signer) return 0;

View File

@ -80,8 +80,9 @@ class db_x509: public db_base
QStringList getSignerDesc();
pki_key * findKey(pki_x509 *cert);
void calcEffTrust();
QList<pki_x509> db_x509::getIssuedCerts(pki_x509 *issuer);
pki_x509 *db_x509::getBySubject(X509_NAME *xname);
QList<pki_x509> getIssuedCerts(pki_x509 *issuer);
QList<pki_x509> getCerts(bool onlyTrusted);
pki_x509 *getBySubject(X509_NAME *xname);
int searchSerial(pki_x509 *signer);
void writeAllCerts(QString fname, bool onlyTrusted);
pki_x509 *getByIssSerial(pki_x509 *iss, long serial);

View File

@ -55,8 +55,9 @@
pki_pkcs7::pki_pkcs7(const string d )
:pki_base(d)
{
p7 = NULL;
certstack = NULL;
p7 = PKCS7_new();
PKCS7_set_type(p7, NID_pkcs7_signed);
PKCS7_content_new(p7, NID_pkcs7_data);
className = "pki_pkcs7";
}
@ -64,16 +65,14 @@ pki_pkcs7::pki_pkcs7(const string d )
pki_pkcs7::~pki_pkcs7()
{
if (p7) PKCS7_free(p7);
if (certstack) sk_X509_free(certstack);
}
void pki_pkcs7::encryptFile(pki_x509 *crt, string filename)
{
BIO *bio = NULL;
STACK_OF(X509) *certstack;
if (!crt) return;
bio = BIO_new_file(filename.c_str(), "r");
openssl_error();
if (certstack) sk_X509_free(certstack);
certstack = sk_X509_new_null();
sk_X509_push(certstack, crt->getCert());
openssl_error();
@ -81,29 +80,30 @@ void pki_pkcs7::encryptFile(pki_x509 *crt, string filename)
p7 = PKCS7_encrypt(certstack, bio, EVP_des_ede3_cbc(), PKCS7_BINARY);
openssl_error();
sk_X509_free(certstack);
certstack = NULL;
}
void pki_pkcs7::signBio(pki_x509 *crt, BIO *bio)
{
pki_key *privkey;
STACK_OF(X509) *certstack;
if (!crt) return;
privkey = crt->getKey();
if (!privkey) throw errorEx("No private key for signing found", className);
if (certstack) sk_X509_free(certstack);
certstack = sk_X509_new_null();
pki_x509 *signer = crt->getSigner();
while (signer != NULL && signer != signer->getSigner()) {
if (signer == crt) signer = NULL;
while (signer != NULL ) {
CERR("SIGNER: "<<signer->getDescription())
sk_X509_push(certstack, signer->getCert());
openssl_error();
signer = signer->getSigner();
CERR("SIGNER: "<<signer->getDescription())
if (signer == signer->getSigner() ) signer = NULL;
else signer = signer->getSigner();
}
if (p7) PKCS7_free(p7);
p7 = PKCS7_sign(crt->getCert(), privkey->getKey(), certstack, bio, PKCS7_BINARY);
openssl_error();
sk_X509_free(certstack);
certstack = NULL;
}
@ -146,17 +146,15 @@ void pki_pkcs7::writeP7(string fname,bool PEM)
}
pki_x509 *pki_pkcs7::getCert(int x) {
if (!certstack) return NULL;
pki_x509 *cert;
cert = new pki_x509(X509_dup(sk_X509_value(certstack, x)));
cert = new pki_x509(X509_dup(sk_X509_value(getCertStack(), x)));
openssl_error();
cert->setDescription("pk7-import");
return cert;
}
int pki_pkcs7::numCert() {
if (!certstack) return 0;
int n= sk_X509_num(certstack);
int n= sk_X509_num(getCertStack());
openssl_error();
return n;
}
@ -169,6 +167,7 @@ void pki_pkcs7::readP7(string fname)
p7 = PEM_read_PKCS7(fp, NULL, NULL, NULL);
if (!p7) {
ign_openssl_error();
rewind(fp);
CERR("Fallback to DER encoded PKCS#7");
p7 = d2i_PKCS7_fp(fp, &p7);
}
@ -176,7 +175,34 @@ void pki_pkcs7::readP7(string fname)
fclose(fp);
openssl_error();
}
certstack = PKCS7_get0_signers(p7, NULL, 0);
else fopen_error(fname);
}
STACK_OF(X509) *pki_pkcs7::getCertStack() {
STACK_OF(X509) *certstack = NULL;
int i;
if (p7 == NULL) return NULL;
i = OBJ_obj2nid(p7->type);
switch (i) {
case NID_pkcs7_signed:
certstack = p7->d.sign->cert;
CERR("PKCS#7: SIGNED");
break;
case NID_pkcs7_signedAndEnveloped:
certstack = p7->d.signed_and_enveloped->cert;
CERR("PKCS#7: SIGNED and ENVELOPED");
break;
default:
break;
}
openssl_error();
return certstack;
}
void pki_pkcs7::addCert(pki_x509 *crt) {
if (p7 == NULL || crt == NULL) return;
PKCS7_add_certificate(p7, crt->getCert());
openssl_error();
}

View File

@ -62,7 +62,7 @@ class pki_pkcs7: public pki_base
friend class pki_x509;
protected:
PKCS7 *p7;
STACK_OF(X509) *certstack;
STACK_OF(X509) *getCertStack();
void signBio(pki_x509 *crt, BIO * bio);
public:
pki_pkcs7(const string d);
@ -75,6 +75,7 @@ class pki_pkcs7: public pki_base
void writeP7(string fname,bool PEM);
void readP7(string fname);
pki_x509 *getCert(int x);
void addCert(pki_x509 *crt);
int numCert(); // number of certs;
};