146QSslCertificate::QSslCertificate(QIODevice *device, QSsl::EncodingFormat format)
147 : d(
new QSslCertificatePrivate)
150 const auto data = device->readAll();
154 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
158 auto *X509Reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
160 qCWarning(lcSsl,
"Current TLS plugin does not support reading from PEM/DER");
164 QList<QSslCertificate> certs = X509Reader(data, 1);
165 if (!certs.isEmpty())
176QSslCertificate::QSslCertificate(
const QByteArray &data, QSsl::EncodingFormat format)
177 : d(
new QSslCertificatePrivate)
182 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
186 auto *X509Reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
188 qCWarning(lcSsl,
"Current TLS plugin does not support reading from PEM/DER");
192 const QList<QSslCertificate> certs = X509Reader(data, 1);
193 if (!certs.isEmpty())
630QList<QSslCertificate> QSslCertificate::fromPath(
const QString &path,
631 QSsl::EncodingFormat format,
632 PatternSyntax syntax)
637 if (syntax == PatternSyntax::FixedString && QFileInfo(path).isFile())
638 return fromFile(path, format);
643 QString sourcePath = QDir::fromNativeSeparators(path);
646 QStringView pathPrefix = QStringView(sourcePath).left(sourcePath.lastIndexOf(u'/'));
651#if QT_CONFIG(regularexpression)
652 if (syntax == PatternSyntax::Wildcard)
653 pos = pathPrefix.indexOf(QRegularExpression(
"[*?[]"_L1));
654 else if (syntax == PatternSyntax::RegularExpression)
655 pos = sourcePath.indexOf(QRegularExpression(
"[\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\}\\|]"_L1));
657 if (syntax == PatternSyntax::Wildcard || syntax == PatternSyntax::RegularExpression)
658 qWarning(
"Regular expression support is disabled in this build. Only fixed string can be searched");
659 return QList<QSslCertificate>();
664 pathPrefix = pathPrefix.left(pos);
665 const qsizetype lastIndexOfSlash = pathPrefix.lastIndexOf(u'/');
666 if (lastIndexOfSlash != -1)
667 pathPrefix = pathPrefix.left(lastIndexOfSlash);
672 if (QFileInfo(sourcePath).isFile())
673 return fromFile(sourcePath, format);
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 certs += QSslCertificate::fromFile(filePath, format);
738QList<QSslCertificate> QSslCertificate::fromData(
const QByteArray &data, QSsl::EncodingFormat format)
740 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
742 qCWarning(lcSsl,
"No TLS backend is available");
746 auto reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
748 qCWarning(lcSsl,
"The available TLS backend does not support reading PEM/DER");
752 return reader(data, -1);
767QList<QSslCertificate> QSslCertificate::fromFile(
const QString &filePath,
768 QSsl::EncodingFormat format)
770 QFile file(filePath);
771 QIODevice::OpenMode openMode = QIODevice::ReadOnly;
772 if (format == QSsl::Pem)
773 openMode |= QIODevice::Text;
774 if (file.open(openMode))
775 return QSslCertificate::fromData(file.readAll(), format);
794QList<QSslError> QSslCertificate::verify(
const QList<QSslCertificate> &certificateChain,
const QString &hostName)
796 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
798 qCWarning(lcSsl,
"No TLS backend is available");
801 auto verifyPtr = tlsBackend->X509Verifier();
803 qCWarning(lcSsl,
"Available TLS backend does not support manual certificate verification");
806 return verifyPtr(certificateChain, hostName);
821bool QSslCertificate::importPkcs12(QIODevice *device,
822 QSslKey *key, QSslCertificate *certificate,
823 QList<QSslCertificate> *caCertificates,
824 const QByteArray &passPhrase)
826 if (!device || !key || !certificate)
829 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
831 qCWarning(lcSsl,
"No TLS backend is available");
835 if (
auto reader = tlsBackend->X509Pkcs12Reader())
836 return reader(device, key, certificate, caCertificates, passPhrase);
838 qCWarning(lcSsl,
"Available TLS backend does not support PKCS12");
846 QList<QSslCertificateExtension> result;
849 auto nExt = backend->numberOfExtensions();
850 for (
decltype (nExt) i = 0; i < nExt; ++i) {
851 QSslCertificateExtension ext;
852 ext.d->oid = backend->oidForExtension(i);
853 ext.d->name = backend->nameForExtension(i);
854 ext.d->value = backend->valueForExtension(i);
855 ext.d->critical = backend->isExtensionCritical(i);
856 ext.d->supported = backend->isExtensionSupported(i);
918 if (certificate.serialNumber() == certificate_blacklist[a++] &&
919 (certificate.subjectInfo(QSslCertificate::CommonName).contains(blacklistedCommonName) ||
920 certificate.issuerInfo(QSslCertificate::CommonName).contains(blacklistedCommonName)))
929 case QSslCertificate::Organization:
return "O"_ba;
930 case QSslCertificate::CommonName:
return "CN"_ba;
931 case QSslCertificate::LocalityName:
return"L"_ba;
932 case QSslCertificate::OrganizationalUnitName:
return "OU"_ba;
933 case QSslCertificate::CountryName:
return "C"_ba;
934 case QSslCertificate::StateOrProvinceName:
return "ST"_ba;
935 case QSslCertificate::DistinguishedNameQualifier:
return "dnQualifier"_ba;
936 case QSslCertificate::SerialNumber:
return "serialNumber"_ba;
937 case QSslCertificate::EmailAddress:
return "emailAddress"_ba;