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>();
665 pathPrefix = pathPrefix.left(pos);
666 const qsizetype lastIndexOfSlash = pathPrefix.lastIndexOf(u'/');
667 if (lastIndexOfSlash != -1)
668 pathPrefix = pathPrefix.left(lastIndexOfSlash);
673 if (QFileInfo(sourcePath).isFile())
674 return fromFile(sourcePath, format);
679 if (pathPrefix.isEmpty()) {
684 const QString pathPrefixString = pathPrefix.toString();
687 QList<QSslCertificate> certs;
689#if QT_CONFIG(regularexpression)
690 if (syntax == PatternSyntax::Wildcard)
691 sourcePath = QRegularExpression::wildcardToRegularExpression(sourcePath, QRegularExpression::UnanchoredWildcardConversion);
693 QRegularExpression pattern(QRegularExpression::anchoredPattern(sourcePath));
696 using F = QDirListing::IteratorFlag;
697 constexpr auto iterFlags = F::FollowDirSymlinks | F::Recursive | F::FilesOnly;
698 for (
const auto &dirEntry : QDirListing(pathPrefixString, iterFlags)) {
699 QString filePath = dirEntry.filePath();
701 filePath.remove(0, startIndex);
703#if QT_CONFIG(regularexpression)
704 if (!pattern.match(filePath).hasMatch())
707 if (sourcePath != filePath)
711 certs += QSslCertificate::fromFile(filePath, format);
739QList<QSslCertificate> QSslCertificate::fromData(
const QByteArray &data, QSsl::EncodingFormat format)
741 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
743 qCWarning(lcSsl,
"No TLS backend is available");
747 auto reader = format == QSsl::Pem ? tlsBackend->X509PemReader() : tlsBackend->X509DerReader();
749 qCWarning(lcSsl,
"The available TLS backend does not support reading PEM/DER");
753 return reader(data, -1);
768QList<QSslCertificate> QSslCertificate::fromFile(
const QString &filePath,
769 QSsl::EncodingFormat format)
771 QFile file(filePath);
772 QIODevice::OpenMode openMode = QIODevice::ReadOnly;
773 if (format == QSsl::Pem)
774 openMode |= QIODevice::Text;
775 if (file.open(openMode))
776 return QSslCertificate::fromData(file.readAll(), format);
795QList<QSslError> QSslCertificate::verify(
const QList<QSslCertificate> &certificateChain,
const QString &hostName)
797 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
799 qCWarning(lcSsl,
"No TLS backend is available");
802 auto verifyPtr = tlsBackend->X509Verifier();
804 qCWarning(lcSsl,
"Available TLS backend does not support manual certificate verification");
807 return verifyPtr(certificateChain, hostName);
822bool QSslCertificate::importPkcs12(QIODevice *device,
823 QSslKey *key, QSslCertificate *certificate,
824 QList<QSslCertificate> *caCertificates,
825 const QByteArray &passPhrase)
827 if (!device || !key || !certificate)
830 const auto *tlsBackend = QTlsBackend::activeOrAnyBackend();
832 qCWarning(lcSsl,
"No TLS backend is available");
836 if (
auto reader = tlsBackend->X509Pkcs12Reader())
837 return reader(device, key, certificate, caCertificates, passPhrase);
839 qCWarning(lcSsl,
"Available TLS backend does not support PKCS12");
847 QList<QSslCertificateExtension> result;
850 auto nExt = backend->numberOfExtensions();
851 for (
decltype (nExt) i = 0; i < nExt; ++i) {
852 QSslCertificateExtension ext;
853 ext.d->oid = backend->oidForExtension(i);
854 ext.d->name = backend->nameForExtension(i);
855 ext.d->value = backend->valueForExtension(i);
856 ext.d->critical = backend->isExtensionCritical(i);
857 ext.d->supported = backend->isExtensionSupported(i);
930 case QSslCertificate::Organization:
return "O"_ba;
931 case QSslCertificate::CommonName:
return "CN"_ba;
932 case QSslCertificate::LocalityName:
return"L"_ba;
933 case QSslCertificate::OrganizationalUnitName:
return "OU"_ba;
934 case QSslCertificate::CountryName:
return "C"_ba;
935 case QSslCertificate::StateOrProvinceName:
return "ST"_ba;
936 case QSslCertificate::DistinguishedNameQualifier:
return "dnQualifier"_ba;
937 case QSslCertificate::SerialNumber:
return "serialNumber"_ba;
938 case QSslCertificate::EmailAddress:
return "emailAddress"_ba;