Use OpenSSL X509_NAME_ENTRY API to parse UTF8 subjectName/issuerName
authorRaul Metsma <raul@innovaatik.ee>
Wed, 4 May 2011 15:40:15 +0000 (17:40 +0200)
committerPeter Hartmann <peter.hartmann@nokia.com>
Mon, 23 May 2011 15:41:47 +0000 (17:41 +0200)
... to be able to display non-ASCII names from subject and issuerInfo.

Task-number: QTBUG-7912
Merge-request: 922
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
(cherry picked from commit e5d94256be2525c24a8b61edd771662b7f2b8be3)

src/network/ssl/qsslcertificate.cpp
src/network/ssl/qsslsocket_openssl_symbols.cpp
src/network/ssl/qsslsocket_openssl_symbols_p.h

index a5cdf01..9887438 100644 (file)
 QT_BEGIN_NAMESPACE
 
 // forward declaration
-static QMap<QString, QString> _q_mapFromOnelineName(char *name);
+static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name);
 
 /*!
     Constructs a QSslCertificate by reading \a format encoded data
@@ -324,7 +324,7 @@ QString QSslCertificate::issuerInfo(SubjectInfo info) const
     // lazy init
     if (d->issuerInfo.isEmpty() && d->x509)
         d->issuerInfo =
-                _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0));
+                _q_mapFromX509Name(q_X509_get_issuer_name(d->x509));
 
     return d->issuerInfo.value(_q_SubjectInfoToString(info));
 }
@@ -341,7 +341,7 @@ QString QSslCertificate::issuerInfo(const QByteArray &tag) const
     // lazy init
     if (d->issuerInfo.isEmpty() && d->x509)
         d->issuerInfo =
-                _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0));
+                _q_mapFromX509Name(q_X509_get_issuer_name(d->x509));
 
     return d->issuerInfo.value(QString::fromLatin1(tag));
 }
@@ -360,7 +360,7 @@ QString QSslCertificate::subjectInfo(SubjectInfo info) const
     // lazy init
     if (d->subjectInfo.isEmpty() && d->x509)
         d->subjectInfo =
-                _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0));
+                _q_mapFromX509Name(q_X509_get_subject_name(d->x509));
 
     return d->subjectInfo.value(_q_SubjectInfoToString(info));
 }
@@ -376,7 +376,7 @@ QString QSslCertificate::subjectInfo(const QByteArray &tag) const
     // lazy init
     if (d->subjectInfo.isEmpty() && d->x509)
         d->subjectInfo =
-                _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0));
+                _q_mapFromX509Name(q_X509_get_subject_name(d->x509));
 
     return d->subjectInfo.value(QString::fromLatin1(tag));
 }
@@ -666,37 +666,18 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi
     return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n";
 }
 
-static QMap<QString, QString> _q_mapFromOnelineName(char *name)
+static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name)
 {
     QMap<QString, QString> info;
-    QString infoStr = QString::fromLocal8Bit(name);
-    q_CRYPTO_free(name);
-
-    // ### The right-hand encoding seems to allow hex (Regulierungsbeh\xC8orde)
-    //entry.replace(QLatin1String("\\x"), QLatin1String("%"));
-    //entry = QUrl::fromPercentEncoding(entry.toLatin1());
-    // ### See RFC-4630 for more details!
-
-    QRegExp rx(QLatin1String("/([A-Za-z]+)=(.+)"));
-
-    int pos = 0;
-    while ((pos = rx.indexIn(infoStr, pos)) != -1) {
-        const QString name = rx.cap(1);
-
-        QString value = rx.cap(2);
-        const int valuePos = rx.pos(2);
-
-        const int next = rx.indexIn(value);
-        if (next == -1) {
-            info.insert(name, value);
-            break;
-        }
-
-        value = value.left(next);
-        info.insert(name, value);
-        pos = valuePos + value.length();
+    for( int i = 0; i < q_X509_NAME_entry_count(name); ++i )  
+    {
+        X509_NAME_ENTRY *e = q_X509_NAME_get_entry( name, i );
+        const char *obj = q_OBJ_nid2sn( q_OBJ_obj2nid( q_X509_NAME_ENTRY_get_object( e ) ) );
+        unsigned char *data = 0;
+        int size = q_ASN1_STRING_to_UTF8( &data, q_X509_NAME_ENTRY_get_data( e ) );
+        info[QString::fromUtf8( obj )] = QString::fromUtf8( (char*)data, size );
+        q_CRYPTO_free( data );
     }
-
     return info;
 }
 
index b1310cc..6cb4794 100644 (file)
@@ -101,6 +101,7 @@ DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c,
 DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return)
 DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
 DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
+DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return);
 DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
 DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
 DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
@@ -248,7 +249,10 @@ DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d
 DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
 DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
 DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
-DEFINEFUNC3(char *, X509_NAME_oneline, X509_NAME *a, a, char *b, b, int c, c, return 0, return)
+DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
+DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
+DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return)
+DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return)
 DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
 DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
 DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
@@ -647,6 +651,7 @@ bool q_resolveOpenSslSymbols()
     RESOLVEFUNC(ASN1_INTEGER_get)
     RESOLVEFUNC(ASN1_STRING_data)
     RESOLVEFUNC(ASN1_STRING_length)
+    RESOLVEFUNC(ASN1_STRING_to_UTF8)
     RESOLVEFUNC(BIO_ctrl)
     RESOLVEFUNC(BIO_free)
     RESOLVEFUNC(BIO_new)
@@ -736,7 +741,10 @@ bool q_resolveOpenSslSymbols()
     RESOLVEFUNC(SSLv3_server_method)
     RESOLVEFUNC(SSLv23_server_method)
     RESOLVEFUNC(TLSv1_server_method)
-    RESOLVEFUNC(X509_NAME_oneline)
+    RESOLVEFUNC(X509_NAME_entry_count)
+    RESOLVEFUNC(X509_NAME_get_entry)
+    RESOLVEFUNC(X509_NAME_ENTRY_get_data)
+    RESOLVEFUNC(X509_NAME_ENTRY_get_object)
     RESOLVEFUNC(X509_PUBKEY_get)
     RESOLVEFUNC(X509_STORE_free)
     RESOLVEFUNC(X509_STORE_new)
index 49830ac..ceff57d 100644 (file)
@@ -204,6 +204,7 @@ bool q_resolveOpenSslSymbols();
 long q_ASN1_INTEGER_get(ASN1_INTEGER *a);
 unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
 int q_ASN1_STRING_length(ASN1_STRING *a);
+int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b);
 long q_BIO_ctrl(BIO *a, int b, long c, void *d);
 int q_BIO_free(BIO *a);
 BIO *q_BIO_new(BIO_METHOD *a);
@@ -360,7 +361,10 @@ void *q_X509_get_ext_d2i(X509 *a, int b, int *c, int *d);
 X509_NAME *q_X509_get_issuer_name(X509 *a);
 X509_NAME *q_X509_get_subject_name(X509 *a);
 int q_X509_verify_cert(X509_STORE_CTX *ctx);
-char *q_X509_NAME_oneline(X509_NAME *a, char *b, int c);
+int q_X509_NAME_entry_count(X509_NAME *a);
+X509_NAME_ENTRY *q_X509_NAME_get_entry(X509_NAME *a,int b);
+ASN1_STRING *q_X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *a);
+ASN1_OBJECT *q_X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *a);
 EVP_PKEY *q_X509_PUBKEY_get(X509_PUBKEY *a);
 void q_X509_STORE_free(X509_STORE *store);
 X509_STORE *q_X509_STORE_new();