mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Support for PKCS#7 files completed. Extension *.p7b added
Certificate stack export in PKCS7 format added BUG #737031 solved
This commit is contained in:
parent
e5b7e4ab54
commit
1739747e7b
@ -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];
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user