mirror of
https://github.com/chris2511/xca.git
synced 2026-09-14 11:06:19 +05:00
Close #313: Support JWK export format of certificates
The "x5t" and "x5t#256" properties are always present. The "x5c" Certificate chain can be optionally selected.
This commit is contained in:
parent
2e70aa6329
commit
60aefeac53
@ -563,6 +563,11 @@ int db_x509::exportFlags(const QModelIndex &idx) const
|
||||
if (!crt->isCA())
|
||||
disable_flags |= F_CA;
|
||||
|
||||
pki_key *key = crt->getPubKey();
|
||||
if (key && key->getKeyType() != EVP_PKEY_RSA && key->getJWKcrv().isEmpty())
|
||||
disable_flags |= F_JWK;
|
||||
delete key;
|
||||
|
||||
return disable_flags;
|
||||
}
|
||||
|
||||
@ -643,12 +648,8 @@ void db_x509::exportItems(const QModelIndexList &list,
|
||||
foreach(crt, certs)
|
||||
crt->writeCert(file, true);
|
||||
}
|
||||
} else if (xport->match_all(F_DER)) {
|
||||
crt->writeCert(file, false);
|
||||
} else if (xport->match_all(F_PKCS7)) {
|
||||
writePKCS7(crt, file, xport->flags, list);
|
||||
} else if (xport->match_all(F_PKCS12)) {
|
||||
writePKCS12(crt, file, xport->match_all(F_CHAIN));
|
||||
} else if (xport->match_all(F_INDEX)) {
|
||||
writeIndex(file, certs);
|
||||
} else if (xport->match_all(F_CAL)) {
|
||||
@ -658,10 +659,27 @@ void db_x509::exportItems(const QModelIndexList &list,
|
||||
crt->icsVEVENT_ca() : crt->icsVEVENT();
|
||||
}
|
||||
writeVcalendar(file, vcal);
|
||||
} else if (xport->match_all(F_CONFIG)) {
|
||||
crt->opensslConf(file);
|
||||
} else if (xport->match_all(F_TAKEY)) {
|
||||
file.write(crt->getTaKey().toLatin1());
|
||||
} else {
|
||||
qDebug() << "exportItems: db_base";
|
||||
db_base::exportItems(list, xport, file);
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::exportItem(const QModelIndex &index,
|
||||
const pki_export *xport, XFile &file) const
|
||||
{
|
||||
pki_x509 *crt = fromIndex<pki_x509>(index);
|
||||
|
||||
if (xport->match_all(F_DER)) {
|
||||
crt->writeCert(file, false);
|
||||
} else if (xport->match_all(F_PKCS12)) {
|
||||
writePKCS12(crt, file, xport->match_all(F_CHAIN));
|
||||
} else if (xport->match_all(F_CONFIG)) {
|
||||
crt->opensslConf(file);
|
||||
} else {
|
||||
db_base::exportItem(index, xport, file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -64,6 +64,7 @@ class db_x509: public db_x509super
|
||||
int exportFlags(const QModelIndex &idx) const;
|
||||
void exportItems(const QModelIndexList &indexes,
|
||||
const pki_export *xport, XFile &file) const;
|
||||
void exportItem(const QModelIndex &, const pki_export *, XFile &) const;
|
||||
|
||||
public slots:
|
||||
void newItem();
|
||||
|
||||
@ -80,6 +80,8 @@ new pki_export(17, x509, "ics", tr("vCalendar"), F_CAL,
|
||||
new pki_export(18, x509, "ics", tr("CA vCalendar"), F_CAL | F_CA, tr("vCalendar expiry reminder containing all issued, valid certificates, the CA itself and the latest CRL")),
|
||||
new pki_export(38, x509, "conf", tr("OpenSSL config"), F_SINGLE | F_CONFIG, tr("OpenSSL configuration file to create a certificate or request with the openssl commandline tool")),
|
||||
new pki_export(39, x509, "key", tr("OpenVPN tls-auth key"), F_SINGLE | F_TAKEY, tr("The OpenVPN tls-auth key is a secret key shared between endpoints")),
|
||||
new pki_export(42, x509, "jwk", tr("JSON Web Kit"), F_JWK, tr("The public key of the certificate in JSON Web Kit format with X.509 Certificate Thumbprint (x5t)")),
|
||||
new pki_export(43, x509, "jwk", tr("JSON Web Kit chain"), F_JWK | F_JWK_X5C, tr("The public key of the certificate in JSON Web Kit format with X.509 Certificate Thumbprint (x5t) and certificate chain (x5c)")),
|
||||
|
||||
new pki_export(19, asym_key, "pem", tr("PEM public"), F_PEM | F_CLIPBOARD, tr("Text format of the public key in one PEM file")),
|
||||
new pki_export(20, asym_key, "pem", tr("PEM private"), F_PEM | F_PRIVATE | F_USUAL | F_CLIPBOARD, tr("Unencrypted private key in text format")),
|
||||
|
||||
@ -54,6 +54,7 @@ enum {
|
||||
F_TRADITION = BIT(23),/* Traditional OpenSSL encrypted PEM */
|
||||
F_UNUSABLE = BIT(24),/* Unusable certificates */
|
||||
F_JWK = BIT(25),/* JSON Web Key (JWK) RFC-7517 */
|
||||
F_JWK_X5C = BIT(26),/* JSON Web Key (JWK) RFC-7517 X.509 Certificate Chain */
|
||||
};
|
||||
|
||||
class pki_export : public QObject {
|
||||
|
||||
@ -739,6 +739,28 @@ bool pki_x509::pem(BioByteArray &b)
|
||||
return true;
|
||||
}
|
||||
|
||||
void pki_x509::fillJWK(QJsonObject &json, const pki_export *xport) const
|
||||
{
|
||||
QByteArray der = i2d();
|
||||
pki_key *key = getPubKey();
|
||||
|
||||
key->fillJWK(json, xport);
|
||||
json["kid"] = getIntName();
|
||||
json["x5t"] = BioByteArray(Digest(der, EVP_sha1())).base64UrlEncode();
|
||||
json["x5t#256"] = BioByteArray(Digest(der, EVP_sha256())).base64UrlEncode();
|
||||
if (xport->match_all(F_JWK_X5C)) {
|
||||
QJsonArray x5c;
|
||||
for (const pki_x509 *cert = this, *prev = nullptr;
|
||||
cert && cert != prev;
|
||||
prev = cert, cert = cert->getSigner())
|
||||
{
|
||||
x5c.append(cert->i2d_b64());
|
||||
}
|
||||
json["x5c"] = x5c;
|
||||
}
|
||||
delete key;
|
||||
}
|
||||
|
||||
bool pki_x509::cmpIssuerAndSerial(pki_x509 *refcert)
|
||||
{
|
||||
bool ret = X509_issuer_and_serial_cmp(cert, refcert->cert);
|
||||
@ -869,7 +891,7 @@ void pki_x509::setPubKey(pki_key *key)
|
||||
|
||||
QString pki_x509::fingerprint(const EVP_MD *digest) const
|
||||
{
|
||||
return ::fingerprint(i2d_bytearray(I2D_VOID(i2d_X509), cert), digest);
|
||||
return ::fingerprint(i2d(), digest);
|
||||
}
|
||||
|
||||
bool pki_x509::checkDate()
|
||||
@ -918,7 +940,7 @@ int pki_x509::sigAlg() const
|
||||
return X509_get_signature_nid(cert);
|
||||
}
|
||||
|
||||
pki_x509 *pki_x509::getSigner()
|
||||
pki_x509 *pki_x509::getSigner() const
|
||||
{
|
||||
return Store.lookupPki<pki_x509>(issuerSqlId);
|
||||
}
|
||||
|
||||
@ -80,12 +80,13 @@ class pki_x509 : public pki_x509super
|
||||
bool isCA() const;
|
||||
bool canSign() const;
|
||||
void writeCert(XFile &file, bool PEM) const;
|
||||
void fillJWK(QJsonObject &json, const pki_export *xport) const;
|
||||
QString getIndexEntry();
|
||||
bool verify(pki_x509 *signer);
|
||||
bool verify_only(const pki_x509 *signer) const;
|
||||
pki_key *getPubKey() const;
|
||||
void setPubKey(pki_key *key);
|
||||
pki_x509 *getSigner();
|
||||
pki_x509 *getSigner() const;
|
||||
void delSigner(pki_base *s);
|
||||
QString fingerprint(const EVP_MD *digest) const;
|
||||
extList getV3ext() const;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user