QDtls Class
このクラスはUDPソケットの暗号化を行う。詳細...
ヘッダ | #include <QDtls> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Network) target_link_libraries(mytarget PRIVATE Qt6::Network) |
qmake: | QT += network |
継承: | QObject |
- 継承されたメンバーを含む全メンバーのリスト
- QDtls はNetwork Programming API に含まれています。
パブリック型
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 ¶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) |
シグナル
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を使用する方法を示している。
QUdpSocket 、QDtlsClientVerifier 、HandshakeState 、QDtlsError 、QSslConfigurationも参照のこと 。
メンバー・タイプ・ドキュメント
[alias]
QDtls::GeneratorParameters
enum QDtls::HandshakeState
DTLSハンドシェイクの現在の状態を記述する。
この enum はQDtls 接続の DTLS ハンドシェイクの現在の状態を記述する。
定数 | 値 | 説明 |
---|---|---|
QDtls::HandshakeNotStarted | 0 | まだ何も行われていない。 |
QDtls::HandshakeInProgress | 1 | ハンドシェイクが開始され、今のところエラーは見つかっていない。 |
QDtls::PeerVerificationFailed | 2 | 相手の身元が確認できない。 |
QDtls::HandshakeComplete | 3 | ハンドシェイクが正常に完了し、暗号化された接続が確立された。 |
QDtls::doHandshake() およびQDtls::handshakeState()も参照 。
メンバー関数ドキュメント
[explicit]
QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)
QDtls オブジェクトを作成します。parent はQObject コンストラクタに渡されます。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 には、ハンドシェークフェーズで最終的にセッション暗号を選択する暗号の順序リストを設定する関数が用意されています。この順序付きリストは、ハンドシェークフェーズの開始前に設定されている必要がある。
QSslConfiguration 、setDtlsConfiguration()、dtlsConfiguration()も参照のこと 。
QSsl::SslProtocol QDtls::sessionProtocol() const
この接続で使用されている DTLS プロトコルのバージョンを返します。 接続がまだ暗号化されていない場合は UnknownProtocol を返します。接続のプロトコルはハンドシェーク時に選択されます。
setDtlsConfiguration() は、ハンドシェークが始まる前に優先バージョンを設定することができます。
setDtlsConfiguration()、QSslConfiguration 、QSslConfiguration::defaultDtlsConfiguration()、QSslConfiguration::setProtocol()も参照 。
bool QDtls::setCookieGeneratorParameters(const QDtls::GeneratorParameters ¶ms)
暗号化ハッシュアルゴリズムと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 によって発見される可能性のあるエラーを記述する。
この列挙型は、QDtlsClientVerifier とQDtls のクラスのオブジェクトが遭遇する可能性のある、一般的なエラーと TLS 固有のエラーを記述します。
定数 | 値 | 説明 |
---|---|---|
QDtls::QDtlsError::NoError | 0 | エラーは発生せず、最後の操作は成功した。 |
QDtls::QDtlsError::InvalidInputParameters | 1 | 呼び出し元が提供した入力パラメータが無効でした。 |
QDtls::QDtlsError::InvalidOperation | 2 | 操作が許可されていない状態で操作を試みた。 |
QDtls::QDtlsError::UnderlyingSocketError | 3 | QUdpSocket::writeDatagram()は失敗した。QUdpSocket::error()およびQUdpSocket::errorString()は、より具体的な情報を提供できる。 |
QDtls::QDtlsError::RemoteClosedConnectionError | 4 | TLSシャットダウン警告メッセージを受信した。 |
QDtls::QDtlsError::PeerVerificationError | 5 | TLSハンドシェイク中にピアの身元を確認できなかった。 |
QDtls::QDtlsError::TlsInitializationError | 6 | 基盤となるTLSバックエンドの初期化中にエラーが発生した。 |
QDtls::QDtlsError::TlsFatalError | 7 | TLSハンドシェイク中に致命的なエラーが発生した(ピア検証エラーまたはTLS初期化エラー以外)。 |
QDtls::QDtlsError::TlsNonFatalError | 8 | データグラムの暗号化または復号化に失敗した。致命的なエラーではないので、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.