私はDragino Yunでopenwrtを実行しています。私の願いはDragino上でいくつかの(それほど大量ではない)データを転送するために使用されるopensslサーバーを実行することです。ただし、サーバーを起動して証明書をロードした後、BIO_do_accept()
の呼び出しは値< = 0を返し、バインドに失敗したことを示します。私がバインドしようとしているポートは5354ですが、8081、8080、443でも試しました。OpenSSL openwrt failedソケットバインド
私はERR_print_errors_fp
から取得するエラーメッセージは次のとおりです。
1998677064:error:0200407C:lib(2):func(4):reason(124):NA:0:port='5354'
1998677064:error:20069076:lib(32):func(105):reason(118):NA:0:
私のプログラムが結合することができない理由を誰もが説明してもらえますか? OpenSSLバージョンOpenSSL 1.0.1f 6 Jan 2014
と、DraginoのOpenSSLバージョンは、OpenSSL 1.0.1h 5 Jun 2014
です。私はUbuntuでテストしました。これは私がコードを投稿していない理由です(クロスコンパイルされたバージョンの問題です)。 はまた、(バナーから)Draginoバージョンは、私はs_serverを使用しようとしたDragino-v2 common-2.0.5
であり、結果は以下の通りである:s_clientが使用される場合、いくつかの通信を生じ、
[email protected]:~/certificates# openssl s_server -key server.key.pem -cert server.cert.pem -accept 8081
Enter pass phrase for server.key.pem:
Using default temp DH parameters
ACCEPT
は、このようにソケット結合がOKでした。
問題は何ですか?この問題を正しく解決するにはどうすればよいですか。 私はグーグルでエラーメッセージを見ましたが、役に立たなかった。
また、私は、iptablesをINPUT、FORWARD、OUTPUTチェーンに対してACCEPTデフォルトポリシーに変更しました。
EDIT:コードを追加しています。
COMMON.H:
#define PORT "5354"
#define SERVER "localhost"
#define CLIENT "localhost"
#define CIPHER_LIST "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
#define SSL_METHOD_ SSLv23_method()
#define SEED_PRNG_() seed_prng(30)
#define SSL_CTX_FLAGS_ SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
#define DEFAULT_DEPTH_ 4
#define DATA_SIZE_ 256
void init_OpenSSL(void) ;
int seed_prng(int bytes) ;
int verify_callback(int ok, X509_STORE_CTX *store) ;
int write_to_SSL(SSL *ssl, const char* msg, int length) ;
int read_from_SSL(SSL *ssl, char* msg, int length) ;
common.c:
#include "common.h"
void init_OpenSSL(void)
{
if (!SSL_library_init())
{
fprintf(stderr, "** OpenSSL initialization failed!\n");
exit(-1);
}
//Loads error strings for various SSL functions
SSL_load_error_strings();
}
//Not sure if this is good idea
int seed_prng(int bytes)
{
//Seeds PRNG (pseudo random number generator) with the contents of the /dev/urandom file
if (!RAND_load_file("/dev/urandom", bytes))
{
return 0;
}
return 1;
}
int verify_callback(int ok, X509_STORE_CTX *store)
{
char data[DATA_SIZE_];
if (!ok)
{
X509 *cert = X509_STORE_CTX_get_current_cert(store);
int depth = X509_STORE_CTX_get_error_depth(store);
int err = X509_STORE_CTX_get_error(store);
fprintf(stderr, "-Error with certificate at depth: %i\n", depth);
X509_NAME_oneline(X509_get_issuer_name(cert), data, DATA_SIZE_);
fprintf(stderr, " issuer = %s\n", data);
X509_NAME_oneline(X509_get_subject_name(cert), data, DATA_SIZE_);
fprintf(stderr, " subject = %s\n", data);
fprintf(stderr, " err %i:%s\n", err,
X509_verify_cert_error_string(err));
}
return ok;
}
int write_to_SSL(SSL *ssl, const char* msg, int length)
{
int writtenbytes = 0;
int err = 0;
while(err >= 0 && writtenbytes < length)
{
err = SSL_write(ssl, msg + writtenbytes, length - writtenbytes);
if(err < 0)
{
return err;
}
else
{
writtenbytes += err;
}
}
return writtenbytes ;
}
int read_from_SSL(SSL *ssl, char* msg, int length)
{
int err = 0, readbytes = 0;
while(err > 0 && readbytes < length)
{
err = SSL_read(ssl, msg + readbytes, length - readbytes);
if(err < 0)
{
return err;
}
else
{
readbytes += err ;
}
}
return readbytes;
}
server.h:
#include "common.h"
//If the key and the certificate are in the same file, these two can be the same
#define CERTFILE "/root/certificates/server.cert.pem"
#define KEYFILE "/root/certificates/server.key.pem"
//One of the two values below can be NULL but not both
#define CAFILE "/root/certificates/ca-chain.cert.pem"
#define CADIR NULL
SSL_CTX *ctx = NULL;
BIO *acc = NULL;
void cleanup_(void) ;
//Does the setup of the server (loading SSL libraries, loading certificates, etc)
SSL_CTX *setup_server_ctx_(void) ;
//Exchange of data with the clien
int exchange_data_(SSL *ssl) ;
//Does the whole communication once the connection is established
void communicate_(SSL *ssl) ;
//Waits for clients, establishes the connection and then proceeds to
//call communicate_()
void run_server_(void) ;
server.c:
#include "server.h"
#include "logger.h"
#include <sys/time.h>
SSL_CTX *setup_server_ctx_(void)
{
SSL_CTX *ctx;
init_OpenSSL();
//This is my function, gotta investigate it and see what should be there (maybe I got it right?)
SEED_PRNG_();
// This specifies that either SSL or TLS can be used
// Later, we will "filter" out SSLv2
ctx = SSL_CTX_new(SSL_METHOD_);
// NULL return value indicates a failure in creation of SSL_CTX object
if(ctx == NULL)
{
int_error("Setup error: The creation of a new SSL_CTX object failed.");
}
SSL_CTX_set_options(ctx, SSL_CTX_FLAGS_);
// These two functions are used to load trusted CAs
if (SSL_CTX_load_verify_locations(ctx, CAFILE, CADIR) != 1)
{
int_error("Setup error: Error loading CA file and/or directory");
}
if (SSL_CTX_set_default_verify_paths(ctx) != 1)
{
int_error("Setup error: Error loading default CA file and/or directory");
}
// This loads a certificate from a file
if (SSL_CTX_use_certificate_chain_file(ctx, CERTFILE) != 1)
{
int_error("Setup error: Error loading certificate from file");
}
// This loads a private key (can be the same file as certificate)
if (SSL_CTX_use_PrivateKey_file(ctx, KEYFILE, SSL_FILETYPE_PEM) != 1)
{
int_error("Setup error: Error loading private key from file");
}
if (SSL_CTX_set_cipher_list(ctx, CIPHER_LIST) != 1)
{
int_error("Error setting cipher list (no valid ciphers)");
}
// Setting the verify options for ctx context
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
// Setting the maximum allowed depth for CA verification
SSL_CTX_set_verify_depth(ctx, DEFAULT_DEPTH_);
return ctx;
}
int exchange_data_(SSL *ssl)
{
int err;
err = write_to_SSL(ssl, "Hello, client!", strlen("Hello, client!"));
if (err <= 0)
{
printf("An unsuccessful write!");
}
else
{
printf("Sent %d bytes.\n", err);
}
// SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN != 0 indicate that the shutdown notification
// was sent from the peer (in this case, the client)
//close(uart_fd);
return (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) ? 1 : 0;
}
void communicate_(SSL *ssl)
{
long err;
struct timeval tval_before, tval_after, tval_result;
//accepting connection from ssl object (structure)
if (SSL_accept(ssl) <= 0)
{
int_error("Error accepting SSL connection");
}
fprintf(stderr, "SSL Connection opened\n");
if (exchange_data_(ssl))
{
SSL_shutdown(ssl);
}
else
{
SSL_clear(ssl);
}
fprintf(stderr, "SSL Connection closed\n");
SSL_free(ssl);
}
void run_server_(void)
{
BIO *client;
SSL *ssl;
//This call does the setup of the server context (see the function for more info)
ctx = setup_server_ctx_();
// Creates BIO and sets the accept port
acc = BIO_new_accept(PORT);
BIO_set_bind_mode(acc, BIO_BIND_REUSEADDR_IF_UNUSED);
if (!acc)
{
int_error("Error creating server socket");
}
//The first call to BIO_do_accept() binds to the given port
if (BIO_do_accept(acc) <= 0)
{
int_error("Error binding server socket");
}
for (;;)
{
//The second BIO_do_accept() call listens on the acc BIO
if (BIO_do_accept(acc) <= 0)
{
int_error("Error accepting connection from client");
}
client = BIO_pop(acc);
if (!(ssl = SSL_new(ctx)))
{
int_error("Error creating SSL context");
}
SSL_set_bio(ssl, client, client);
communicate_(ssl);
}
}
int main(int argc, char *argv[])
{
run_server_();
return 1;
}
注:コードは主に、O'Reillyの著書「Network Security with OpenSSL」から取られています。 また、これは私が持っているコード全体ではありませんが、OpenSSLに関連するコード全体ですので、関連する他のコードとはみなされませんでした。 コピー/ペーストのためにコードに誤りがある可能性があります。
* *「私のプログラムが結合することができない理由を誰も説明してもらえますか?」 - いいえ、あなたは、関連するソースコードを提供していないので。この時点で***あなたの質問を***編集し、関連するソースコードを追加する必要があります。関連するパラメータ(接続の盗聴やサーバーのURLなど)を含めます。 – jww
私が書いたように私は実際にUbuntuでコードをテストしました。しかし、大丈夫、私は編集でいくつかのコードを投稿します。 – NMilev
元の投稿を編集しました。 @jww – NMilev