Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/network/ssl/qsslcertificate_openssl.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||
2 | - | |||||||||||||
3 | - | |||||||||||||
4 | - | |||||||||||||
5 | - | |||||||||||||
6 | static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name); | - | ||||||||||||
7 | - | |||||||||||||
8 | bool QSslCertificate::operator==(const QSslCertificate &other) const | - | ||||||||||||
9 | { | - | ||||||||||||
10 | if (d == other.d) | - | ||||||||||||
11 | return true; | - | ||||||||||||
12 | if (d->null && other.d->null) | - | ||||||||||||
13 | return true; | - | ||||||||||||
14 | if (d->x509 && other.d->x509) | - | ||||||||||||
15 | return q_X509_cmp(d->x509, other.d->x509) == 0; | - | ||||||||||||
16 | return false; | - | ||||||||||||
17 | } | - | ||||||||||||
18 | - | |||||||||||||
19 | uint qHash(const QSslCertificate &key, uint seed) noexcept | - | ||||||||||||
20 | { | - | ||||||||||||
21 | if (X509 * const x509 = key.d->x509
| 0-4 | ||||||||||||
22 | (void)q_X509_cmp(x509, x509); | - | ||||||||||||
23 | - | |||||||||||||
24 | return never executed: qHashBits(x509->sha1_hash, 20, seed);return qHashBits(x509->sha1_hash, 20, seed); never executed: return qHashBits(x509->sha1_hash, 20, seed); | 0 | ||||||||||||
25 | } else { | - | ||||||||||||
26 | return executed 4 times by 2 tests: seed;return seed; Executed by:
executed 4 times by 2 tests: return seed; Executed by:
| 4 | ||||||||||||
27 | } | - | ||||||||||||
28 | } | - | ||||||||||||
29 | - | |||||||||||||
30 | bool QSslCertificate::isNull() const | - | ||||||||||||
31 | { | - | ||||||||||||
32 | return d->null; | - | ||||||||||||
33 | } | - | ||||||||||||
34 | - | |||||||||||||
35 | bool QSslCertificate::isSelfSigned() const | - | ||||||||||||
36 | { | - | ||||||||||||
37 | if (!d->x509) | - | ||||||||||||
38 | return false; | - | ||||||||||||
39 | - | |||||||||||||
40 | return (q_X509_check_issued(d->x509, d->x509) == 0); | - | ||||||||||||
41 | } | - | ||||||||||||
42 | - | |||||||||||||
43 | QByteArray QSslCertificate::version() const | - | ||||||||||||
44 | { | - | ||||||||||||
45 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
46 | if (d->versionString.isEmpty() && d->x509) | - | ||||||||||||
47 | d->versionString = | - | ||||||||||||
48 | QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->version)) + 1); | - | ||||||||||||
49 | - | |||||||||||||
50 | return d->versionString; | - | ||||||||||||
51 | } | - | ||||||||||||
52 | - | |||||||||||||
53 | QByteArray QSslCertificate::serialNumber() const | - | ||||||||||||
54 | { | - | ||||||||||||
55 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
56 | if (d->serialNumberString.isEmpty() && d->x509) { | - | ||||||||||||
57 | ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber; | - | ||||||||||||
58 | QByteArray hexString; | - | ||||||||||||
59 | hexString.reserve(serialNumber->length * 3); | - | ||||||||||||
60 | for (int a = 0; a < serialNumber->length; ++a) { | - | ||||||||||||
61 | hexString += QByteArray::number(serialNumber->data[a], 16).rightJustified(2, '0'); | - | ||||||||||||
62 | hexString += ':'; | - | ||||||||||||
63 | } | - | ||||||||||||
64 | hexString.chop(1); | - | ||||||||||||
65 | d->serialNumberString = hexString; | - | ||||||||||||
66 | } | - | ||||||||||||
67 | return d->serialNumberString; | - | ||||||||||||
68 | } | - | ||||||||||||
69 | - | |||||||||||||
70 | QStringList QSslCertificate::issuerInfo(SubjectInfo info) const | - | ||||||||||||
71 | { | - | ||||||||||||
72 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
73 | - | |||||||||||||
74 | if (d->issuerInfo.isEmpty() && d->x509) | - | ||||||||||||
75 | d->issuerInfo = | - | ||||||||||||
76 | _q_mapFromX509Name(q_X509_get_issuer_name(d->x509)); | - | ||||||||||||
77 | - | |||||||||||||
78 | return d->issuerInfo.values(d->subjectInfoToString(info)); | - | ||||||||||||
79 | } | - | ||||||||||||
80 | - | |||||||||||||
81 | QStringList QSslCertificate::issuerInfo(const QByteArray &attribute) const | - | ||||||||||||
82 | { | - | ||||||||||||
83 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
84 | - | |||||||||||||
85 | if (d->issuerInfo.isEmpty() && d->x509) | - | ||||||||||||
86 | d->issuerInfo = | - | ||||||||||||
87 | _q_mapFromX509Name(q_X509_get_issuer_name(d->x509)); | - | ||||||||||||
88 | - | |||||||||||||
89 | return d->issuerInfo.values(attribute); | - | ||||||||||||
90 | } | - | ||||||||||||
91 | - | |||||||||||||
92 | QStringList QSslCertificate::subjectInfo(SubjectInfo info) const | - | ||||||||||||
93 | { | - | ||||||||||||
94 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
95 | - | |||||||||||||
96 | if (d->subjectInfo.isEmpty() && d->x509) | - | ||||||||||||
97 | d->subjectInfo = | - | ||||||||||||
98 | _q_mapFromX509Name(q_X509_get_subject_name(d->x509)); | - | ||||||||||||
99 | - | |||||||||||||
100 | return d->subjectInfo.values(d->subjectInfoToString(info)); | - | ||||||||||||
101 | } | - | ||||||||||||
102 | - | |||||||||||||
103 | QStringList QSslCertificate::subjectInfo(const QByteArray &attribute) const | - | ||||||||||||
104 | { | - | ||||||||||||
105 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
106 | - | |||||||||||||
107 | if (d->subjectInfo.isEmpty() && d->x509) | - | ||||||||||||
108 | d->subjectInfo = | - | ||||||||||||
109 | _q_mapFromX509Name(q_X509_get_subject_name(d->x509)); | - | ||||||||||||
110 | - | |||||||||||||
111 | return d->subjectInfo.values(attribute); | - | ||||||||||||
112 | } | - | ||||||||||||
113 | - | |||||||||||||
114 | QList<QByteArray> QSslCertificate::subjectInfoAttributes() const | - | ||||||||||||
115 | { | - | ||||||||||||
116 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
117 | - | |||||||||||||
118 | if (d->subjectInfo.isEmpty() && d->x509) | - | ||||||||||||
119 | d->subjectInfo = | - | ||||||||||||
120 | _q_mapFromX509Name(q_X509_get_subject_name(d->x509)); | - | ||||||||||||
121 | - | |||||||||||||
122 | return d->subjectInfo.uniqueKeys(); | - | ||||||||||||
123 | } | - | ||||||||||||
124 | - | |||||||||||||
125 | QList<QByteArray> QSslCertificate::issuerInfoAttributes() const | - | ||||||||||||
126 | { | - | ||||||||||||
127 | QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); | - | ||||||||||||
128 | - | |||||||||||||
129 | if (d->issuerInfo.isEmpty() && d->x509) | - | ||||||||||||
130 | d->issuerInfo = | - | ||||||||||||
131 | _q_mapFromX509Name(q_X509_get_issuer_name(d->x509)); | - | ||||||||||||
132 | - | |||||||||||||
133 | return d->issuerInfo.uniqueKeys(); | - | ||||||||||||
134 | } | - | ||||||||||||
135 | - | |||||||||||||
136 | QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlternativeNames() const | - | ||||||||||||
137 | { | - | ||||||||||||
138 | QMultiMap<QSsl::AlternativeNameEntryType, QString> result; | - | ||||||||||||
139 | - | |||||||||||||
140 | if (!d->x509) | - | ||||||||||||
141 | return result; | - | ||||||||||||
142 | - | |||||||||||||
143 | struct stack_st_GENERAL_NAME *altNames = (struct stack_st_GENERAL_NAME*)q_X509_get_ext_d2i(d->x509, 85, 0, 0); | - | ||||||||||||
144 | - | |||||||||||||
145 | if (altNames) { | - | ||||||||||||
146 | for (int i = 0; i < ((int (*)(const struct stack_st_GENERAL_NAME *))q_sk_num)((altNames)); ++i) { | - | ||||||||||||
147 | const GENERAL_NAME *genName = ((GENERAL_NAME * (*)(const struct stack_st_GENERAL_NAME *, int))q_sk_value)((altNames), (i)); | - | ||||||||||||
148 | if (genName->type != 2 && genName->type != 1) | - | ||||||||||||
149 | continue; | - | ||||||||||||
150 | - | |||||||||||||
151 | int len = q_ASN1_STRING_length(genName->d.ia5); | - | ||||||||||||
152 | if (len < 0 || len >= 8192) { | - | ||||||||||||
153 | - | |||||||||||||
154 | continue; | - | ||||||||||||
155 | } | - | ||||||||||||
156 | - | |||||||||||||
157 | const char *altNameStr = reinterpret_cast<const char *>(q_ASN1_STRING_data(genName->d.ia5)); | - | ||||||||||||
158 | const QString altName = QString::fromLatin1(altNameStr, len); | - | ||||||||||||
159 | if (genName->type == 2) | - | ||||||||||||
160 | result.insert(QSsl::DnsEntry, altName); | - | ||||||||||||
161 | else if (genName->type == 1) | - | ||||||||||||
162 | result.insert(QSsl::EmailEntry, altName); | - | ||||||||||||
163 | } | - | ||||||||||||
164 | q_sk_pop_free((STACK*)altNames, reinterpret_cast<void(*)(void*)>(q_sk_free)); | - | ||||||||||||
165 | } | - | ||||||||||||
166 | - | |||||||||||||
167 | return result; | - | ||||||||||||
168 | } | - | ||||||||||||
169 | - | |||||||||||||
170 | QDateTime QSslCertificate::effectiveDate() const | - | ||||||||||||
171 | { | - | ||||||||||||
172 | return d->notValidBefore; | - | ||||||||||||
173 | } | - | ||||||||||||
174 | - | |||||||||||||
175 | QDateTime QSslCertificate::expiryDate() const | - | ||||||||||||
176 | { | - | ||||||||||||
177 | return d->notValidAfter; | - | ||||||||||||
178 | } | - | ||||||||||||
179 | - | |||||||||||||
180 | Qt::HANDLE QSslCertificate::handle() const | - | ||||||||||||
181 | { | - | ||||||||||||
182 | return Qt::HANDLE(d->x509); | - | ||||||||||||
183 | } | - | ||||||||||||
184 | - | |||||||||||||
185 | QSslKey QSslCertificate::publicKey() const | - | ||||||||||||
186 | { | - | ||||||||||||
187 | if (!d->x509) | - | ||||||||||||
188 | return QSslKey(); | - | ||||||||||||
189 | - | |||||||||||||
190 | QSslKey key; | - | ||||||||||||
191 | - | |||||||||||||
192 | key.d->type = QSsl::PublicKey; | - | ||||||||||||
193 | X509_PUBKEY *xkey = d->x509->cert_info->key; | - | ||||||||||||
194 | EVP_PKEY *pkey = q_X509_PUBKEY_get(xkey); | - | ||||||||||||
195 | ((!(pkey)) ? qt_assert("pkey",__FILE__,234240) : qt_noop()); | - | ||||||||||||
196 | - | |||||||||||||
197 | if (q_EVP_PKEY_type(pkey->type) == 6) { | - | ||||||||||||
198 | key.d->rsa = q_EVP_PKEY_get1_RSA(pkey); | - | ||||||||||||
199 | key.d->algorithm = QSsl::Rsa; | - | ||||||||||||
200 | key.d->isNull = false; | - | ||||||||||||
201 | } else if (q_EVP_PKEY_type(pkey->type) == 116) { | - | ||||||||||||
202 | key.d->dsa = q_EVP_PKEY_get1_DSA(pkey); | - | ||||||||||||
203 | key.d->algorithm = QSsl::Dsa; | - | ||||||||||||
204 | key.d->isNull = false; | - | ||||||||||||
205 | - | |||||||||||||
206 | } else if (q_EVP_PKEY_type(pkey->type) == 408) { | - | ||||||||||||
207 | key.d->ec = q_EVP_PKEY_get1_EC_KEY(pkey); | - | ||||||||||||
208 | key.d->algorithm = QSsl::Ec; | - | ||||||||||||
209 | key.d->isNull = false; | - | ||||||||||||
210 | - | |||||||||||||
211 | } else if (q_EVP_PKEY_type(pkey->type) == 28) { | - | ||||||||||||
212 | - | |||||||||||||
213 | } else { | - | ||||||||||||
214 | - | |||||||||||||
215 | } | - | ||||||||||||
216 | - | |||||||||||||
217 | q_EVP_PKEY_free(pkey); | - | ||||||||||||
218 | return key; | - | ||||||||||||
219 | } | - | ||||||||||||
220 | - | |||||||||||||
221 | - | |||||||||||||
222 | - | |||||||||||||
223 | - | |||||||||||||
224 | static QVariant x509UnknownExtensionToValue(X509_EXTENSION *ext) | - | ||||||||||||
225 | { | - | ||||||||||||
226 | - | |||||||||||||
227 | - | |||||||||||||
228 | - | |||||||||||||
229 | - | |||||||||||||
230 | X509V3_EXT_METHOD *meth = const_cast<X509V3_EXT_METHOD *>(q_X509V3_EXT_get(ext)); | - | ||||||||||||
231 | if (!meth) { | - | ||||||||||||
232 | ASN1_OCTET_STRING *value = q_X509_EXTENSION_get_data(ext); | - | ||||||||||||
233 | QByteArray result( reinterpret_cast<const char *>(q_ASN1_STRING_data(value)), | - | ||||||||||||
234 | q_ASN1_STRING_length(value)); | - | ||||||||||||
235 | return result; | - | ||||||||||||
236 | } | - | ||||||||||||
237 | - | |||||||||||||
238 | - | |||||||||||||
239 | void *ext_internal = q_X509V3_EXT_d2i(ext); | - | ||||||||||||
240 | - | |||||||||||||
241 | - | |||||||||||||
242 | if (meth->i2v && ext_internal) { | - | ||||||||||||
243 | struct stack_st_CONF_VALUE *val = meth->i2v(meth, ext_internal, 0); | - | ||||||||||||
244 | - | |||||||||||||
245 | QVariantMap map; | - | ||||||||||||
246 | QVariantList list; | - | ||||||||||||
247 | bool isMap = false; | - | ||||||||||||
248 | - | |||||||||||||
249 | for (int j = 0; j < ((int (*)(const struct stack_st_CONF_VALUE *))q_sk_num)(val); j++) { | - | ||||||||||||
250 | CONF_VALUE *nval = ((CONF_VALUE * (*)(const struct stack_st_CONF_VALUE *, int))q_sk_value)(val, j); | - | ||||||||||||
251 | if (nval->name && nval->value) { | - | ||||||||||||
252 | isMap = true; | - | ||||||||||||
253 | map[QString::fromUtf8(nval->name)] = QString::fromUtf8(nval->value); | - | ||||||||||||
254 | } else if (nval->name) { | - | ||||||||||||
255 | list << QString::fromUtf8(nval->name); | - | ||||||||||||
256 | } else if (nval->value) { | - | ||||||||||||
257 | list << QString::fromUtf8(nval->value); | - | ||||||||||||
258 | } | - | ||||||||||||
259 | } | - | ||||||||||||
260 | - | |||||||||||||
261 | if (isMap) | - | ||||||||||||
262 | return map; | - | ||||||||||||
263 | else | - | ||||||||||||
264 | return list; | - | ||||||||||||
265 | } else if (meth->i2s && ext_internal) { | - | ||||||||||||
266 | - | |||||||||||||
267 | QVariant result(QString::fromUtf8(meth->i2s(meth, ext_internal))); | - | ||||||||||||
268 | return result; | - | ||||||||||||
269 | } else if (meth->i2r && ext_internal) { | - | ||||||||||||
270 | QByteArray result; | - | ||||||||||||
271 | - | |||||||||||||
272 | BIO *bio = q_BIO_new(q_BIO_s_mem()); | - | ||||||||||||
273 | if (!bio) | - | ||||||||||||
274 | return result; | - | ||||||||||||
275 | - | |||||||||||||
276 | meth->i2r(meth, ext_internal, bio, 0); | - | ||||||||||||
277 | - | |||||||||||||
278 | char *bio_buffer; | - | ||||||||||||
279 | long bio_size = (int)q_BIO_ctrl(bio,3,0,(char *)&bio_buffer); | - | ||||||||||||
280 | result = QByteArray(bio_buffer, bio_size); | - | ||||||||||||
281 | - | |||||||||||||
282 | q_BIO_free(bio); | - | ||||||||||||
283 | return result; | - | ||||||||||||
284 | } | - | ||||||||||||
285 | - | |||||||||||||
286 | return QVariant(); | - | ||||||||||||
287 | } | - | ||||||||||||
288 | - | |||||||||||||
289 | - | |||||||||||||
290 | - | |||||||||||||
291 | - | |||||||||||||
292 | - | |||||||||||||
293 | - | |||||||||||||
294 | static QVariant x509ExtensionToValue(X509_EXTENSION *ext) | - | ||||||||||||
295 | { | - | ||||||||||||
296 | ASN1_OBJECT *obj = q_X509_EXTENSION_get_object(ext); | - | ||||||||||||
297 | int nid = q_OBJ_obj2nid(obj); | - | ||||||||||||
298 | - | |||||||||||||
299 | switch (nid) { | - | ||||||||||||
300 | case 87: | - | ||||||||||||
301 | { | - | ||||||||||||
302 | BASIC_CONSTRAINTS *basic = reinterpret_cast<BASIC_CONSTRAINTS *>(q_X509V3_EXT_d2i(ext)); | - | ||||||||||||
303 | - | |||||||||||||
304 | QVariantMap result; | - | ||||||||||||
305 | result[QLatin1String("ca")] = basic->ca ? true : false; | - | ||||||||||||
306 | if (basic->pathlen) | - | ||||||||||||
307 | result[QLatin1String("pathLenConstraint")] = (qlonglong)q_ASN1_INTEGER_get(basic->pathlen); | - | ||||||||||||
308 | - | |||||||||||||
309 | q_BASIC_CONSTRAINTS_free(basic); | - | ||||||||||||
310 | return result; | - | ||||||||||||
311 | } | - | ||||||||||||
312 | break; dead code: break; | - | ||||||||||||
313 | case 177: | - | ||||||||||||
314 | { | - | ||||||||||||
315 | AUTHORITY_INFO_ACCESS *info = reinterpret_cast<AUTHORITY_INFO_ACCESS *>(q_X509V3_EXT_d2i(ext)); | - | ||||||||||||
316 | - | |||||||||||||
317 | QVariantMap result; | - | ||||||||||||
318 | for (int i=0; i < ((int (*)(const struct stack_st_ACCESS_DESCRIPTION *))q_sk_num)(info); i++) { | - | ||||||||||||
319 | ACCESS_DESCRIPTION *ad = ((ACCESS_DESCRIPTION * (*)(const struct stack_st_ACCESS_DESCRIPTION *, int))q_sk_value)(info, i); | - | ||||||||||||
320 | - | |||||||||||||
321 | GENERAL_NAME *name = ad->location; | - | ||||||||||||
322 | if (name->type == 6) { | - | ||||||||||||
323 | int len = q_ASN1_STRING_length(name->d.uniformResourceIdentifier); | - | ||||||||||||
324 | if (len < 0 || len >= 8192) { | - | ||||||||||||
325 | - | |||||||||||||
326 | continue; | - | ||||||||||||
327 | } | - | ||||||||||||
328 | - | |||||||||||||
329 | const char *uriStr = reinterpret_cast<const char *>(q_ASN1_STRING_data(name->d.uniformResourceIdentifier)); | - | ||||||||||||
330 | const QString uri = QString::fromUtf8(uriStr, len); | - | ||||||||||||
331 | - | |||||||||||||
332 | result[QString::fromUtf8(QSslCertificatePrivate::asn1ObjectName(ad->method))] = uri; | - | ||||||||||||
333 | } else { | - | ||||||||||||
334 | for (bool qt_category_enabled = lcSsl().isWarningEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 373379, __PRETTY_FUNCTION__, lcSsl().categoryName()).warning() << "Strange location type" << name->type; | - | ||||||||||||
335 | } | - | ||||||||||||
336 | } | - | ||||||||||||
337 | - | |||||||||||||
338 | - | |||||||||||||
339 | q_sk_pop_free((_STACK*)info, reinterpret_cast<void(*)(void*)>(q_sk_free)); | - | ||||||||||||
340 | - | |||||||||||||
341 | - | |||||||||||||
342 | - | |||||||||||||
343 | return result; | - | ||||||||||||
344 | } | - | ||||||||||||
345 | break; dead code: break; | - | ||||||||||||
346 | case 82: | - | ||||||||||||
347 | { | - | ||||||||||||
348 | void *ext_internal = q_X509V3_EXT_d2i(ext); | - | ||||||||||||
349 | - | |||||||||||||
350 | - | |||||||||||||
351 | - | |||||||||||||
352 | - | |||||||||||||
353 | X509V3_EXT_METHOD *meth = const_cast<X509V3_EXT_METHOD *>(q_X509V3_EXT_get(ext)); | - | ||||||||||||
354 | - | |||||||||||||
355 | return QVariant(QString::fromUtf8(meth->i2s(meth, ext_internal))); | - | ||||||||||||
356 | } | - | ||||||||||||
357 | break; dead code: break; | - | ||||||||||||
358 | case 90: | - | ||||||||||||
359 | { | - | ||||||||||||
360 | AUTHORITY_KEYID *auth_key = reinterpret_cast<AUTHORITY_KEYID *>(q_X509V3_EXT_d2i(ext)); | - | ||||||||||||
361 | - | |||||||||||||
362 | QVariantMap result; | - | ||||||||||||
363 | - | |||||||||||||
364 | - | |||||||||||||
365 | if (auth_key->keyid) { | - | ||||||||||||
366 | QByteArray keyid(reinterpret_cast<const char *>(auth_key->keyid->data), | - | ||||||||||||
367 | auth_key->keyid->length); | - | ||||||||||||
368 | result[QLatin1String("keyid")] = keyid.toHex(); | - | ||||||||||||
369 | } | - | ||||||||||||
370 | - | |||||||||||||
371 | - | |||||||||||||
372 | - | |||||||||||||
373 | - | |||||||||||||
374 | - | |||||||||||||
375 | if (auth_key->serial) | - | ||||||||||||
376 | result[QLatin1String("serial")] = (qlonglong)q_ASN1_INTEGER_get(auth_key->serial); | - | ||||||||||||
377 | - | |||||||||||||
378 | q_AUTHORITY_KEYID_free(auth_key); | - | ||||||||||||
379 | return result; | - | ||||||||||||
380 | } | - | ||||||||||||
381 | break; dead code: break; | - | ||||||||||||
382 | } | - | ||||||||||||
383 | - | |||||||||||||
384 | return QVariant(); | - | ||||||||||||
385 | } | - | ||||||||||||
386 | - | |||||||||||||
387 | QSslCertificateExtension QSslCertificatePrivate::convertExtension(X509_EXTENSION *ext) | - | ||||||||||||
388 | { | - | ||||||||||||
389 | QSslCertificateExtension result; | - | ||||||||||||
390 | - | |||||||||||||
391 | ASN1_OBJECT *obj = q_X509_EXTENSION_get_object(ext); | - | ||||||||||||
392 | QByteArray oid = QSslCertificatePrivate::asn1ObjectId(obj); | - | ||||||||||||
393 | QByteArray name = QSslCertificatePrivate::asn1ObjectName(obj); | - | ||||||||||||
394 | - | |||||||||||||
395 | result.d->oid = QString::fromUtf8(oid); | - | ||||||||||||
396 | result.d->name = QString::fromUtf8(name); | - | ||||||||||||
397 | - | |||||||||||||
398 | bool critical = q_X509_EXTENSION_get_critical(ext); | - | ||||||||||||
399 | result.d->critical = critical; | - | ||||||||||||
400 | - | |||||||||||||
401 | - | |||||||||||||
402 | QVariant extensionValue = x509ExtensionToValue(ext); | - | ||||||||||||
403 | if (extensionValue.isValid()) { | - | ||||||||||||
404 | result.d->value = extensionValue; | - | ||||||||||||
405 | result.d->supported = true; | - | ||||||||||||
406 | - | |||||||||||||
407 | return result; | - | ||||||||||||
408 | } | - | ||||||||||||
409 | - | |||||||||||||
410 | extensionValue = x509UnknownExtensionToValue(ext); | - | ||||||||||||
411 | if (extensionValue.isValid()) { | - | ||||||||||||
412 | result.d->value = extensionValue; | - | ||||||||||||
413 | result.d->supported = false; | - | ||||||||||||
414 | return result; | - | ||||||||||||
415 | } | - | ||||||||||||
416 | - | |||||||||||||
417 | return result; | - | ||||||||||||
418 | } | - | ||||||||||||
419 | - | |||||||||||||
420 | QList<QSslCertificateExtension> QSslCertificate::extensions() const | - | ||||||||||||
421 | { | - | ||||||||||||
422 | QList<QSslCertificateExtension> result; | - | ||||||||||||
423 | - | |||||||||||||
424 | if (!d->x509) | - | ||||||||||||
425 | return result; | - | ||||||||||||
426 | - | |||||||||||||
427 | int count = q_X509_get_ext_count(d->x509); | - | ||||||||||||
428 | result.reserve(count); | - | ||||||||||||
429 | - | |||||||||||||
430 | for (int i = 0; i < count; i++) { | - | ||||||||||||
431 | X509_EXTENSION *ext = q_X509_get_ext(d->x509, i); | - | ||||||||||||
432 | result << QSslCertificatePrivate::convertExtension(ext); | - | ||||||||||||
433 | } | - | ||||||||||||
434 | - | |||||||||||||
435 | return result; | - | ||||||||||||
436 | } | - | ||||||||||||
437 | - | |||||||||||||
438 | QByteArray QSslCertificate::toPem() const | - | ||||||||||||
439 | { | - | ||||||||||||
440 | if (!d->x509) | - | ||||||||||||
441 | return QByteArray(); | - | ||||||||||||
442 | return d->QByteArray_from_X509(d->x509, QSsl::Pem); | - | ||||||||||||
443 | } | - | ||||||||||||
444 | - | |||||||||||||
445 | QByteArray QSslCertificate::toDer() const | - | ||||||||||||
446 | { | - | ||||||||||||
447 | if (!d->x509) | - | ||||||||||||
448 | return QByteArray(); | - | ||||||||||||
449 | return d->QByteArray_from_X509(d->x509, QSsl::Der); | - | ||||||||||||
450 | } | - | ||||||||||||
451 | - | |||||||||||||
452 | QString QSslCertificate::toText() const | - | ||||||||||||
453 | { | - | ||||||||||||
454 | if (!d->x509) | - | ||||||||||||
455 | return QString(); | - | ||||||||||||
456 | return d->text_from_X509(d->x509); | - | ||||||||||||
457 | } | - | ||||||||||||
458 | - | |||||||||||||
459 | - | |||||||||||||
460 | - | |||||||||||||
461 | - | |||||||||||||
462 | void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat format) | - | ||||||||||||
463 | { | - | ||||||||||||
464 | if (!data.isEmpty()
| 73-30192 | ||||||||||||
465 | const QList<QSslCertificate> certs = (
| 13-60 | ||||||||||||
466 | ? certificatesFromPem(data, 1) | - | ||||||||||||
467 | : certificatesFromDer(data, 1); | - | ||||||||||||
468 | if (!certs.isEmpty()
| 3-70 | ||||||||||||
469 | *this = *certs.first().d; | - | ||||||||||||
470 | if (x509
| 0-70 | ||||||||||||
471 | x509 = q_X509_dup(x509); executed 70 times by 3 tests: x509 = q_X509_dup(x509); Executed by:
| 70 | ||||||||||||
472 | } executed 70 times by 3 tests: end of block Executed by:
| 70 | ||||||||||||
473 | } executed 73 times by 3 tests: end of block Executed by:
| 73 | ||||||||||||
474 | } executed 30265 times by 16 tests: end of block Executed by:
| 30265 | ||||||||||||
475 | - | |||||||||||||
476 | - | |||||||||||||
477 | QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format) | - | ||||||||||||
478 | { | - | ||||||||||||
479 | if (!x509) { | - | ||||||||||||
480 | for (bool qt_category_enabled = lcSsl().isWarningEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 519525, __PRETTY_FUNCTION__, lcSsl().categoryName()).warning("QSslSocketBackendPrivate::X509_to_QByteArray: null X509"); | - | ||||||||||||
481 | return QByteArray(); | - | ||||||||||||
482 | } | - | ||||||||||||
483 | - | |||||||||||||
484 | - | |||||||||||||
485 | int length = q_i2d_X509(x509, 0); | - | ||||||||||||
486 | QByteArray array; | - | ||||||||||||
487 | array.resize(length); | - | ||||||||||||
488 | char *data = array.data(); | - | ||||||||||||
489 | char **dataP = &data; | - | ||||||||||||
490 | unsigned char **dataPu = (unsigned char **)dataP; | - | ||||||||||||
491 | if (q_i2d_X509(x509, dataPu) < 0) | - | ||||||||||||
492 | return QByteArray(); | - | ||||||||||||
493 | - | |||||||||||||
494 | if (format == QSsl::Der) | - | ||||||||||||
495 | return array; | - | ||||||||||||
496 | - | |||||||||||||
497 | - | |||||||||||||
498 | array = array.toBase64(); | - | ||||||||||||
499 | QByteArray tmp; | - | ||||||||||||
500 | for (int i = 0; i <= array.size() - 64; i += 64) { | - | ||||||||||||
501 | tmp += QByteArray::fromRawData(array.data() + i, 64); | - | ||||||||||||
502 | tmp += '\n'; | - | ||||||||||||
503 | } | - | ||||||||||||
504 | if (int remainder = array.size() % 64) { | - | ||||||||||||
505 | tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder); | - | ||||||||||||
506 | tmp += '\n'; | - | ||||||||||||
507 | } | - | ||||||||||||
508 | - | |||||||||||||
509 | return "-----BEGIN CERTIFICATE-----" "\n" + tmp + "-----END CERTIFICATE-----" "\n"; | - | ||||||||||||
510 | } | - | ||||||||||||
511 | - | |||||||||||||
512 | QString QSslCertificatePrivate::text_from_X509(X509 *x509) | - | ||||||||||||
513 | { | - | ||||||||||||
514 | if (!x509) { | - | ||||||||||||
515 | for (bool qt_category_enabled = lcSsl().isWarningEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 554560, __PRETTY_FUNCTION__, lcSsl().categoryName()).warning("QSslSocketBackendPrivate::text_from_X509: null X509"); | - | ||||||||||||
516 | return QString(); | - | ||||||||||||
517 | } | - | ||||||||||||
518 | - | |||||||||||||
519 | QByteArray result; | - | ||||||||||||
520 | BIO *bio = q_BIO_new(q_BIO_s_mem()); | - | ||||||||||||
521 | if (!bio) | - | ||||||||||||
522 | return QString(); | - | ||||||||||||
523 | - | |||||||||||||
524 | q_X509_print(bio, x509); | - | ||||||||||||
525 | - | |||||||||||||
526 | QVarLengthArray<char, 16384> data; | - | ||||||||||||
527 | int count = q_BIO_read(bio, data.data(), 16384); | - | ||||||||||||
528 | if ( count > 0 ) { | - | ||||||||||||
529 | result = QByteArray( data.data(), count ); | - | ||||||||||||
530 | } | - | ||||||||||||
531 | - | |||||||||||||
532 | q_BIO_free(bio); | - | ||||||||||||
533 | - | |||||||||||||
534 | return QString::fromLatin1(result); | - | ||||||||||||
535 | } | - | ||||||||||||
536 | - | |||||||||||||
537 | QByteArray QSslCertificatePrivate::asn1ObjectId(ASN1_OBJECT *object) | - | ||||||||||||
538 | { | - | ||||||||||||
539 | char buf[80]; | - | ||||||||||||
540 | q_OBJ_obj2txt(buf, sizeof(buf), object, 1); | - | ||||||||||||
541 | - | |||||||||||||
542 | return QByteArray(buf); | - | ||||||||||||
543 | } | - | ||||||||||||
544 | - | |||||||||||||
545 | - | |||||||||||||
546 | QByteArray QSslCertificatePrivate::asn1ObjectName(ASN1_OBJECT *object) | - | ||||||||||||
547 | { | - | ||||||||||||
548 | int nid = q_OBJ_obj2nid(object); | - | ||||||||||||
549 | if (nid != 0) | - | ||||||||||||
550 | return QByteArray(q_OBJ_nid2sn(nid)); | - | ||||||||||||
551 | - | |||||||||||||
552 | return asn1ObjectId(object); | - | ||||||||||||
553 | } | - | ||||||||||||
554 | - | |||||||||||||
555 | static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name) | - | ||||||||||||
556 | { | - | ||||||||||||
557 | QMap<QByteArray, QString> info; | - | ||||||||||||
558 | for (int i = 0; i < q_X509_NAME_entry_count(name); ++i) { | - | ||||||||||||
559 | X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i); | - | ||||||||||||
560 | - | |||||||||||||
561 | QByteArray name = QSslCertificatePrivate::asn1ObjectName(q_X509_NAME_ENTRY_get_object(e)); | - | ||||||||||||
562 | unsigned char *data = 0; | - | ||||||||||||
563 | int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e)); | - | ||||||||||||
564 | info.insertMulti(name, QString::fromUtf8((char*)data, size)); | - | ||||||||||||
565 | q_CRYPTO_free(data); | - | ||||||||||||
566 | } | - | ||||||||||||
567 | - | |||||||||||||
568 | return info; | - | ||||||||||||
569 | } | - | ||||||||||||
570 | - | |||||||||||||
571 | QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509) | - | ||||||||||||
572 | { | - | ||||||||||||
573 | QSslCertificate certificate; | - | ||||||||||||
574 | if (!x509 || !QSslSocket::supportsSsl()) | - | ||||||||||||
575 | return certificate; | - | ||||||||||||
576 | - | |||||||||||||
577 | ASN1_TIME *nbef = ((x509)->cert_info->validity->notBefore); | - | ||||||||||||
578 | ASN1_TIME *naft = ((x509)->cert_info->validity->notAfter); | - | ||||||||||||
579 | certificate.d->notValidBefore = q_getTimeFromASN1(nbef); | - | ||||||||||||
580 | certificate.d->notValidAfter = q_getTimeFromASN1(naft); | - | ||||||||||||
581 | certificate.d->null = false; | - | ||||||||||||
582 | certificate.d->x509 = q_X509_dup(x509); | - | ||||||||||||
583 | - | |||||||||||||
584 | return certificate; | - | ||||||||||||
585 | } | - | ||||||||||||
586 | - | |||||||||||||
587 | static bool matchLineFeed(const QByteArray &pem, int *offset) | - | ||||||||||||
588 | { | - | ||||||||||||
589 | char ch = 0; | - | ||||||||||||
590 | - | |||||||||||||
591 | - | |||||||||||||
592 | while (*offset < pem.size() && (ch = pem.at(*offset)) == ' ') | - | ||||||||||||
593 | ++*offset; | - | ||||||||||||
594 | - | |||||||||||||
595 | if (ch == '\n') { | - | ||||||||||||
596 | *offset += 1; | - | ||||||||||||
597 | return true; | - | ||||||||||||
598 | } | - | ||||||||||||
599 | if (ch == '\r' && pem.size() > (*offset + 1) && pem.at(*offset + 1) == '\n') { | - | ||||||||||||
600 | *offset += 2; | - | ||||||||||||
601 | return true; | - | ||||||||||||
602 | } | - | ||||||||||||
603 | return false; | - | ||||||||||||
604 | } | - | ||||||||||||
605 | - | |||||||||||||
606 | QList<QSslCertificate> QSslCertificatePrivate::certificatesFromPem(const QByteArray &pem, int count) | - | ||||||||||||
607 | { | - | ||||||||||||
608 | QList<QSslCertificate> certificates; | - | ||||||||||||
609 | QSslSocketPrivate::ensureInitialized(); | - | ||||||||||||
610 | - | |||||||||||||
611 | int offset = 0; | - | ||||||||||||
612 | while (count == -1 || certificates.size() < count) { | - | ||||||||||||
613 | int startPos = pem.indexOf("-----BEGIN CERTIFICATE-----", offset); | - | ||||||||||||
614 | if (startPos == -1) | - | ||||||||||||
615 | break; | - | ||||||||||||
616 | startPos += sizeof("-----BEGIN CERTIFICATE-----") - 1; | - | ||||||||||||
617 | if (!matchLineFeed(pem, &startPos)) | - | ||||||||||||
618 | break; | - | ||||||||||||
619 | - | |||||||||||||
620 | int endPos = pem.indexOf("-----END CERTIFICATE-----", startPos); | - | ||||||||||||
621 | if (endPos == -1) | - | ||||||||||||
622 | break; | - | ||||||||||||
623 | - | |||||||||||||
624 | offset = endPos + sizeof("-----END CERTIFICATE-----") - 1; | - | ||||||||||||
625 | if (offset < pem.size() && !matchLineFeed(pem, &offset)) | - | ||||||||||||
626 | break; | - | ||||||||||||
627 | - | |||||||||||||
628 | QByteArray decoded = QByteArray::fromBase64( | - | ||||||||||||
629 | QByteArray::fromRawData(pem.data() + startPos, endPos - startPos)); | - | ||||||||||||
630 | const unsigned char *data = (const unsigned char *)decoded.data(); | - | ||||||||||||
631 | - | |||||||||||||
632 | if (X509 *x509 = q_d2i_X509(0, &data, decoded.size())) { | - | ||||||||||||
633 | certificates << QSslCertificate_from_X509(x509); | - | ||||||||||||
634 | q_X509_free(x509); | - | ||||||||||||
635 | } | - | ||||||||||||
636 | } | - | ||||||||||||
637 | - | |||||||||||||
638 | return certificates; | - | ||||||||||||
639 | } | - | ||||||||||||
640 | - | |||||||||||||
641 | QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteArray &der, int count) | - | ||||||||||||
642 | { | - | ||||||||||||
643 | QList<QSslCertificate> certificates; | - | ||||||||||||
644 | QSslSocketPrivate::ensureInitialized(); | - | ||||||||||||
645 | - | |||||||||||||
646 | const unsigned char *data = (const unsigned char *)der.data(); | - | ||||||||||||
647 | int size = der.size(); | - | ||||||||||||
648 | - | |||||||||||||
649 | while (size > 0 && (count == -1 || certificates.size() < count)) { | - | ||||||||||||
650 | if (X509 *x509 = q_d2i_X509(0, &data, size)) { | - | ||||||||||||
651 | certificates << QSslCertificate_from_X509(x509); | - | ||||||||||||
652 | q_X509_free(x509); | - | ||||||||||||
653 | } else { | - | ||||||||||||
654 | break; | - | ||||||||||||
655 | } | - | ||||||||||||
656 | size -= ((const char *)data - der.data()); | - | ||||||||||||
657 | } | - | ||||||||||||
658 | - | |||||||||||||
659 | return certificates; | - | ||||||||||||
660 | } | - | ||||||||||||
661 | - | |||||||||||||
662 | - | |||||||||||||
Switch to Source code | Preprocessed file |