Revert "Revert "qt4: Updated to v4.7.3"
[openembedded.git] / recipes / qt4 / files / blacklist-fraudulent-comodo-certificates-patch.diff
1 Security advisory: Fraudulent certificates
2
3 Background:
4
5 Recently a group of people managed to get fraudulent SSL certificates signed
6 by a Certificate Authority (CA).
7
8 These certificates potentially enable their owners to pretend to be other
9 entities on the Web; the attackers can present valid certificates for e.g.
10 mail.google.com, login.yahoo.com and login.live.com, among others.
11
12 The patch below solves this problem by blacklisting those fake certificates
13 and aborting an SSL handshake with entities that present these certificates.
14 The patch applies to all 4.6 and 4.7 versions, and should be applied to all Qt
15 4.6.x and 4.7.x versions; upcoming Qt releases will contain a fix for this
16 problem.
17
18 More technical background:
19
20 In order to trick a user into establishing an SSL connection to a site using
21 one of those fake certificates, in addition to controlling the certificate, an
22 attacker would need to either control the DNS server used by the victim, or
23 have control over a proxy that the victim uses. That way, the attacker could
24 trick the victim to connect to the attacker?s site and then present the user
25 with a valid certificate.
26
27 One obvious question now is: Should those certificates not just be revoked,
28 which would solve the problem?
29
30 First, they have been revoked by the affected Certificate Authority (see above
31 link).
32
33 However, the problem in this case, and probably part of the reason why most
34 browser vendors release new versions blacklisting those certificates, is that
35 by default browsers do not treat invalid responses from an OCSP server (a
36 server used for checking the revocation status of a certificate) as fatal, and
37 will allow the SSL connection to proceed anyway. Qt itself does not support
38 OCSP yet, which makes blacklisting the certificates the only valid option (now
39 would be a good moment to vote on the task for implementing OCSP in Qt); since
40 Qt is relying on the system root certificates since version 4.7, it cannot
41 control the root certificates that Qt trusts automatically anymore.
42
43 http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html
44 http://qt.nokia.com/files/qt-patches/blacklist-fraudulent-comodo-certificates-patch.diff/view
45
46 diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
47 index 618ac79..a5cdf01 100644
48 --- a/src/network/ssl/qsslcertificate.cpp
49 +++ b/src/network/ssl/qsslcertificate.cpp
50 @@ -219,17 +219,19 @@ bool QSslCertificate::isNull() const
51      Returns true if this certificate is valid; otherwise returns
52      false.
53  
54 -    Note: Currently, this function only checks that the current
55 +    Note: Currently, this function checks that the current
56      data-time is within the date-time range during which the
57 -    certificate is considered valid. No other checks are
58 -    currently performed.
59 +    certificate is considered valid, and checks that the
60 +    certificate is not in a blacklist of fraudulent certificates.
61  
62      \sa isNull()
63  */
64  bool QSslCertificate::isValid() const
65  {
66      const QDateTime currentTime = QDateTime::currentDateTime();
67 -    return currentTime >= d->notValidBefore && currentTime <= d->notValidAfter;
68 +    return currentTime >= d->notValidBefore &&
69 +            currentTime <= d->notValidAfter &&
70 +            ! QSslCertificatePrivate::isBlacklisted(*this);
71  }
72  
73  /*!
74 @@ -798,6 +800,30 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr
75      return certificates;
76  }
77  
78 +// These certificates are known to be fraudulent and were created during the comodo
79 +// compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html
80 +static const char *certificate_blacklist[] = {
81 +    "04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e",
82 +    "f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06",
83 +    "d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3",
84 +    "39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29",
85 +    "3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71",
86 +    "e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47",
87 +    "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43",
88 +    "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0",
89 +    "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0",
90 +    0
91 +};
92 +
93 +bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate)
94 +{
95 +    for (int a = 0; certificate_blacklist[a] != 0; a++) {
96 +        if (certificate.serialNumber() == certificate_blacklist[a])
97 +            return true;
98 +    }
99 +    return false;
100 +}
101 +
102  #ifndef QT_NO_DEBUG_STREAM
103  QDebug operator<<(QDebug debug, const QSslCertificate &certificate)
104  {
105 diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
106 index cdceb0f..1ce33d3 100644
107 --- a/src/network/ssl/qsslcertificate_p.h
108 +++ b/src/network/ssl/qsslcertificate_p.h
109 @@ -96,6 +96,7 @@ public:
110      static QSslCertificate QSslCertificate_from_X509(X509 *x509);
111      static QList<QSslCertificate> certificatesFromPem(const QByteArray &pem, int count = -1);
112      static QList<QSslCertificate> certificatesFromDer(const QByteArray &der, int count = -1);
113 +    static bool isBlacklisted(const QSslCertificate &certificate);
114  
115      friend class QSslSocketBackendPrivate;
116  
117 diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
118 index 0866534..2427193 100644
119 --- a/src/network/ssl/qsslsocket_openssl.cpp
120 +++ b/src/network/ssl/qsslsocket_openssl.cpp
121 @@ -1193,6 +1193,13 @@ bool QSslSocketBackendPrivate::startHandshake()
122      X509 *x509 = q_SSL_get_peer_certificate(ssl);
123      configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
124      q_X509_free(x509);
125 +    if (QSslCertificatePrivate::isBlacklisted(configuration.peerCertificate)) {
126 +        q->setErrorString(QSslSocket::tr("The peer certificate is blacklisted"));
127 +        q->setSocketError(QAbstractSocket::SslHandshakeFailedError);
128 +        emit q->error(QAbstractSocket::SslHandshakeFailedError);
129 +        plainSocket->disconnectFromHost();
130 +        return false;
131 +    }
132  
133      // Start translating errors.
134      QList<QSslError> errors;