QDtls Class
Esta clase proporciona encriptación para sockets UDP. Más...
| Cabecera: | #include <QDtls> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Network)target_link_libraries(mytarget PRIVATE Qt6::Network) |
| qmake: | QT += network |
| Hereda: | QObject |
- Lista de todos los miembros, incluyendo los heredados
- QDtls es parte de la API de programación de red.
Tipos Públicos
| GeneratorParameters | |
| enum | HandshakeState { HandshakeNotStarted, HandshakeInProgress, PeerVerificationFailed, HandshakeComplete } |
Funciones Públicas
| QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr) | |
| virtual | ~QDtls() |
| bool | abortHandshake(QUdpSocket *socket) |
| QDtls::GeneratorParameters | cookieGeneratorParameters() const |
| QByteArray | decryptDatagram(QUdpSocket *socket, const QByteArray &dgram) |
| bool | doHandshake(QUdpSocket *socket, const QByteArray &dgram = {}) |
| QSslConfiguration | dtlsConfiguration() const |
| QDtlsError | dtlsError() const |
| QString | dtlsErrorString() const |
| bool | handleTimeout(QUdpSocket *socket) |
| QDtls::HandshakeState | handshakeState() const |
| void | ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore) |
| bool | isConnectionEncrypted() const |
| quint16 | mtuHint() const |
| QHostAddress | peerAddress() const |
| quint16 | peerPort() const |
| QList<QSslError> | peerVerificationErrors() const |
| QString | peerVerificationName() const |
| bool | resumeHandshake(QUdpSocket *socket) |
| QSslCipher | sessionCipher() const |
| QSsl::SslProtocol | sessionProtocol() const |
| bool | setCookieGeneratorParameters(const QDtls::GeneratorParameters ¶ms) |
| bool | setDtlsConfiguration(const QSslConfiguration &configuration) |
| void | setMtuHint(quint16 mtuHint) |
| bool | setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {}) |
| bool | setPeerVerificationName(const QString &name) |
| bool | shutdown(QUdpSocket *socket) |
| QSslSocket::SslMode | sslMode() const |
| qint64 | writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram) |
Señales
| void | handshakeTimeout() |
| void | pskRequired(QSslPreSharedKeyAuthenticator *authenticator) |
No miembros relacionados
| enum class | QDtlsError { NoError, InvalidInputParameters, InvalidOperation, UnderlyingSocketError, RemoteClosedConnectionError, …, TlsNonFatalError } |
Descripción detallada
La clase QDtls se puede utilizar para establecer una conexión segura con un peer de red utilizando el Protocolo de Datagramas de Usuario (UDP). La conexión DTLS sobre UDP esencialmente sin conexión significa que dos peers primero tienen que completar con éxito un handshake TLS llamando a doHandshake(). Una vez completado el protocolo de enlace, se pueden enviar datagramas cifrados al par mediante writeDatagramEncrypted(). Los datagramas cifrados procedentes del par pueden descifrarse mediante decryptDatagram().
QDtls está diseñado para trabajar con QUdpSocket. Dado que QUdpSocket puede recibir datagramas procedentes de diferentes peers, una aplicación debe implementar el demultiplexado, reenviando los datagramas procedentes de diferentes peers a sus correspondientes instancias de QDtls. Se puede establecer una asociación entre un peer de red y su objeto QDtls utilizando la dirección y el número de puerto del peer. Antes de iniciar un handshake, la aplicación debe establecer la dirección y el número de puerto del peer utilizando setPeer().
QDtls no lee datagramas de QUdpSocket, esto se espera que lo haga la aplicación, por ejemplo, en un slot adjunto a la señal QUdpSocket::readyRead(). Entonces, estos datagramas deben ser procesados por QDtls.
Nota: QDtls no toma posesión del objeto QUdpSocket.
Normalmente, varios datagramas deben ser recibidos y enviados por ambos peers durante la fase de handshake. Al leer los datagramas, el servidor y el cliente deben pasar estos datagramas a doHandshake() hasta que se encuentre algún error o handshakeState() devuelva HandshakeComplete:
// A client initiates a handshake: QUdpSocket clientSocket; QDtls clientDtls; clientDtls.setPeer(address, port, peerName); clientDtls.doHandshake(&clientSocket); // A server accepting an incoming connection; address, port, clientHello are // read by QUdpSocket::readDatagram(): QByteArray clientHello(serverSocket.pendingDatagramSize(), Qt::Uninitialized); QHostAddress address; quin16 port = {}; serverSocket.readDatagram(clientHello.data(), clientHello.size(), &address, &port); QDtls serverDtls; serverDtls.setPeer(address, port); serverDtls.doHandshake(&serverSocket, clientHello); // Handshake completion, both for server and client: void DtlsConnection::continueHandshake(const QByteArray &datagram) { if (dtls.doHandshake(&udpSocket, datagram)) { // Check handshake status: if (dtls.handshakeStatus() == QDlts::HandshakeComplete) { // Secure DTLS connection is now established. } } else { // Error handling. } }
Para un servidor, la primera llamada a doHandshake() requiere un datagrama no vacío que contenga un mensaje ClientHello. Si el servidor también despliega QDtlsClientVerifier, se espera que el primer mensaje ClientHello sea el verificado por QDtlsClientVerifier.
En caso de que la identidad del peer no pueda ser validada durante el handshake, la aplicación debe inspeccionar los errores devueltos por peerVerificationErrors() y entonces ignorar los errores llamando a ignoreVerificationErrors() o abortar el handshake llamando a abortHandshake(). Si los errores fueron ignorados, el handshake puede ser reanudado llamando a resumeHandshake().
Una vez completado el handshake, se pueden enviar y recibir datagramas de forma segura:
// Sending an encrypted datagram: dtlsConnection.writeDatagramEncrypted(&clientSocket, "Hello DTLS server!"); // Decryption: QByteArray encryptedMessage(dgramSize); socket.readDatagram(encryptedMessage.data(), dgramSize); const QByteArray plainText = dtlsConnection.decryptDatagram(&socket, encryptedMessage);
Una conexión DTLS puede cerrarse utilizando shutdown().
DtlsClient::~DtlsClient() { clientDtls.shutdown(&clientSocket); }
Advertencia: Se recomienda llamar a shutdown() antes de destruir el objeto QDtls del cliente si está planeando reutilizar el mismo número de puerto para conectarse al servidor más tarde. De lo contrario, el servidor puede perder los mensajes ClientHello entrantes, vea RFC 6347, sección 4.2.8 para más detalles y consejos de implementación.
Si el servidor no utiliza QDtlsClientVerifier, debe configurar sus objetos QDtls para desactivar el procedimiento de verificación de cookies:
auto config = QSslConfiguration::defaultDtlsConfiguration(); config.setDtlsCookieVerificationEnabled(false); // Some other customization ... dtlsConnection.setDtlsConfiguration(config);
Un servidor que utilice la verificación de cookies con parámetros generadores no predeterminados debe configurar los mismos parámetros para su objeto QDtls antes de iniciar el handshake.
Nota: El protocolo DTLS deja el descubrimiento de la Unidad de Transmisión Máxima de Ruta (PMTU) a la aplicación. La aplicación puede proporcionar a QDtls la MTU utilizando setMtuHint(). Esta sugerencia sólo afecta a la fase de handshake, ya que sólo los mensajes de handshake pueden ser fragmentados y reensamblados por el DTLS. Todos los demás mensajes enviados por la aplicación deben caber en un único datagrama.
Nota: Las cabeceras específicas del DTLS añaden cierta sobrecarga a los datos de la aplicación, reduciendo aún más el tamaño posible del mensaje.
Advertencia: Un servidor configurado para responder con HelloVerifyRequest descartará todos los mensajes ClientHello fragmentados, sin iniciar nunca un handshake.
Los ejemplos de servidor DTLS y cliente DTLS ilustran cómo utilizar QDtls en aplicaciones.
Ver también QUdpSocket, QDtlsClientVerifier, HandshakeState, QDtlsError, y QSslConfiguration.
Documentación de tipos de miembros
[alias] QDtls::GeneratorParameters
enum QDtls::HandshakeState
Describe el estado actual del handshake DTLS.
Este enum describe el estado actual del handshake DTLS para una conexión QDtls.
| Constante | Valor | Descripción |
|---|---|---|
QDtls::HandshakeNotStarted | 0 | Aún no se ha hecho nada. |
QDtls::HandshakeInProgress | 1 | Se ha iniciado el handshake y no se han encontrado errores hasta el momento. |
QDtls::PeerVerificationFailed | 2 | No se puede establecer la identidad del peer. |
QDtls::HandshakeComplete | 3 | El Handshake se completó con éxito y se estableció la conexión cifrada. |
Véase también QDtls::doHandshake() y QDtls::handshakeState().
Documentación de las funciones miembro
[explicit] QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)
Crea un objeto QDtls, parent se pasa al constructor QObject. mode es QSslSocket::SslServerMode para una conexión DTLS del lado del servidor o QSslSocket::SslClientMode para un cliente.
Véase también sslMode() y QSslSocket::SslMode.
[virtual noexcept] QDtls::~QDtls()
Destruye el objeto QDtls.
bool QDtls::abortHandshake(QUdpSocket *socket)
Aborta el handshake en curso. Devuelve true si había uno en curso en socket; en caso contrario, establece un error adecuado y devuelve false.
Véase también doHandshake() y resumeHandshake().
QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const
Devuelve el algoritmo hash y el secreto actuales, ya sean los predeterminados o los establecidos previamente mediante una llamada a setCookieGeneratorParameters().
El algoritmo hash por defecto es QCryptographicHash::Sha256 si Qt fue configurado para soportarlo, QCryptographicHash::Sha1 en caso contrario. El secreto por defecto se obtiene del generador de números pseudoaleatorios criptográficamente fuerte específico del backend.
Véase también QDtlsClientVerifier y setCookieGeneratorParameters().
QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
Desencripta dgram y devuelve su contenido como texto sin formato. El handshake debe completarse antes de que los datagramas puedan ser desencriptados. Dependiendo del tipo de mensaje TLS, la conexión puede escribir en socket, que debe ser un puntero válido.
bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})
Inicia o continúa un handshake DTLS. socket debe ser un puntero válido. Cuando se inicia un handshake DTLS del lado del servidor, dgram debe contener el mensaje ClientHello inicial leído de QUdpSocket. Esta función devuelve true si no se encontró ningún error. El estado del Handshake puede comprobarse utilizando handshakeState(). El retorno de false significa que se ha producido algún error, utilice dtlsError() para obtener información más detallada.
Nota: Si no se puede establecer la identidad del peer, el error se establece en QDtlsError::PeerVerificationError. Si se desea ignorar los errores de verificación y continuar la conexión, se debe llamar a ignoreVerificationErrors() y luego a resumeHandshake(). Si no se pueden ignorar los errores, se debe llamar a abortHandshake().
if (!dtls.doHandshake(&socket, dgram)) { if (dtls.dtlsError() == QDtlsError::PeerVerificationError) dtls.abortAfterError(&socket); }
Véase también handshakeState(), dtlsError(), ignoreVerificationErrors(), resumeHandshake() y abortHandshake().
QSslConfiguration QDtls::dtlsConfiguration() const
Devuelve la configuración DTLS por defecto o la configuración establecida por una llamada anterior a setDtlsConfiguration().
Véase también setDtlsConfiguration() y QSslConfiguration::defaultDtlsConfiguration().
QDtlsError QDtls::dtlsError() const
Devuelve el último error encontrado por la conexión o QDtlsError::NoError.
Véase también dtlsErrorString() y QDtlsError.
QString QDtls::dtlsErrorString() const
Devuelve una descripción textual del último error encontrado por la conexión o una cadena vacía.
Véase también dtlsError().
bool QDtls::handleTimeout(QUdpSocket *socket)
Si se produce un timeout durante el handshake, se emite la señal handshakeTimeout(). La aplicación debe llamar a handleTimeout() para retransmitir los mensajes de handshake; handleTimeout() devuelve true si se ha producido un timeout, false en caso contrario. socket debe ser un puntero válido.
Véase también handshakeTimeout().
QDtls::HandshakeState QDtls::handshakeState() const
Devuelve el estado actual del apretón de manos para este QDtls.
Véase también doHandshake() y QDtls::HandshakeState.
[signal] void QDtls::handshakeTimeout()
La pérdida de paquetes puede provocar tiempos de espera durante la fase de handshake. En este caso QDtls emite una señal handshakeTimeout(). Llama a handleTimeout() para retransmitir los mensajes de handshake:
DtlsClient::DtlsClient() { // Some initialization code here ... connect(&clientDtls, &QDtls::handshakeTimeout, this, &DtlsClient::handleTimeout); } void DtlsClient::handleTimeout() { clientDtls.handleTimeout(&clientSocket); }
Véase también handleTimeout().
void QDtls::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
Este método indica a QDtls que ignore sólo los errores indicados en errorsToIgnore.
Si, por ejemplo, quieres conectarte a un servidor que utiliza un certificado autofirmado, considera el siguiente fragmento:
QList<QSslCertificate> cert = QSslCertificate::fromPath("server-certificate.pem"_L1); QSslError error(QSslError::SelfSignedCertificate, cert.at(0)); QList<QSslError> expectedSslErrors; expectedSslErrors.append(error); QDtls dtls; dtls.ignoreVerificationErrors(expectedSslErrors); dtls.doHandshake(udpSocket);
También puedes llamar a esta función después de que doHandshake() encuentre el error QDtlsError::PeerVerificationError, y luego reanudar el handshake llamando a resumeHandshake().
Las llamadas posteriores a esta función reemplazarán la lista de errores que se pasaron en las llamadas anteriores. Puede borrar la lista de errores que desea ignorar llamando a esta función con una lista vacía.
Véase también doHandshake(), resumeHandshake(), y QSslError.
bool QDtls::isConnectionEncrypted() const
Devuelve true si el handshake DTLS se ha completado con éxito.
Véase también doHandshake() y handshakeState().
quint16 QDtls::mtuHint() const
Devuelve el valor establecido previamente por setMtuHint(). El valor por defecto es 0.
Véase también setMtuHint().
QHostAddress QDtls::peerAddress() const
Devuelve la dirección del par, establecida por setPeer(), o QHostAddress::Null.
Véase también setPeer().
quint16 QDtls::peerPort() const
Devuelve el número de puerto del peer, establecido por setPeer(), o 0.
Véase también setPeer().
QList<QSslError> QDtls::peerVerificationErrors() const
Devuelve los errores encontrados al establecer la identidad del peer.
Si desea continuar la conexión a pesar de los errores producidos, debe llamar a ignoreVerificationErrors().
QString QDtls::peerVerificationName() const
Devuelve el nombre de host establecido por setPeer() o setPeerVerificationName(). El valor por defecto es una cadena vacía.
Véase también setPeerVerificationName() y setPeer().
[signal] void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)
QDtls emite esta señal cuando negocia un cifrado PSK, por lo que se requiere una autenticación PSK.
Cuando se utiliza PSK, el cliente debe enviar al servidor una identidad válida y una clave precompartida válida, para que el handshake TLS pueda continuar. Las aplicaciones pueden proporcionar esta información en una ranura conectada a esta señal, rellenando el objeto authenticator pasado según sus necesidades.
Nota: Ignorar esta señal, o no proporcionar las credenciales requeridas, causará que el handshake falle, y por lo tanto que la conexión sea abortada.
Nota: El objeto authenticator es propiedad de QDtls y no debe ser eliminado por la aplicación.
Véase también QSslPreSharedKeyAuthenticator.
bool QDtls::resumeHandshake(QUdpSocket *socket)
Si se ignoraron los errores de verificación de pares durante el handshake, resumeHandshake() reanuda y completa el handshake y devuelve true. socket debe ser un puntero válido. Devuelve false si no se ha podido reanudar el handshake.
Véase también doHandshake(), abortHandshake(), peerVerificationErrors() y ignoreVerificationErrors().
QSslCipher QDtls::sessionCipher() const
Devuelve el cipher criptográfico utilizado por esta conexión, o un cifrado nulo si la conexión no está cifrada. El cifrado para la sesión se selecciona durante la fase de apretón de manos. El cifrado se utiliza para cifrar y descifrar datos.
QSslConfiguration proporciona funciones para establecer la lista ordenada de cifradores a partir de la cual la fase de handshake seleccionará finalmente el cifrado de la sesión. Esta lista ordenada debe estar en su lugar antes de que comience la fase de handshake.
Véase también QSslConfiguration, setDtlsConfiguration(), y dtlsConfiguration().
QSsl::SslProtocol QDtls::sessionProtocol() const
Devuelve la versión del protocolo DTLS utilizada por esta conexión, o UnknownProtocol si la conexión aún no está cifrada. El protocolo para la conexión se selecciona durante la fase de handshake.
setDtlsConfiguration() puede establecer la versión preferida antes de que comience el handshake.
Véase también setDtlsConfiguration(), QSslConfiguration, QSslConfiguration::defaultDtlsConfiguration(), y QSslConfiguration::setProtocol().
bool QDtls::setCookieGeneratorParameters(const QDtls::GeneratorParameters ¶ms)
Establece el algoritmo hash criptográfico y el secreto de params. Esta función sólo es necesaria para una conexión del lado del servidor QDtls. Devuelve true si tiene éxito.
Nota: Esta función debe ser llamada antes de que comience el handshake.
Véase también cookieGeneratorParameters(), doHandshake(), QDtlsClientVerifier, y QDtlsClientVerifier::cookieGeneratorParameters().
bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)
Establece la configuración TLS de la conexión desde configuration y devuelve true si tiene éxito.
Nota: Esta función debe ser llamada antes de que comience el handshake.
Véase también dtlsConfiguration() y doHandshake().
void QDtls::setMtuHint(quint16 mtuHint)
mtuHint es la unidad de transmisión máxima (MTU), descubierta o adivinada por la aplicación. No es necesario que la aplicación establezca este valor.
Véase también mtuHint() y QAbstractSocket::PathMtuSocketOption.
bool QDtls::setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})
Establece la dirección del homólogo, port, y el nombre de host y devuelve true si se ha realizado correctamente. address no debe ser nulo, multidifusión ni difusión. verificationName es el nombre de host utilizado para la validación del certificado.
Véase también peerAddress(), peerPort() y peerVerificationName().
bool QDtls::setPeerVerificationName(const QString &name)
Establece el host name que se utilizará para la validación del certificado y devuelve true si tiene éxito.
Nota: Esta función debe ser llamada antes de que comience el handshake.
Véase también peerVerificationName() y setPeer().
bool QDtls::shutdown(QUdpSocket *socket)
Envía un mensaje de alerta de cierre cifrado y cierra la conexión DTLS. El estado de Handshake cambia a QDtls::HandshakeNotStarted. socket debe ser un puntero válido. Esta función devuelve true en caso de éxito.
Véase también doHandshake().
QSslSocket::SslMode QDtls::sslMode() const
Devuelve QSslSocket::SslServerMode para una conexión del lado del servidor y QSslSocket::SslClientMode para un cliente.
Véase también QDtls() y QSslSocket::SslMode.
qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
Cifra dgram y escribe los datos cifrados en socket. Devuelve el número de bytes escritos, o -1 en caso de error. El handshake debe completarse antes de escribir los datos encriptados. socket debe ser un puntero válido.
Véase también doHandshake(), handshakeState(), isConnectionEncrypted(), y dtlsError().
No miembros relacionados
enum class QDtlsError
Describe los errores que pueden encontrar los objetos de las clases QDtls y QDtlsClientVerifier.
Este enum describe los errores generales y específicos de TLS que pueden encontrar los objetos de las clases QDtlsClientVerifier y QDtls.
| Constante | Valor | Descripción |
|---|---|---|
QDtls::QDtlsError::NoError | 0 | No se ha producido ningún error, la última operación se ha realizado correctamente. |
QDtls::QDtlsError::InvalidInputParameters | 1 | Los parámetros de entrada proporcionados por el autor de la llamada no eran válidos. |
QDtls::QDtlsError::InvalidOperation | 2 | Se intentó realizar una operación en un estado que no lo permitía. |
QDtls::QDtlsError::UnderlyingSocketError | 3 | QUdpSocket::writeDatagram() falló, QUdpSocket::error() y QUdpSocket::errorString() pueden proporcionar información más específica. |
QDtls::QDtlsError::RemoteClosedConnectionError | 4 | Se recibió un mensaje de alerta de desconexión TLS. |
QDtls::QDtlsError::PeerVerificationError | 5 | No se pudo verificar la identidad del peer durante el handshake TLS. |
QDtls::QDtlsError::TlsInitializationError | 6 | Se produjo un error al inicializar un backend TLS subyacente. |
QDtls::QDtlsError::TlsFatalError | 7 | Se ha producido un error fatal durante el protocolo TLS, distinto de un error de verificación de pares o un error de inicialización de TLS. |
QDtls::QDtlsError::TlsNonFatalError | 8 | Un fallo al cifrar o descifrar un datagrama, no fatal, lo que significa que QDtls puede seguir funcionando después de este error. |
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.