Qt 5.8 Сбой рукопожатия Apple Notification Server

Я попробовал это сейчас, но я не смог заставить его работать. Я хочу отправить некоторые уведомления из приложения Qt. Попытался заставить его работать на macOS Sierra с установкой Qt 5.8 и на Pi3 также с Qt 5.8.

Я создал свой push-сертификат с помощью "fastlane pem" и протестировал его с помощью "Pusher", и он работает правильно. Но я не могу заставить его работать в Qt....

Сначала код, который я использую для инициализации и подключения QSslSocket:

QSslSocket * ssl = new QSslSocket;

connect(ssl, &QSslSocket::encrypted, this, &IOSPusher::encrypted );
connect(ssl, static_cast<void(QSslSocket::*)(const QList<QSslError> &)>(&QSslSocket::sslErrors),this,&IOSPusher::sslErrors);
connect(ssl, static_cast<void(QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error),this, &IOSPusher::error );
connect(ssl,&QSslSocket::stateChanged,this,&IOSPusher::stateChanged );

Загрузка сертификата

QString path = QStandardPaths::writableLocation(certificateLocation) + "/apns.pem";

const auto certs =  QSslCertificate::fromPath(path);

if(certs.count() > 0){
    qDebug() << "IOSPusher: Certificate loaded successfully";
}else{
    qDebug() << "Could not load certificate : " + path;
}

QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setCaCertificates(certs);

ssl->setSslConfiguration(config);
ssl->connectToHostEncrypted( gateway.sandbox.push.apple.com,2195 );

И вот результат, который я получаю:

IOSPusher: Certificate loaded successfully
IOSPusher::stateChanged  QAbstractSocket::HostLookupState
IOSPusher::stateChanged  QAbstractSocket::ConnectingState
IOSPusher::stateChanged  QAbstractSocket::ConnectedState
IOSPusher::error  QAbstractSocket::SocketError(13)
IOSPusher::stateChanged  QAbstractSocket::ClosingState
IOSPusher::stateChanged  QAbstractSocket::UnconnectedState

Итак, согласно документации Qt ошибка:

QAbstractSocket:: SocketError (13)

означает следующее:

SslHandshakeFailedError

А также

> Сбой квитирования SSL/TLS, и зашифрованный канал не может быть установлен. Сигнал sslErrors() должен был быть отправлен.

Но sslErrors()сигнал не будет излучаться в моем случае....

Сбой рукопожатия SSL/TLS, поэтому соединение было закрыто (используется только в QSslSocket)

Любые идеи или образцы, как я могу установить зашифрованное соединение с Apple?

Заранее спасибо!

1 ответ

Решение

Хорошо, как часто, когда я пытаюсь получить помощь от кого-то, я получил это сейчас:D

Решение, которое работало для меня сейчас:

Создать *.pem удостоверяю с fastlane pem с паролем (возможно, он работает и без пароля, но это было последнее, что я попробовал сейчас и.... никогда не меняйте работающую систему, ха-ха)

 fastlane pem --development -p <private_key_password> -a <your_app_identifier>

Затем для соединения с QSslSocket сделайте следующее... как и раньше в моем вопросе...

QSslSocket * ssl = new QSslSocket;
QString path = QStandardPaths::writableLocation(certificateLocation) + "/apns.pem";

connect(ssl, &QSslSocket::encrypted, this, &IOSPusher::encrypted );
connect(ssl, static_cast<void(QSslSocket::*)(const QList<QSslError> &)>(&QSslSocket::sslErrors),this,&IOSPusher::sslErrors);
connect(ssl, static_cast<void(QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error),this, &IOSPusher::error );
connect(ssl,&QSslSocket::stateChanged,this,&IOSPusher::stateChanged );

QSslCertificate cert;
const auto certs =  QSslCertificate::fromPath(path);

if(certs.count() > 0){
    cert = certs.at(0);
    qDebug() << "IOSPusher: Certificate loaded successfully";
}else{
    qDebug() << "Could not load certificate : " + path;
    return false;
}

Теперь вот волшебство, что это сделало для меня

Используйте файл private_key (.pkey), который также будет создан с fastlane pem

//Use the path to the .pkey file from fastlane
QFile keyfile(path + "/apns.pkey");
keyfile.open(QFile::ReadOnly);

//Create the QSslKey as private key
QSslKey privateKey(&keyfile,QSsl::Rsa,QSsl::Pem,QSsl::PrivateKey,QByteArray("<private_key_password_from_fastlane>"));
//Close the file
keyfile.close();

И добавьте закрытый ключ и сертификат в конфигурацию ssl

QSslConfiguration config = QSslConfiguration::defaultConfiguration();

config.setLocalCertificate(cert);
config.setPrivateKey(privateKey);

как вы можете видеть здесь на этот раз я не использую config.setCaCertificates метод, но вместо config.setLocalCertificate метод. Это была ошибка на моей стороне...

По крайней мере, добавьте конфиг в сокет ssl и ПОЖАР!

ssl->setSslConfiguration(config);
ssl->connectToHostEncrypted( "gateway.sandbox.push.apple.com",2195 );

Это все

Теперь encrypted() сигнал испускается! Да уж..

Другие вопросы по тегам