QDtls Class

このクラスはUDPソケットの暗号化を行う。詳細...

ヘッダ #include <QDtls>
CMake: find_package(Qt6 REQUIRED COMPONENTS Network)
target_link_libraries(mytarget PRIVATE Qt6::Network)
qmake: QT += network
継承: QObject

パブリック型

GeneratorParameters
enum HandshakeState { HandshakeNotStarted, HandshakeInProgress, PeerVerificationFailed, HandshakeComplete }

パブリック関数

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 &params)
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)

シグナル

void handshakeTimeout()
void pskRequired(QSslPreSharedKeyAuthenticator *authenticator)
enum class QDtlsError { NoError, InvalidInputParameters, InvalidOperation, UnderlyingSocketError, RemoteClosedConnectionError, …, TlsNonFatalError }

詳細説明

QDtlsクラスは、UDP(User Datagram Protocol)を使用してネットワーク・ピアとのセキュアな接続を確立するために使用できます。本質的にコネクションレスなUDP上でのDTLS接続とは、まず2つのピアがdoHandshake() をコールしてTLSハンドシェイクを成功させなければならないことを意味する。ハンドシェイクが完了すると、writeDatagramEncrypted()を使って暗号化されたデータグラムをピアに送ることができる。ピアから送られてくる暗号化されたデータグラムは、decryptDatagram ()で復号化できる。

QDtlsは、QUdpSocket で動作するように設計されています。QUdpSocket は異なるピアからのデータグラムを受信できるため、アプリケーションはデマルチプレクスを実装し、異なるピアからのデータグラムを対応するQDtlsインスタンスに転送する必要がある。ネットワーク・ピアとそのQDtlsオブジェクトの関連付けは、ピアのアドレスとポート番号を使って確立できる。ハンドシェイクを開始する前に、アプリケーションはsetPeer ()を使用してピアのアドレスとポート番号を設定する必要があります。

QDtlsはQUdpSocket からデータグラムを読み込まないため、アプリケーションはQUdpSocket::readyRead ()シグナルに接続されたスロットなどでデータグラムを読み込む必要がある。その後、これらのデータグラムはQDtlsによって処理されなければならない。

注意: QDtlsはQUdpSocket オブジェクトの所有権を持ちません

通常、ハンドシェーク・フェーズの間に、両方のピアによって複数のデータグラムが送受信される。データグラムを読み込むと、サーバーとクライアントは、何らかのエラーが発 生するか、handshakeState() がHandshakeComplete を返すまで、これらのデータグラ ムをdoHandshake() に渡さなければならない:

// 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.
    }
}

サーバーの場合、doHandshake()への最初の呼び出しは、 ClientHelloメッセージを含む空でないデータグラムを必要とする。サーバーがQDtlsClientVerifier も展開している場合、最初のClientHelloメッセージは、QDtlsClientVerifier で検証されたものであることが期待される。

ハンドシェイク中に相手のIDを検証できない場合、アプリケーションはpeerVerificationErrors() が返すエラーを検査し、ignoreVerificationErrors() を呼び出してエラーを無視するか、abortHandshake() を呼び出してハンドシェイクを中止しなければならない。エラーを無視した場合、resumeHandshake ()を呼び出すことで、ハンドシェイクを再開できる。

ハンドシェイクが完了すると、ネットワーク・ピアとの間でデータグラムを安全に送受信できるようになる:

// 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);

DTLS接続は、shutdown ()を使用して閉じることができる。

DtlsClient::~DtlsClient()
{
    clientDtls.shutdown(&clientSocket);
}

警告: 警告:後で同じポート番号を再利用してサーバーに接続する場合は、クライアントのQDtlsオブジェクトを破棄する前にshutdown ()を呼び出すことを推奨する。そうしないと、サーバーは受信した ClientHelloメッセージを落とすかもしれない。詳細と実装のヒントについては、RFC 6347のセクション4.2.8を参照のこと。

サーバーがQDtlsClientVerifier を使用しない場合、QDtls オブジェクトを構成してクッキー検証手順を無効にする必要がある

auto config = QSslConfiguration::defaultDtlsConfiguration();
config.setDtlsCookieVerificationEnabled(false);
// Some other customization ...
dtlsConnection.setDtlsConfiguration(config);

デフォルト以外のジェネレータ・パラメータでCookie検証を使用するサーバーは、ハンドシェイクを開始する前に、同じパラメータをQDtlsオブジェクトに設定しなければならない

注: DTLSプロトコルはPMTU(Path Maximum Transmission Unit)の発見をアプリケーションに任せている。アプリケーションは、setMtuHint ()を使用してQDtlsにMTUを提供することができる。ハンドシェイク・メッセージだけがDTLSによってフラグメント化され、再アセンブルされるので、このヒントはハンドシェイク・フェーズだけに影響する。アプリケーションから送信される他のすべてのメッセージは、1つのデータグラムに収まらなければならない。

注意: DTLS 固有のヘッダーはアプリケーション・データにオーバーヘッドを追加し、可能なメッセージ・サイズをさらに小さくする。

警告: HelloVerifyRequestで応答するように設定されたサーバーは、フラグメント化された ClientHelloメッセージをすべてドロップし、決してハンドシェイクを開始しない。

DTLSサーバーと DTLSクライアントの例は、アプリケーションでQDtlsを使用する方法を示している。

QUdpSocketQDtlsClientVerifierHandshakeStateQDtlsErrorQSslConfigurationも参照のこと

メンバー・タイプ・ドキュメント

[alias] QDtls::GeneratorParameters

enum QDtls::HandshakeState

DTLSハンドシェイクの現在の状態を記述する。

この enum はQDtls 接続の DTLS ハンドシェイクの現在の状態を記述する。

定数説明
QDtls::HandshakeNotStarted0まだ何も行われていない。
QDtls::HandshakeInProgress1ハンドシェイクが開始され、今のところエラーは見つかっていない。
QDtls::PeerVerificationFailed2相手の身元が確認できない。
QDtls::HandshakeComplete3ハンドシェイクが正常に完了し、暗号化された接続が確立された。

QDtls::doHandshake() およびQDtls::handshakeState()も参照

メンバー関数ドキュメント

[explicit] QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)

QDtls オブジェクトを作成します。parentQObject コンストラクタに渡されます。mode は、サーバー側の DTLS 接続の場合はQSslSocket::SslServerMode となり、クライアントの場合はQSslSocket::SslClientMode となります。

sslMode() およびQSslSocket::SslModeも参照してください

[virtual noexcept] QDtls::~QDtls()

QDtls オブジェクトを破棄する。

bool QDtls::abortHandshake(QUdpSocket *socket)

進行中のハンドシェークを中止する。socket で進行中だった場合はtrueを返し、そうでない場合は適切なエラーを設定してfalseを返す。

doHandshake() およびresumeHandshake()も参照のこと

QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const

現在のハッシュアルゴリズムとシークレットを返します。デフォルトのアルゴリズムか、setCookieGeneratorParameters() のコールによって設定されたものです。

デフォルトのハッシュアルゴリズムは、Qt がそれをサポートするように設定されている場合はQCryptographicHash::Sha256 で、そうでない場合はQCryptographicHash::Sha1 です。デフォルトの秘密は、バックエンド固有の暗号化された強力な擬似乱数生成器から取得されます。

setCookieGeneratorParameters()、QDtlsClientVerifier 、および CookieGeneratorParameters()も参照してください

QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)

dgram を復号化し、その内容をプレーンテキストとして返す。データグラムを復号化する前に、ハンドシェイクが完了していなければならない。TLSメッセージのタイプによっては、接続はsocket に書き込むかもしれない。 は有効なポインタでなければならない。

bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})

DTLSハンドシェイクを開始または継続する。socket は有効なポインタでなければならない。サーバー側のDTLSハンドシェイクを開始する場合、dgram には、QUdpSocket から読み込んだ最初の ClientHelloメッセージが含まれていなければならない。 この関数は、エラーが見つからなかった場合、true を返す。ハンドシェイクの状態は、handshakeState()を使用してテストできる。false returnは何らかのエラーが発生したことを意味し、より詳細な情報はdtlsError()を使用する。

注意: ピアの ID を確立できない場合、エラーはQDtlsError::PeerVerificationError に設定される。検証エラーを無視して接続を続行する場合は、ignoreVerificationErrors() を呼び出してからresumeHandshake() を呼び出す必要がある。エラーを無視できない場合は、abortHandshake() を呼び出す必要がある。

if (!dtls.doHandshake(&socket, dgram)) {
    if (dtls.dtlsError() == QDtlsError::PeerVerificationError)
        dtls.abortAfterError(&socket);
}

handshakeState()、dtlsError()、ignoreVerificationErrors()、resumeHandshake()、abortHandshake()も参照

QSslConfiguration QDtls::dtlsConfiguration() const

デフォルトのDTLSコンフィギュレーションか、setDtlsConfiguration() のコールによって設定されたコンフィギュレーションのいずれかを返す。

setDtlsConfiguration() およびQSslConfiguration::defaultDtlsConfiguration()も参照

QDtlsError QDtls::dtlsError() const

接続またはQDtlsError::NoError で最後に発生したエラーを返す。

dtlsErrorString() およびQDtlsErrorも参照

QString QDtls::dtlsErrorString() const

接続で最後に発生したエラーの説明をテキストで返すか、空の文字列を返します。

dtlsError()も参照ください

bool QDtls::handleTimeout(QUdpSocket *socket)

ハンドシェイク中にタイムアウトが発生すると、handshakeTimeout ()シグナルが発 生する。アプリケーションは、ハンドシェイク・メッセージを再送するために handleTimeout() を呼び出す必要がある。handleTimeout() は、タイムアウトが発生した場合はtrue を返し、そうでない場合は false を返す。socket は有効なポインタでなければならない。

handshakeTimeout()も参照のこと

QDtls::HandshakeState QDtls::handshakeState() const

このQDtls の現在のハンドシェーク状態を返す。

doHandshake() およびQDtls::HandshakeStateも参照

[signal] void QDtls::handshakeTimeout()

パケットロスは、ハンドシェーク・フェーズのタイムアウトにつながる可能性がある。この場合、QDtls は handshakeTimeout() シグナルを発する。handleTimeout() を呼び出して、ハンドシェーク・メッセージを再送する:

DtlsClient::DtlsClient()
{
    // Some initialization code here ...
    connect(&clientDtls, &QDtls::handshakeTimeout, this, &DtlsClient::handleTimeout);
}

void DtlsClient::handleTimeout()
{
    clientDtls.handleTimeout(&clientSocket);
}

handleTimeout()も参照

void QDtls::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)

このメソッドは、errorsToIgnore で指定されたエラーだけを無視するようにQDtls に指示する。

例えば、自己署名証明書を使用するサーバーに接続したい場合、以下のスニペットを考 慮してほしい:

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);

この関数は、doHandshake ( )がQDtlsError::PeerVerificationError エラーに遭遇した後に呼び出すこともでき、その場合はresumeHandshake ( )を呼び出してハンドシェイクを再開する。

この関数を後で呼び出すと、前の呼び出しで渡されたエラーのリストが置き換えられる。この関数を空のリストで呼び出すと、無視したいエラーのリストを消去できる。

doHandshake()、resumeHandshake()、QSslErrorも参照のこと

bool QDtls::isConnectionEncrypted() const

DTLSハンドシェイクが正常に完了した場合はtrue を返す。

doHandshake() およびhandshakeState()も参照

quint16 QDtls::mtuHint() const

setMtuHint() で設定した値を返す。デフォルト値は 0。

setMtuHint()も参照

QHostAddress QDtls::peerAddress() const

setPeer()、またはQHostAddress::Null で設定されたピアのアドレスを返す。

setPeer()も参照のこと

quint16 QDtls::peerPort() const

setPeer() で設定した相手のポート番号、または 0 を返す。

setPeer()も参照

QList<QSslError> QDtls::peerVerificationErrors() const

ピアの ID 確立中に見つかったエラーを返す。

エラーが発生したにもかかわらず接続を続行したい場合は、ignoreVerificationErrors() を呼び出す必要がある。

QString QDtls::peerVerificationName() const

setPeer() またはsetPeerVerificationName() で設定されたホスト名を返す。デフォルト値は空文字列です。

setPeerVerificationName() およびsetPeer()も参照

[signal] void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)

QDtls はPSK暗号スイートをネゴシエートするときにこのシグナルを発するので、 PSK認証が必要になる。

PSKを使用する場合、TLSハンドシェイクを継続するために、クライアントは有効なIDと有効な事前共有鍵をサーバーに送信しなければならない。アプリケーションは、このシグナルに接続されたスロットに、渡されたauthenticator オブジェクトを必要に応じて入力することで、この情報を提供することができる。

注: このシグナルを無視したり、必要な認証情報を提供しなかったりすると、ハンドシェイクが失敗し、接続が中断される。

注意 authenticator オブジェクトはQDtls が所有しており、アプリケーションによって削除されてはならない。

QSslPreSharedKeyAuthenticatorも参照のこと

bool QDtls::resumeHandshake(QUdpSocket *socket)

ハンドシェイク中にピア検証エラーが無視された場合、resumeHandshake() はハンドシェイクを再開して完了し、true を返す。socket は有効なポインタでなければならない。ハンドシェークを再開できなかった場合はfalse を返す。

doHandshake()、abortHandshake()、peerVerificationErrors()、ignoreVerificationErrors()も参照のこと

QSslCipher QDtls::sessionCipher() const

この接続で使用されている暗号cipher を返します。 接続が暗号化されていない場合は null の暗号を返します。セッションの暗号はハンドシェーク時に選択されます。暗号はデータの暗号化と復号に使用されます。

QSslConfiguration には、ハンドシェークフェーズで最終的にセッション暗号を選択する暗号の順序リストを設定する関数が用意されています。この順序付きリストは、ハンドシェークフェーズの開始前に設定されている必要がある。

QSslConfigurationsetDtlsConfiguration()、dtlsConfiguration()も参照のこと

QSsl::SslProtocol QDtls::sessionProtocol() const

この接続で使用されている DTLS プロトコルのバージョンを返します。 接続がまだ暗号化されていない場合は UnknownProtocol を返します。接続のプロトコルはハンドシェーク時に選択されます。

setDtlsConfiguration() は、ハンドシェークが始まる前に優先バージョンを設定することができます。

setDtlsConfiguration()、QSslConfigurationQSslConfiguration::defaultDtlsConfiguration()、QSslConfiguration::setProtocol()も参照

bool QDtls::setCookieGeneratorParameters(const QDtls::GeneratorParameters &params)

暗号化ハッシュアルゴリズムとparams からのシークレットを設定する。 この関数はサーバーサイドQDtls 接続にのみ必要である。成功すればtrue を返す。

注意: この関数は、ハンドシェイクが始まる前に呼び出されなければならない。

cookieGeneratorParameters()、doHandshake()、QDtlsClientVerifier 、およびQDtlsClientVerifier::cookieGeneratorParameters()も参照

bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)

接続のTLSコンフィギュレーションをconfiguration から設定し、成功したらtrue を返す。

注意: この関数はハンドシェイクが始まる前に呼び出されなければならない。

dtlsConfiguration() およびdoHandshake()も参照のこと

void QDtls::setMtuHint(quint16 mtuHint)

mtuHint は最大伝送単位(MTU)であり、アプリケーションによって検出または推測される。アプリケーションはこの値を設定する必要はない。

mtuHint() およびQAbstractSocket::PathMtuSocketOptionも参照のこと

bool QDtls::setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})

ピアのアドレス、port 、およびホスト名を設定し、成功すればtrue を返す。address は、NULL、マルチキャスト、またはブロードキャストであってはならない。verificationName は、証明書の検証に使用されるホスト名である。

peerAddress()、peerPort()、peerVerificationName()も参照のこと

bool QDtls::setPeerVerificationName(const QString &name)

証明書の検証に使用するホストname を設定し、成功した場合はtrue を返す。

注意: この関数は、ハンドシェイクが始まる前に呼び出されなければならない。

peerVerificationName() およびsetPeer()も参照のこと

bool QDtls::shutdown(QUdpSocket *socket)

暗号化されたシャットダウン警告メッセージを送信し、DTLS接続を閉じる。ハンドシェーク状態はQDtls::HandshakeNotStarted に変化する。socket は有効なポインタでなければならない。この関数は成功するとtrue を返す。

doHandshake()も参照のこと

QSslSocket::SslMode QDtls::sslMode() const

サーバ側接続の場合はQSslSocket::SslServerMode を、クライアントの場合はQSslSocket::SslClientMode を返す。

QDtls() およびQSslSocket::SslModeも参照のこと

qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)

dgram を暗号化し、暗号化されたデータをsocket に書き込む。書き込まれたバイト数、またはエラーの場合は-1を返す。socket は有効なポインタでなければならない。

doHandshake()、handshakeState()、isConnectionEncrypted()、dtlsError()も参照のこと

関連する非メンバー

enum class QDtlsError

QDtls およびQDtlsClientVerifier によって発見される可能性のあるエラーを記述する。

この列挙型は、QDtlsClientVerifierQDtls のクラスのオブジェクトが遭遇する可能性のある、一般的なエラーと TLS 固有のエラーを記述します。

定数説明
QDtls::QDtlsError::NoError0エラーは発生せず、最後の操作は成功した。
QDtls::QDtlsError::InvalidInputParameters1呼び出し元が提供した入力パラメータが無効でした。
QDtls::QDtlsError::InvalidOperation2操作が許可されていない状態で操作を試みた。
QDtls::QDtlsError::UnderlyingSocketError3QUdpSocket::writeDatagram()は失敗した。QUdpSocket::error()およびQUdpSocket::errorString()は、より具体的な情報を提供できる。
QDtls::QDtlsError::RemoteClosedConnectionError4TLSシャットダウン警告メッセージを受信した。
QDtls::QDtlsError::PeerVerificationError5TLSハンドシェイク中にピアの身元を確認できなかった。
QDtls::QDtlsError::TlsInitializationError6基盤となるTLSバックエンドの初期化中にエラーが発生した。
QDtls::QDtlsError::TlsFatalError7TLSハンドシェイク中に致命的なエラーが発生した(ピア検証エラーまたはTLS初期化エラー以外)。
QDtls::QDtlsError::TlsNonFatalError8データグラムの暗号化または復号化に失敗した。致命的なエラーではないので、QDtls 、このエラーの後でも作業を継続できる。

© 2025 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.