Add the ability to convert a certificate to text
authorRichard Moore <rich@kde.org>
Mon, 20 Jun 2011 16:11:33 +0000 (18:11 +0200)
committerQt Continuous Integration System <qt-info@nokia.com>
Tue, 21 Jun 2011 14:12:55 +0000 (16:12 +0200)
Adds a function that will convert a certificate to human readable text
format using the openssl print function. This is useful for debugging
and for displaying the full details of a certificate (including those
parts not supported by the Qt API).

Change-Id: I27238d05df37f8b15ad09f8e761b06344631a9ce
Merge-request: 2
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Reviewed-on: http://codereview.qt.nokia.com/551
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
src/network/ssl/qsslcertificate.cpp
src/network/ssl/qsslcertificate.h
src/network/ssl/qsslcertificate_p.h
src/network/ssl/qsslsocket_openssl_symbols.cpp
src/network/ssl/qsslsocket_openssl_symbols_p.h

index 76b7d41..dc7b5be 100644 (file)
 #include <QtCore/qmap.h>
 #include <QtCore/qstring.h>
 #include <QtCore/qstringlist.h>
+#include <QtCore/qvarlengtharray.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -522,6 +523,17 @@ QByteArray QSslCertificate::toDer() const
 }
 
 /*!
+    Returns this certificate converted to a human-readable text
+    representation.
+*/
+QByteArray QSslCertificate::toText() const
+{
+    if (!d->x509)
+        return QByteArray();
+    return d->text_from_X509(d->x509);
+}
+
+/*!
     Searches all files in the \a path for certificates encoded in the
     specified \a format and returns them in a list. \e must be a file or a
     pattern matching one or more files, as specified by \a syntax.
@@ -666,6 +678,31 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi
     return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n";
 }
 
+QByteArray QSslCertificatePrivate::text_from_X509(X509 *x509)
+{
+    if (!x509) {
+        qWarning("QSslSocketBackendPrivate::text_from_X509: null X509");
+        return QByteArray();
+    }
+
+    QByteArray result;
+    BIO *bio = q_BIO_new(q_BIO_s_mem());
+    if (!bio)
+      return result;
+
+    q_X509_print(bio, x509);
+
+    QVarLengthArray<char, 4096> data;
+    int count = q_BIO_read(bio, data.data(), 4096);
+    if ( count > 0 ) {
+        result = QByteArray( data.data(), count );
+    }
+
+    q_BIO_free(bio);
+
+    return result;
+}
+
 static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name)
 {
     QMap<QString, QString> info;
index e52f9c1..b942bd8 100644 (file)
@@ -107,6 +107,7 @@ public:
 
     QByteArray toPem() const;
     QByteArray toDer() const;
+    QByteArray toText() const;
 
     static QList<QSslCertificate> fromPath(
         const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
index 448ca8d..eb19296 100644 (file)
@@ -93,6 +93,7 @@ public:
     void init(const QByteArray &data, QSsl::EncodingFormat format);
 
     static QByteArray QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format);
+    static QByteArray text_from_X509(X509 *x509);
     static QSslCertificate QSslCertificate_from_X509(X509 *x509);
     static QList<QSslCertificate> certificatesFromPem(const QByteArray &pem, int count = -1);
     static QList<QSslCertificate> certificatesFromDer(const QByteArray &der, int count = -1);
index a4cc3c4..c73aae0 100644 (file)
@@ -241,6 +241,7 @@ DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
 #ifndef SSLEAY_MACROS
 DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
 #endif
+DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
 DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
 DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
 DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
@@ -761,6 +762,7 @@ bool q_resolveOpenSslSymbols()
 #ifndef SSLEAY_MACROS
     RESOLVEFUNC(X509_dup)
 #endif
+    RESOLVEFUNC(X509_print)
     RESOLVEFUNC(X509_EXTENSION_get_object)
     RESOLVEFUNC(X509_free)
     RESOLVEFUNC(X509_get_ext)
index c0a3b4d..00f56d6 100644 (file)
@@ -353,6 +353,7 @@ void *q_ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
 #else
 X509 *q_X509_dup(X509 *a);
 #endif
+void q_X509_print(BIO *a, X509*b);
 ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a);
 void q_X509_free(X509 *a);
 X509_EXTENSION *q_X509_get_ext(X509 *a, int b);