diff --git a/TODO b/TODO index 7ec13870..c063ffb0 100644 --- a/TODO +++ b/TODO @@ -29,9 +29,6 @@ create qt4 qmake .prf for auto-discovery by applications * finish code for APIs: - redundant global static functions in publickey / cert - CertificateOptions: isValid - Certificate: operator== cert: rfc 2818 hostname validation tls sasl diff --git a/include/QtCrypto/qca_cert.h b/include/QtCrypto/qca_cert.h index c3fc29a2..889cf43b 100644 --- a/include/QtCrypto/qca_cert.h +++ b/include/QtCrypto/qca_cert.h @@ -175,6 +175,7 @@ namespace QCA bool isSelfSigned() const; int pathLimit() const; + QSecureArray signature() const; SignatureAlgorithm signatureAlgorithm() const; // import / export @@ -222,6 +223,7 @@ namespace QCA int pathLimit() const; // PKCS#10 only QString challenge() const; + QSecureArray signature() const; SignatureAlgorithm signatureAlgorithm() const; // import / export - PKCS#10 only @@ -281,6 +283,7 @@ namespace QCA QList<CRLEntry> revoked() const; + QSecureArray signature() const; SignatureAlgorithm signatureAlgorithm() const; // import / export diff --git a/include/QtCrypto/qcaprovider.h b/include/QtCrypto/qcaprovider.h index 5241f00c..d7003e8d 100644 --- a/include/QtCrypto/qcaprovider.h +++ b/include/QtCrypto/qcaprovider.h @@ -224,6 +224,7 @@ public: class CertContextProps { public: + int version; // cert only QDateTime start, end; // cert only CertificateInfo subject; CertificateInfo issuer; // cert only @@ -233,6 +234,7 @@ public: bool isCA; bool isSelfSigned; // cert only int pathLimit; + QSecureArray sig; SignatureAlgorithm sigalgo; QString challenge; // csr only CertificateRequestFormat format; // csr only @@ -245,6 +247,7 @@ public: int number; QDateTime thisUpdate, nextUpdate; QList<CRLEntry> revoked; + QSecureArray sig; SignatureAlgorithm sigalgo; }; diff --git a/src/qca_cert.cpp b/src/qca_cert.cpp index af6f77dc..80af6d72 100644 --- a/src/qca_cert.cpp +++ b/src/qca_cert.cpp @@ -29,43 +29,11 @@ namespace QCA { Provider::Context *getContext(const QString &type, const QString &provider); -static bool stringToFile(const QString &fileName, const QString &content) -{ - QFile f(fileName); - if(!f.open(QFile::WriteOnly)) - return false; - QTextStream ts(&f); - ts << content; - return true; -} - -static bool stringFromFile(const QString &fileName, QString *s) -{ - QFile f(fileName); - if(!f.open(QFile::ReadOnly)) - return false; - QTextStream ts(&f); - *s = ts.readAll(); - return true; -} - -static bool arrayToFile(const QString &fileName, const QByteArray &content) -{ - QFile f(fileName); - if(!f.open(QFile::WriteOnly)) - return false; - f.write(content.data(), content.size()); - return true; -} - -static bool arrayFromFile(const QString &fileName, QByteArray *a) -{ - QFile f(fileName); - if(!f.open(QFile::ReadOnly)) - return false; - *a = f.readAll(); - return true; -} +// from qca_publickey.cpp +bool stringToFile(const QString &fileName, const QString &content); +bool stringFromFile(const QString &fileName, QString *s); +bool arrayToFile(const QString &fileName, const QByteArray &content); +bool arrayFromFile(const QString &fileName, QByteArray *a); //---------------------------------------------------------------------------- // CertificateOptions @@ -123,8 +91,14 @@ void CertificateOptions::setFormat(CertificateRequestFormat f) bool CertificateOptions::isValid() const { - // TODO: check the content - return false; + // logic from Botan + if(d->info.value(CommonName).isEmpty() || d->info.value(Country).isEmpty()) + return false; + if(d->info.value(Country).length() != 2) + return false; + if(d->start >= d->end) + return false; + return true; } QString CertificateOptions::challenge() const @@ -359,6 +333,11 @@ int Certificate::pathLimit() const return static_cast<const CertContext *>(context())->props()->pathLimit; } +QSecureArray Certificate::signature() const +{ + return static_cast<const CertContext *>(context())->props()->sig; +} + SignatureAlgorithm Certificate::signatureAlgorithm() const { return static_cast<const CertContext *>(context())->props()->sigalgo; @@ -428,10 +407,21 @@ bool Certificate::matchesHostname(const QString &realHost) const return false; } -bool Certificate::operator==(const Certificate &) const +bool Certificate::operator==(const Certificate &cert) const { - // TODO - return false; + const CertContextProps *a = static_cast<const CertContext *>(context())->props(); + const CertContextProps *b = static_cast<const CertContext *>(cert.context())->props(); + + // logic from Botan + if(a->sig != b->sig || a->sigalgo != b->sigalgo || subjectPublicKey() != cert.subjectPublicKey()) + return false; + if(a->issuer != b->issuer || a->subject != b->subject) + return false; + if(a->serial != b->serial || a->version != b->version) + return false; + if(a->start != b->start || a->end != b->end) + return false; + return true; } bool Certificate::operator!=(const Certificate &a) const @@ -535,6 +525,11 @@ QString CertificateRequest::challenge() const return static_cast<const CSRContext *>(context())->props()->challenge; } +QSecureArray CertificateRequest::signature() const +{ + return static_cast<const CSRContext *>(context())->props()->sig; +} + SignatureAlgorithm CertificateRequest::signatureAlgorithm() const { return static_cast<const CSRContext *>(context())->props()->sigalgo; @@ -675,6 +670,11 @@ QList<CRLEntry> CRL::revoked() const return static_cast<const CRLContext *>(context())->props()->revoked; } +QSecureArray CRL::signature() const +{ + return static_cast<const CRLContext *>(context())->props()->sig; +} + SignatureAlgorithm CRL::signatureAlgorithm() const { return static_cast<const CRLContext *>(context())->props()->sigalgo; diff --git a/src/qca_publickey.cpp b/src/qca_publickey.cpp index 1c30910f..c13903d3 100644 --- a/src/qca_publickey.cpp +++ b/src/qca_publickey.cpp @@ -28,7 +28,7 @@ namespace QCA { Provider::Context *getContext(const QString &type, const QString &provider); -static bool stringToFile(const QString &fileName, const QString &content) +bool stringToFile(const QString &fileName, const QString &content) { QFile f(fileName); if(!f.open(QFile::WriteOnly)) @@ -38,13 +38,31 @@ static bool stringToFile(const QString &fileName, const QString &content) return true; } -static bool stringFromFile(const QString &fileName, QString *str) +bool stringFromFile(const QString &fileName, QString *s) { QFile f(fileName); if(!f.open(QFile::ReadOnly)) return false; QTextStream ts(&f); - *str = ts.readAll(); + *s = ts.readAll(); + return true; +} + +bool arrayToFile(const QString &fileName, const QByteArray &content) +{ + QFile f(fileName); + if(!f.open(QFile::WriteOnly)) + return false; + f.write(content.data(), content.size()); + return true; +} + +bool arrayFromFile(const QString &fileName, QByteArray *a) +{ + QFile f(fileName); + if(!f.open(QFile::ReadOnly)) + return false; + *a = f.readAll(); return true; }