📄 qsslcertificate.cpp
字号:
q_ASN1_STRING_length(genName->d.ia5))); if (genName->type == GEN_DNS) result.insert(QSsl::DnsEntry, altName); else if (genName->type == GEN_EMAIL) result.insert(QSsl::EmailEntry, altName); } q_sk_free(altNames); } return result;}/*! Returns the date-time that the certificate becomes valid, or an empty QDateTime if this is a null certificate. \sa expiryDate()*/QDateTime QSslCertificate::effectiveDate() const{ return d->notValidBefore;}/*! Returns the date-time that the certificate expires, or an empty QDateTime if this is a null certificate. \sa effectiveDate()*/QDateTime QSslCertificate::expiryDate() const{ return d->notValidAfter;}/*! Returns a pointer to the native certificate handle, if there is one, or a null pointer otherwise. You can use this handle, together with the native API, to access extended information about the certificate. \warning Use of this function has a high probability of being non-portable, and its return value may vary from platform to platform or change from minor release to minor release.*/Qt::HANDLE QSslCertificate::handle() const{ return Qt::HANDLE(d->x509);}/*! Returns the certificate subject's public key.*/QSslKey QSslCertificate::publicKey() const{ if (!d->x509) return QSslKey(); QSslKey key; key.d->type = QSsl::PublicKey; X509_PUBKEY *xkey = d->x509->cert_info->key; EVP_PKEY *pkey = q_X509_PUBKEY_get(xkey); Q_ASSERT(pkey); if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) { key.d->rsa = q_EVP_PKEY_get1_RSA(pkey); key.d->algorithm = QSsl::Rsa; key.d->isNull = false; } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) { key.d->dsa = q_EVP_PKEY_get1_DSA(pkey); key.d->algorithm = QSsl::Dsa; key.d->isNull = false; } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DH) { // DH unsupported } else { // error? } q_EVP_PKEY_free(pkey); return key;}/*! Returns this certificate converted to a PEM (Base64) encoded representation.*/QByteArray QSslCertificate::toPem() const{ if (!d->x509) return QByteArray(); return d->QByteArray_from_X509(d->x509, QSsl::Pem);}/*! Returns this certificate converted to a DER (binary) encoded representation.*/QByteArray QSslCertificate::toDer() const{ if (!d->x509) return QByteArray(); return d->QByteArray_from_X509(d->x509, QSsl::Der);}/*! Searches all files in the \a path for certificates encoded in the specified \a format and returns them in a list. \a path can be for an explicit file, or it can contain wildcards in the format specified by \a syntax. \sa fromData()*/QList<QSslCertificate> QSslCertificate::fromPath(const QString &path, QSsl::EncodingFormat format, QRegExp::PatternSyntax syntax){ if (syntax == QRegExp::FixedString) { QFile file(path); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) return QSslCertificate::fromData(file.readAll(),format); return QList<QSslCertificate>(); } QList<QSslCertificate> certs; QRegExp pattern(path, Qt::CaseSensitive, syntax); QDirIterator it(path); while (it.hasNext()) { if (!pattern.exactMatch(path)) continue; QFile file(it.filePath()); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) certs += QSslCertificate::fromData(file.readAll(),format); } return certs;}/*! Searches for and parses all certificates in \a device that are encoded in the specified \a format and returns them in a list of certificates. \sa fromData()*/QList<QSslCertificate> QSslCertificate::fromDevice(QIODevice *device, QSsl::EncodingFormat format){ if (!device) { qWarning("QSslCertificate::fromDevice: cannot read from a null device"); return QList<QSslCertificate>(); } return fromData(device->readAll(), format);}/*! Searches for and parses all certificates in \a data that are encoded in the specified \a format and returns them in a list of certificates. \sa fromDevice()*/QList<QSslCertificate> QSslCertificate::fromData(const QByteArray &data, QSsl::EncodingFormat format){ return (format == QSsl::Pem) ? QSslCertificatePrivate::certificatesFromPem(data) : QSslCertificatePrivate::certificatesFromDer(data);}void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat format){ if (!data.isEmpty()) { QList<QSslCertificate> certs = (format == QSsl::Pem) ? certificatesFromPem(data, 1) : certificatesFromDer(data, 1); if (!certs.isEmpty()) { *this = *certs.first().d; if (x509) x509 = q_X509_dup(x509); } }}static const char BeginCertString[] = "-----BEGIN CERTIFICATE-----\n";static const char EndCertString[] = "-----END CERTIFICATE-----\n";// ### refactor against QSsl::pemFromDer() etc. (to avoid redundant implementations)QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format){ if (!x509) { qWarning("QSslSocketBackendPrivate::X509_to_QByteArray: null X509"); return QByteArray(); } // Use i2d_X509 to convert the X509 to an array. int length = q_i2d_X509(x509, 0); QByteArray array; array.resize(length); char *data = array.data(); char **dataP = &data; unsigned char **dataPu = (unsigned char **)dataP; if (q_i2d_X509(x509, dataPu) < 0) return QByteArray(); if (format == QSsl::Der) return array; // Convert to Base64 - wrap at 64 characters. array = array.toBase64(); QByteArray tmp; for (int i = 0; i < array.size() - 64; i += 64) { tmp += QByteArray::fromRawData(array.data() + i, 64); tmp += "\n"; } if (int remainder = array.size() % 64) { tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder); tmp += "\n"; } return BeginCertString + tmp + EndCertString;}static QMap<QString, QString> _q_mapFromOnelineName(char *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(); } return info;}QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509){ QSslCertificate certificate; if (!x509 || !QSslSocket::supportsSsl()) return certificate; certificate.d->issuerInfo = _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(x509), 0, 0)); certificate.d->subjectInfo = _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(x509), 0, 0)); ASN1_TIME *nbef = q_X509_get_notBefore(x509); ASN1_TIME *naft = q_X509_get_notAfter(x509); certificate.d->notValidBefore.setTime_t(q_getTimeFromASN1(nbef)); certificate.d->notValidAfter.setTime_t(q_getTimeFromASN1(naft)); certificate.d->null = false; certificate.d->x509 = q_X509_dup(x509); return certificate;}QList<QSslCertificate> QSslCertificatePrivate::certificatesFromPem(const QByteArray &pem, int count){ QList<QSslCertificate> certificates; QSslSocketPrivate::ensureInitialized(); int offset = 0; while (count == -1 || certificates.size() < count) { int startPos = pem.indexOf(BeginCertString, offset); if (startPos == -1) break; startPos += sizeof(BeginCertString) - 1; int endPos = pem.indexOf(EndCertString, startPos); if (endPos == -1) break; offset = endPos + sizeof(EndCertString) - 1; QByteArray decoded = QByteArray::fromBase64( QByteArray::fromRawData(pem.data() + startPos, endPos - startPos));#if OPENSSL_VERSION_NUMBER >= 0x00908000L const unsigned char *data = (const unsigned char *)decoded.data();#else unsigned char *data = (unsigned char *)decoded.data();#endif if (X509 *x509 = q_d2i_X509(0, &data, decoded.size())) { certificates << QSslCertificate_from_X509(x509); q_X509_free(x509); } } return certificates;}QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteArray &der, int count){ QList<QSslCertificate> certificates; QSslSocketPrivate::ensureInitialized();#if OPENSSL_VERSION_NUMBER >= 0x00908000L const unsigned char *data = (const unsigned char *)der.data();#else unsigned char *data = (unsigned char *)der.data();#endif int size = der.size(); while (count == -1 || certificates.size() < count) { if (X509 *x509 = q_d2i_X509(0, &data, size)) { certificates << QSslCertificate_from_X509(x509); q_X509_free(x509); } else { break; } size -= ((char *)data - der.data()); } return certificates;}#ifndef QT_NO_DEBUG_STREAMQDebug operator<<(QDebug debug, const QSslCertificate &certificate){ debug << "QSslCertificate(" << certificate.version() << "," << certificate.serialNumber() << "," << certificate.digest() << "," << certificate.issuerInfo(QSslCertificate::Organization) << "," << certificate.subjectInfo(QSslCertificate::Organization) << "," << certificate.alternateSubjectNames()#ifndef QT_NO_TEXTSTREAM << "," << certificate.effectiveDate() << "," << certificate.expiryDate()#endif << ")"; return debug;}QDebug operator<<(QDebug debug, QSslCertificate::SubjectInfo info){ switch (info) { case QSslCertificate::Organization: debug << "Organization"; break; case QSslCertificate::CommonName: debug << "CommonName"; break; case QSslCertificate::CountryName: debug << "CountryName"; break; case QSslCertificate::LocalityName: debug << "LocalityName"; break; case QSslCertificate::OrganizationalUnitName: debug << "OrganizationalUnitName"; break; case QSslCertificate::StateOrProvinceName: debug << "StateOrProvinceName"; break; } return debug;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -