2016-05-02 16 views
0

に私は(Cで)libmosquittoを使用してSSL/TLSでのMQTTブローカーに接続しようとしています。コマンドラインでmosquitto_sub(またはmosquitto_pub)を使用し、私のコードで使用しているのと同じ証明書を使用して、ボーカーに正常に接続しているので、サーバー側で作業していると確信しています。私は私のCプログラムを使用して接続しようとするとmosquittoおよびSSL/TLSはC

、私はいつも次のエラーを取得:「エラー:TLSコンテキストを作成することができませんが」

私は、Linux上でlibmosquitto 1.4.8を使用しています。私が使用しているコードは次のとおりです。

#include <mosquitto.h> 

static struct SomeStruct *data = NULL; 
// The variable mosq is included in the struct 
// The struct has been created somewhere else 

void foo(void) 
{ 
    // I usually check the return values but removed 
    // it to make the code easier to read 
    mosquitto_lib_init(); 
    data->mosq = mosquitto_new("foobar", true, data); 

    // Connect the callbacks 

    mosquitto_username_pw_set(data->mosq, "user", "pass"); 
    mosquitto_tls_set(data->mosq, "/path/to/ca/file.crt, 
         NULL, NULL, NULL, NULL); 
    mosquitto_tls_insecure_set(data->mosq, 1) 
    mosquitto_tls_opts_set(data->mosq, 
          1, // also tried 0 
          NULL, // also tried "tlsv1.2" 
          NULL); 

    // All the return values are correct up to here 

    mosquitto_connect(data->mosq, "mqtt.example.com", 8883, 30); // Fails 
    // Logs : Error: Unable to create TLS context. 
    // A TLS error occurred. 
} 

誰でも問題が分かるでしょうか?

乾杯、

アントワーヌ

編集:私は私は私は1つを持っていると私はスレッドの非常に限られた数を持っている必要があり、既に使用別のライブラリbeacause mosquittoのメインループを使用していないことを追加するのを忘れ。したがって、ファイル記述子が変更されるたびにmosquitto_loop()と呼びます。 SSL_CTX_new()が失敗した場合

+0

'mqtt.example.com'のような偽のデータではなく、サーバー名のような実際のデータが必要です。 – jww

+0

サーバ名が私が抱えている問題にどのように関連しているのかわかりません - できるだけコードを単純化しようとしましたが、モスキートリブへのすべての呼び出しはここにあります – Antoine

答えて

0

この問題が発生する可能性があります。これは、mosquitto_subが同じマシン上でうまく動作するとは思われません。 tls_opts_setの他のオプションとして "tlsv1"、 "tlsv1.1"を試してください。また、OpenSSLが不幸である理由についての詳細情報を取得するためにmosquittoクライアントライブラリにパッチを適用しようとすることができます

diff --git a/lib/net_mosq.c b/lib/net_mosq.c 
index 08f24d9..d4c57fd 100644 
--- a/lib/net_mosq.c 
+++ b/lib/net_mosq.c 
@@ -409,6 +409,8 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t 
#ifdef WITH_TLS 
     int ret; 
     BIO *bio; 
+  int e; 
+  char ebuf[256]; 
#endif 

     if(!mosq || !host || !port) return MOSQ_ERR_INVAL; 
@@ -441,6 +443,11 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t 
#endif 
       if(!mosq->ssl_ctx){ 
         _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); 
+      e = ERR_get_error(); 
+      while(e){ 
+        _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "OpenSSL Error: %s", ERR_error_string(e, ebuf)); 
+        e = ERR_get_error(); 
+      } 
         COMPAT_CLOSE(sock); 
         return MOSQ_ERR_TLS; 
       } 

問題を再現するサンプルコード:

#include <stdio.h> 

#include <mosquitto.h> 

void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str) 
{ 
    printf("LOG: %s\n", str); 
} 


int main(int argc, char *argv[]) 
{ 
    struct mosquitto *mosq = NULL; 
    int rc; 

    printf("Calling connect before lib init, this should fail.\n"); 
    mosq = mosquitto_new(NULL, true, NULL); 
    mosquitto_log_callback_set(mosq, my_log_callback); 
    mosquitto_tls_set(mosq, "mosquitto.org.crt", NULL, NULL, NULL, NULL); 
    rc = mosquitto_connect(mosq, "test.mosquitto.org", 8883, 60); 
    printf("connect returned %d\n", rc); 
    mosquitto_destroy(mosq); 


    mosquitto_lib_init(); 


    printf("Calling connect after lib init, this should be fine.\n"); 
    mosq = mosquitto_new(NULL, true, NULL); 
    mosquitto_log_callback_set(mosq, my_log_callback); 
    mosquitto_tls_set(mosq, "mosquitto.org.crt", NULL, NULL, NULL, NULL); 
    rc = mosquitto_connect(mosq, "test.mosquitto.org", 8883, 60); 
    printf("connect returned %d\n", rc); 
    mosquitto_destroy(mosq); 


    mosquitto_lib_cleanup(); 


    printf("Calling connect after lib cleanup, this should fail.\n"); 
    mosq = mosquitto_new(NULL, true, NULL); 
    mosquitto_log_callback_set(mosq, my_log_callback); 
    mosquitto_tls_set(mosq, "mosquitto.org.crt", NULL, NULL, NULL, NULL); 
    rc = mosquitto_connect(mosq, "test.mosquitto.org", 8883, 60); 
    printf("connect returned %d\n", rc); 
    mosquitto_destroy(mosq); 

    return 0; 
} 

これは出力を生成します。

Calling connect before lib init, this should fail. 
LOG: Error: Unable to create TLS context. 
LOG: OpenSSL Error: error:140A90A1:lib(20):func(169):reason(161) 
connect returned 8 
Calling connect after lib init, this should be fine. 
LOG: Client mosq/7v?>[email protected]\U=;sO] sending CONNECT 
connect returned 0 
Calling connect after lib cleanup, this should fail. 
LOG: Error: Unable to create TLS context. 
LOG: OpenSSL Error: error:140A90F1:lib(20):func(169):reason(241) 
connect returned 8 

最終OpenSSLのエラーはあなたと同じであるので、あなたは、あなたがdeinitialiseてきたかどうかを確認する必要がありますd openssl。これはmosquitto_lib_cleanup()のようなものですが、あなたのコードがlibmosquittoとは完全に独立しています。

+0

私は異なったバージョンのtls常に同じ問題があります。モスキートとTLSに関する既知の問題はありませんか?あなたが送ったパッチをお試しいただきます。ありがとうございます。 – Antoine

+0

あなたが提供したパッチでは、 'OpenSSL Error:140A90F1:lib(20):func(169):reason(241)' – Antoine

+0

という出力が表示されます。 'mosquitto_lib_init()または 'mosquitto_lib_cleanup()'を呼び出すことによってopensslライブラリが初期化されていないことを確認してください。 – ralight

関連する問題