145QSslCertificate::QSslCertificate(QIODevice *device, QSsl::EncodingFormat format)
146 : d(
new QSslCertificatePrivate)
149 const auto data = device->readAll();
153 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
157 auto *X509Reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
159 qCWarning(lcSsl,
"Current TLS plugin does not support reading from PEM/DER");
163 QList<QSslCertificate> certs = X509Reader(data, 1);
164 if (!certs.isEmpty())
175QSslCertificate::QSslCertificate(
const QByteArray &data, QSsl::EncodingFormat format)
176 : d(
new QSslCertificatePrivate)
181 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
185 auto *X509Reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
187 qCWarning(lcSsl,
"Current TLS plugin does not support reading from PEM/DER");
191 const QList<QSslCertificate> certs = X509Reader(data, 1);
192 if (!certs.isEmpty())
629QList<QSslCertificate> QSslCertificate::fromPath(
const QString &path,
630 QSsl::EncodingFormat format,
631 PatternSyntax syntax)
636 QString sourcePath = QDir::fromNativeSeparators(path);
639 QStringView pathPrefix = QStringView(sourcePath).left(sourcePath.lastIndexOf(u'/'));
644#if QT_CONFIG(regularexpression)
645 if (syntax == PatternSyntax::Wildcard)
646 pos = pathPrefix.indexOf(QRegularExpression(
"[*?[]"_L1));
647 else if (syntax == PatternSyntax::RegularExpression)
648 pos = sourcePath.indexOf(QRegularExpression(
"[\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\}\\|]"_L1));
650 if (syntax == PatternSyntax::Wildcard || syntax == PatternSyntax::RegExp)
651 qWarning(
"Regular expression support is disabled in this build. Only fixed string can be searched");
652 return QList<QSslCertificate>();
657 pathPrefix = pathPrefix.left(pos);
658 const qsizetype lastIndexOfSlash = pathPrefix.lastIndexOf(u'/');
659 if (lastIndexOfSlash != -1)
660 pathPrefix = pathPrefix.left(lastIndexOfSlash);
665 if (QFileInfo(sourcePath).isFile()) {
666 QFile file(sourcePath);
667 QIODevice::OpenMode openMode = QIODevice::ReadOnly;
668 if (format == QSsl::Pem)
669 openMode |= QIODevice::Text;
670 if (file.open(openMode))
671 return QSslCertificate::fromData(file.readAll(), format);
672 return QList<QSslCertificate>();
678 if (pathPrefix.isEmpty()) {
683 const QString pathPrefixString = pathPrefix.toString();
686 QList<QSslCertificate> certs;
688#if QT_CONFIG(regularexpression)
689 if (syntax == PatternSyntax::Wildcard)
690 sourcePath = QRegularExpression::wildcardToRegularExpression(sourcePath, QRegularExpression::UnanchoredWildcardConversion);
692 QRegularExpression pattern(QRegularExpression::anchoredPattern(sourcePath));
695 using F = QDirListing::IteratorFlag;
696 constexpr auto iterFlags = F::FollowDirSymlinks | F::Recursive | F::FilesOnly;
697 for (
const auto &dirEntry : QDirListing(pathPrefixString, iterFlags)) {
698 QString filePath = dirEntry.filePath();
700 filePath.remove(0, startIndex);
702#if QT_CONFIG(regularexpression)
703 if (!pattern.match(filePath).hasMatch())
706 if (sourcePath != filePath)
710 QFile file(filePath);
711 QIODevice::OpenMode openMode = QIODevice::ReadOnly;
712 if (format == QSsl::Pem)
713 openMode |= QIODevice::Text;
714 if (file.open(openMode))
715 certs += QSslCertificate::fromData(file.readAll(), format);
743QList<QSslCertificate> QSslCertificate::fromData(
const QByteArray &data, QSsl::EncodingFormat format)
745 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
747 qCWarning(lcSsl,
"No TLS backend is available");
751 auto reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
753 qCWarning(lcSsl,
"The available TLS backend does not support reading PEM/DER");
757 return reader(data, -1);
775QList<QSslError> QSslCertificate::verify(
const QList<QSslCertificate> &certificateChain,
const QString &hostName)
777 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
779 qCWarning(lcSsl,
"No TLS backend is available");
782 auto verifyPtr = tlsBackend->X509Verifier();
784 qCWarning(lcSsl,
"Available TLS backend does not support manual certificate verification");
787 return verifyPtr(certificateChain, hostName);
802bool QSslCertificate::importPkcs12(QIODevice *device,
803 QSslKey *key, QSslCertificate *certificate,
804 QList<QSslCertificate> *caCertificates,
805 const QByteArray &passPhrase)
807 if (!device || !key || !certificate)
810 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
812 qCWarning(lcSsl,
"No TLS backend is available");
816 if (
auto reader = tlsBackend->X509Pkcs12Reader())
817 return reader(device, key, certificate, caCertificates, passPhrase);
819 qCWarning(lcSsl,
"Available TLS backend does not support PKCS12");
827 QList<QSslCertificateExtension> result;
830 auto nExt = backend->numberOfExtensions();
831 for (
decltype (nExt) i = 0; i < nExt; ++i) {
832 QSslCertificateExtension ext;
833 ext.d->oid = backend->oidForExtension(i);
834 ext.d->name = backend->nameForExtension(i);
835 ext.d->value = backend->valueForExtension(i);
836 ext.d->critical = backend->isExtensionCritical(i);
837 ext.d->supported = backend->isExtensionSupported(i);
899 if (certificate.serialNumber() == certificate_blacklist[a++] &&
900 (certificate.subjectInfo(QSslCertificate::CommonName).contains(blacklistedCommonName) ||
901 certificate.issuerInfo(QSslCertificate::CommonName).contains(blacklistedCommonName)))
910 case QSslCertificate::Organization:
return "O"_ba;
911 case QSslCertificate::CommonName:
return "CN"_ba;
912 case QSslCertificate::LocalityName:
return"L"_ba;
913 case QSslCertificate::OrganizationalUnitName:
return "OU"_ba;
914 case QSslCertificate::CountryName:
return "C"_ba;
915 case QSslCertificate::StateOrProvinceName:
return "ST"_ba;
916 case QSslCertificate::DistinguishedNameQualifier:
return "dnQualifier"_ba;
917 case QSslCertificate::SerialNumber:
return "serialNumber"_ba;
918 case QSslCertificate::EmailAddress:
return "emailAddress"_ba;
988QDebug operator<<(QDebug debug,
const QSslCertificate &certificate)
990 QDebugStateSaver saver(debug);
991 debug.resetFormat().nospace();
992 debug <<
"QSslCertificate("
993 <<
"Version=" << certificate.version()
994 <<
", SerialNumber=" << certificate.serialNumber()
995 <<
", Digest=" << certificate.digest().toBase64()
996 <<
", Issuer=" << certificate.issuerDisplayName()
997 <<
", Subject=" << certificate.subjectDisplayName()
998 <<
", AlternativeSubjectNames=" << certificate.subjectAlternativeNames()
999#if QT_CONFIG(datestring)
1000 <<
", EffectiveDate=" << certificate.effectiveDate()
1001 <<
", ExpiryDate=" << certificate.expiryDate()
1006QDebug operator<<(QDebug debug, QSslCertificate::SubjectInfo info)
1009 case QSslCertificate::Organization: debug <<
"Organization";
break;
1010 case QSslCertificate::CommonName: debug <<
"CommonName";
break;
1011 case QSslCertificate::CountryName: debug <<
"CountryName";
break;
1012 case QSslCertificate::LocalityName: debug <<
"LocalityName";
break;
1013 case QSslCertificate::OrganizationalUnitName: debug <<
"OrganizationalUnitName";
break;
1014 case QSslCertificate::StateOrProvinceName: debug <<
"StateOrProvinceName";
break;
1015 case QSslCertificate::DistinguishedNameQualifier: debug <<
"DistinguishedNameQualifier";
break;
1016 case QSslCertificate::SerialNumber: debug <<
"SerialNumber";
break;
1017 case QSslCertificate::EmailAddress: debug <<
"EmailAddress";
break;