Программирование openssl, Towellie, 14-Янв-09, 07:06 [смотреть все]Надо организовать клиент сервер с шифрованием средством openssl. server.c //---------------------------------------------------- #include <openssl/bio.h> #include <openssl/ssl.h> #include <openssl/err.h>#include <stdio.h> #include <string.h> main() { BIO *sbio, *bbio, *acpt, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); /* Might seed PRNG here */ ctx=SSL_CTX_new(SSLv23_server_method()); if(ctx == NULL) { printf("CTX is null\n"); return; } printf("After Cert Load\n"); if (!SSL_CTX_use_certificate_file(ctx,"certfiles/cacert.pem", SSL_FILETYPE_PEM) || SSL_CTX_use_PrivateKey_file(ctx,"certfiles/rsa_private_key.pem", SSL_FILETYPE_PEM) || SSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Error setting up SSL_CTX\n"); ERR_print_errors_fp(stderr); return 0; } printf("After Cert Load\n "); /* Might do other things here like setting verify locations and * DH and/or RSA temporary key callbacks */ /* New SSL BIO setup as server */ sbio=BIO_new_ssl(ctx,0); BIO_get_ssl(sbio, &ssl); if(!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); /* whatever ... */ } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* Create the buffering BIO */ bbio = BIO_new(BIO_f_buffer()); /* Add to chain */ sbio = BIO_push(bbio, sbio); acpt=BIO_new_accept("1332"); /* By doing this when a new connection is established * we automatically have sbio inserted into it. The * BIO chain is now 'swallowed' by the accept BIO and * will be freed when the accept BIO is freed. */ BIO_set_accept_bios(acpt,sbio); out = BIO_new_fp(stdout, BIO_NOCLOSE); /* Setup accept BIO */ if(BIO_do_accept(acpt) <= 0) { fprintf(stderr, "Error setting up accept BIO\n"); ERR_print_errors_fp(stderr); return 0; } /* Now wait for incoming connection */ if(BIO_do_accept(acpt) <= 0) { fprintf(stderr, "Error in connection\n"); ERR_print_errors_fp(stderr); return 0; } /* We only want one connection so remove and free * accept BIO */ sbio = BIO_pop(acpt); BIO_free_all(acpt); if(BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error in SSL handshake\n"); ERR_print_errors_fp(stderr); return 0; } BIO_puts(sbio, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n"); BIO_puts(sbio, "\r\nConnection Established\r\nRequest headers:\r\n"); BIO_puts(sbio, "--------------------------------------------------\r\n"); for(;;) { len = BIO_gets(sbio, tmpbuf, 1024); if(len <= 0) break; BIO_write(sbio, tmpbuf, len); BIO_write(out, tmpbuf, len); /* Look for blank line signifying end of headers*/ if((tmpbuf[0] == '\r') || (tmpbuf[0] == '\n')) break; } BIO_puts(sbio, "--------------------------------------------------\r\n"); BIO_puts(sbio, "\r\n"); /* Since there is a buffering BIO present we had better flush it */ BIO_flush(sbio); BIO_free_all(sbio); } //---------------------------------------------------- client.c //---------------------------------------------------- #include <openssl/bio.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <stdio.h> #include <string.h> main() { BIO *sbio, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); /* We would seed the PRNG here if the platform didn't * do it automatically */ ctx = SSL_CTX_new(SSLv23_client_method()); /* We'd normally set some stuff like the verify paths and * mode here because as things stand this will connect to * any server whose certificate is signed by any CA. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if(!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); /* whatever ... */ } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ BIO_set_conn_hostname(sbio, "localhost:1332"); out = BIO_new_fp(stdout, BIO_NOCLOSE); if(BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); /* whatever ... */ } if(BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); /* whatever ... */ } /* Could examine ssl here to get info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for(;;) { len = BIO_read(sbio, tmpbuf, 1024); if(len <= 0) break; BIO_write(out, tmpbuf, len); } BIO_free_all(sbio); BIO_free(out); } //---------------------------------------------------- Когда клиент коннектится сервер вылетает со следующим текстом: $ ./recv After Cert Load Enter PEM pass phrase: After Cert Load Error in SSL handshake 23749:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s3_srvr.c:974: А клиент с таким: $ ./send Error connecting to server 24080:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s23_clnt.c:562: Error establishing SSL connection 24080:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s23_clnt.c:562: Вот собственно и проблема. Заранее спасибо
|
- Программирование openssl, angra, 07:11 , 14-Янв-09 (1)
Студентам здесь не подают. Если уж стырил код, то напряги то, что замещает у тебя мозг, и почитай хотя бы лекции.
- граммиро вание, Andrey Mitrofanov, 08:57 , 14-Янв-09 (3)
>то напряги то, что замещает у тебя мозгОн и напрягает -- форум. %) >, и почитай хотя бы лекции. Осторожно, а то вдруг и это оно только ч/з форум умеет??! |))
- Программирование openssl, from_mars, 07:18 , 14-Янв-09 (2)
вот здесь ошибка:main() { BIO *sbio, *bbio, *acpt, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); /* Might seed PRNG here */ ctx=SSL_CTX_new(SSLv23_server_method()); if(ctx == NULL) { printf("CTX is null\n"); return; } printf("After Cert Load\n"); if (!SSL_CTX_use_certificate_file(ctx,"certfiles/cacert.pem", SSL_FILETYPE_PEM) || SSL_CTX_use_PrivateKey_file(ctx,"certfiles/rsa_private_key.pem", SSL_FILETYPE_PEM) || SSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Error setting up SSL_CTX\n"); ERR_print_errors_fp(stderr); return 0; } printf("After Cert Load\n "); /* Might do other things here like setting verify locations and * DH and/or RSA temporary key callbacks */ /* New SSL BIO setup as server */ sbio=BIO_new_ssl(ctx,0); BIO_get_ssl(sbio, &ssl); if(!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); /* whatever ... */ } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* Create the buffering BIO */ bbio = BIO_new(BIO_f_buffer()); /* Add to chain */ sbio = BIO_push(bbio, sbio); acpt=BIO_new_accept("1332"); /* By doing this when a new connection is established * we automatically have sbio inserted into it. The * BIO chain is now 'swallowed' by the accept BIO and * will be freed when the accept BIO is freed. */ BIO_set_accept_bios(acpt,sbio); out = BIO_new_fp(stdout, BIO_NOCLOSE); /* Setup accept BIO */ if(BIO_do_accept(acpt) <= 0) { fprintf(stderr, "Error setting up accept BIO\n"); ERR_print_errors_fp(stderr); return 0; } /* Now wait for incoming connection */ if(BIO_do_accept(acpt) <= 0) { fprintf(stderr, "Error in connection\n"); ERR_print_errors_fp(stderr); return 0; } /* We only want one connection so remove and free * accept BIO */ sbio = BIO_pop(acpt); BIO_free_all(acpt); if(BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error in SSL handshake\n"); ERR_print_errors_fp(stderr); return 0; } BIO_puts(sbio, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n"); BIO_puts(sbio, "\r\nConnection Established\r\nRequest headers:\r\n"); BIO_puts(sbio, "--------------------------------------------------\r\n"); for(;;) { len = BIO_gets(sbio, tmpbuf, 1024); if(len <= 0) break; BIO_write(sbio, tmpbuf, len); BIO_write(out, tmpbuf, len); /* Look for blank line signifying end of headers*/ if((tmpbuf[0] == '\r') || (tmpbuf[0] == '\n')) break; } BIO_puts(sbio, "--------------------------------------------------\r\n"); BIO_puts(sbio, "\r\n"); /* Since there is a buffering BIO present we had better flush it */ BIO_flush(sbio); BIO_free_all(sbio); } //---------------------------------------------------- client.c //---------------------------------------------------- #include <openssl/bio.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <stdio.h> #include <string.h> main() { BIO *sbio, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); /* We would seed the PRNG here if the platform didn't * do it automatically */ ctx = SSL_CTX_new(SSLv23_client_method()); /* We'd normally set some stuff like the verify paths and * mode here because as things stand this will connect to * any server whose certificate is signed by any CA. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if(!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); /* whatever ... */ } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ BIO_set_conn_hostname(sbio, "localhost:1332"); out = BIO_new_fp(stdout, BIO_NOCLOSE); if(BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); /* whatever ... */ } if(BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); /* whatever ... */ } /* Could examine ssl here to get info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for(;;) { len = BIO_read(sbio, tmpbuf, 1024); if(len <= 0) break; BIO_write(out, tmpbuf, len); } BIO_free_all(sbio); BIO_free(out); }
- Программирование openssl, Towellie, 15:03 , 14-Янв-09 (4)
Проблема преобразилась в другую server.c //------------- #include "stdio.h" #include "string.h"#include "openssl/bio.h" #include "openssl/ssl.h" #include "openssl/err.h" int password_callback(char *buf, int size, int rwflag, void *userdata) { /* For the purposes of this demonstration, the password is "ibmdw" */ printf("*** Callback function called\n"); strcpy(buf, "ibmdw"); return 1; } int main() { SSL_CTX *ctx; SSL *ssl; BIO *bio, *abio, *out, *sbio; char tmpbuf[1024]; int len; int (*callback)(char *, int, int, void *) = &password_callback; printf("Secure Programming with the OpenSSL API, Part 4:\n"); printf("Serving it up in a secure manner\n\n"); SSL_load_error_strings(); ERR_load_BIO_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); printf("Attempting to create SSL context... "); ctx = SSL_CTX_new(SSLv23_server_method()); if(ctx == NULL) { printf("Failed. Aborting.\n"); return 0; } printf("\nLoading certificates...\n"); SSL_CTX_set_default_passwd_cb(ctx, callback); if(!SSL_CTX_use_certificate_file(ctx, "certificate.pem", SSL_FILETYPE_PEM)) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } if(!SSL_CTX_use_PrivateKey_file(ctx, "private.key", SSL_FILETYPE_PEM)) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } printf("Attempting to create BIO object... "); bio = BIO_new_ssl(ctx, 0); if(bio == NULL) { printf("Failed. Aborting.\n"); ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } printf("\nAttempting to set up BIO for SSL...\n"); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); abio = BIO_new_accept("4422"); BIO_set_accept_bios(abio, bio); printf("Waiting for incoming connection...\n"); if(BIO_do_accept(abio) <= 0) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); BIO_free_all(bio); BIO_free_all(abio); return; } if(BIO_do_accept(abio) <= 0) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); BIO_free_all(bio); BIO_free_all(abio); return; } out = BIO_pop(abio); if(BIO_do_handshake(out) <= 0) { printf("Handshake failed.\n"); ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); BIO_free_all(bio); BIO_free_all(abio); return; } BIO_puts(out, "Hello\n"); //Read end for(;;) { len = BIO_read(sbio, tmpbuf, 1024); if(len <= 0) break; tmpbuf[len]='\0'; } printf("%s", tmpbuf); //Read end if(strcmp(tmpbuf,"Hello\n")==0) { printf("Hello received sending user request\n"); BIO_puts(out, "Hello\n"); } //---------- client.c //-------- #include "stdio.h" #include "string.h" #include "openssl/bio.h" #include "openssl/ssl.h" #include "openssl/err.h" int password_callback(char *buf, int size, int rwflag, void *userdata) { /* For the purposes of this demonstration, the password is "ibmdw" */ printf("*** Callback function called\n"); strcpy(buf, "ibmdw"); return 1; } int main() { SSL_CTX *ctx; SSL *ssl; BIO *bio, *abio, *out, *sbio; char tmpbuf[1024]; int len; int (*callback)(char *, int, int, void *) = &password_callback; printf("Secure Programming with the OpenSSL API, Part 4:\n"); printf("Serving it up in a secure manner\n\n"); SSL_load_error_strings(); ERR_load_BIO_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); printf("Attempting to create SSL context... "); ctx = SSL_CTX_new(SSLv23_server_method()); if(ctx == NULL) { printf("Failed. Aborting.\n"); return 0; } printf("\nLoading certificates...\n"); SSL_CTX_set_default_passwd_cb(ctx, callback); if(!SSL_CTX_use_certificate_file(ctx, "certificate.pem", SSL_FILETYPE_PEM)) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } if(!SSL_CTX_use_PrivateKey_file(ctx, "private.key", SSL_FILETYPE_PEM)) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } printf("Attempting to create BIO object... "); bio = BIO_new_ssl(ctx, 0); if(bio == NULL) { printf("Failed. Aborting.\n"); ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } printf("\nAttempting to set up BIO for SSL...\n"); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); abio = BIO_new_accept("4422"); BIO_set_accept_bios(abio, bio); printf("Waiting for incoming connection...\n"); if(BIO_do_accept(abio) <= 0) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); BIO_free_all(bio); BIO_free_all(abio); return; } if(BIO_do_accept(abio) <= 0) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); BIO_free_all(bio); BIO_free_all(abio); return; } out = BIO_pop(abio); if(BIO_do_handshake(out) <= 0) { printf("Handshake failed.\n"); ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); BIO_free_all(bio); BIO_free_all(abio); return; } BIO_puts(out, "Hello\n"); //Read end for(;;) { len = BIO_read(sbio, tmpbuf, 1024); if(len <= 0) break; tmpbuf[len]='\0'; } printf("%s", tmpbuf); //Read end if(strcmp(tmpbuf,"Hello\n")==0) { printf("Hello received sending user request\n"); BIO_puts(out, "Hello\n"); } //------- BIO_flush(out); BIO_free_all(out); BIO_free_all(bio); BIO_free_all(abio); SSL_CTX_free(ctx); } BIO_flush(out); BIO_free_all(out); BIO_free_all(bio); BIO_free_all(abio); SSL_CTX_free(ctx); } //------- Проблема в том что со стороны клиента Hello получается принять и опознать А со стороны сервера len = BIO_read(sbio, tmpbuf, 1024); возвращает ноль - тоесть на клиенте засовываю в out буфер а он не а на сервере он просто не приходит. Та конструкция которая в мануале вообще в буфер ничего не записывает ни на каких этапах вообще (( ни на сервере ни на клиенте. http://openssl.org/docs/crypto/BIO_read.html Вот описания функций - я не могу понять какие именно функции нужно использовать. (Сижу перевожу дальше)
- Программирование openssl, Towellie, 09:20 , 15-Янв-09 (5)
Вобщем судя по всему надо переделывать кусок кода для чтения //Read end for(;;) { len = BIO_read(sbio, tmpbuf, 1024); if(len <= 0) break; tmpbuf[len]='\0'; } printf("%s", tmpbuf); //Read end Если добавить //Read end for(;;) { len = BIO_read(sbio, tmpbuf, 1024); printf("%d <------ should\n", BIO_should_retry(sbio));<---- Это if(len <= 0) break; tmpbuf[len]='\0'; } printf("%s", tmpbuf); //Read end Возвращается 0 на обоих функциях(на сервере) For example if a call to BIO_read() on a socket BIO returns 0 and BIO_should_retry() is false then the cause will be that the connection closed. Значит соединение закрыто? Оно должно быть открыто может я как то не так использую BIO_should_retry()?
- Программирование openssl, Towellie, 10:04 , 15-Янв-09 (6)
>так использую BIO_should_retry()? Дело еще например в том что логично предположить, что при удачном приеме (Если len > 0) - (Это на клиенте где прием удается) то функция BIO_should_retry должна вернуть true(потому что соединение еще не закрыто) и ошибиться в том что это именно sbio(потому, что мы же все таки с него считываем) тоже сложно.(Хотя я пробовал и bio) один фиг возврящяется 0. :S
- Программирование openssl, Towellie, 12:41 , 15-Янв-09 (7)
Вобщем в итоге все упирается в то, что BIO_read на сервере возвращает -2 по документации If the return value is -2 then the operation is not implemented in the specific BIO type. И вот тут тупик. На клиенте функция отрабатывает.P.S. Если я опять по вашему мнению спираю всю мысленную работу на вас - вы хоть отпишите(Даже сообщения ты студент, ты пень, кури маны только приветвтвуются)
- Программирование openssl, NuINu, 16:34 , 15-Янв-09 (8)
>Вобщем в итоге все упирается в то, что BIO_read на сервере возвращает >-2 по документации If the return value is -2 then the >operation is not implemented in the specific BIO type. >И вот тут тупик. На клиенте функция отрабатывает. > >P.S. Если я опять по вашему мнению спираю всю мысленную работу на >вас - вы хоть отпишите(Даже сообщения ты студент, ты пень, кури >маны только приветвтвуются) почитай: http://www.linuxjournal.com/article/4822 http://www.linuxjournal.com/article/5487 на ibm.com есть 3 статьи по программированию.
- Программирование openssl, Towellie, 06:46 , 16-Янв-09 (9)
Спасибо за ответ - хороший материал. Прочитал первую статью с горем пополам(С английским все плохо) Интересно но много букв и другой подход нежели на ibm.com - (В том числе и то, что например в этих статьях они вообще не используют bio_read). Я их конечно дочитаю эти статьи чтобы понять в чем может быть проблема, но код я их использовать не буду. Тот код что выше это код взятый с openssl.org и исправленный немного(В первоначальном варианте он нерабочий) - сейчас уже почти все работает за исключением того что я не могу прочитать на сервере входящее сообщение. И проанализированный со статьями на ibm.com (Очень доступные статьи) я с этих статей стырил код чтения - записи - с анализом ошибки и с повтором. - В коде с openssl.org он прекрасно себя чувствует при передаче с сервера на клиент а наоборот - нет - такая же в общем история. //Write begin printf("Sending Hello server\n"); strcpy(tmpbuf, "Hello server\n"); for(;;) { if(BIO_write(out, tmpbuf, strlen(tmpbuf)) <= 0) { if(! BIO_should_retry(out)) { printf("Write is crashed\n"); return 0; } continue; } break; } // Write end //Read begin for(;;) { len = BIO_read(sbio, tmpbuf, sizeof(tmpbuf)); if(len == 0) { printf("Server is close connection\n"); return 0; } else if(len < 0) { if(! BIO_should_retry(sbio)) { printf("Read is crashed %d\n",len); return 0; } continue; } break; } printf("[%s] --- [%d] \n",tmpbuf, strlen(tmpbuf)); //Read end
- Программирование openssl, NuINu, 12:36 , 16-Янв-09 (10)
>Спасибо за ответ - хороший материал. >Прочитал первую статью с горем пополам(С английским все плохо) Интересно но много >букв и другой подход нежели на ibm.com - (В том числе >и то, что например в этих статьях они вообще не используют >bio_read). >Я их конечно дочитаю эти статьи чтобы понять в чем может быть >проблема, но код я их использовать не буду. Тот код что >выше это код взятый с openssl.org и исправленный немного(В первоначальном варианте >он нерабочий) - сейчас уже почти все работает за исключением того собственно не понятно как он у вас работает, потому как в вашем клиенте нет главного, а именно попытки соединиться с сервером.
- Программирование openssl, Towellie, 07:10 , 18-Янв-09 (11)
Прошу прощения я не правильно вставил код. Вобщем почитал я тут поэксперементировал немного - некоторые вещи прояснились переделал код - в общем я в обе стороны могу передавать, но возникла следующая трудность: Код подкючения и тд и тп я писать не буду - он рабочий осталость только понять как работают BIO_read + BIO_write вобщем Идея следующая - код записи и чтения везде одинаковый на одной стороне считать а потом записать а на втором конце соответственно наоборот. Получается следующая картина: ./send Sending Hello server End writing lets reading Before read./recv Before read Это означает то, что функция write отработала программа пошла дальше читать, а на другом конце read не получила ничего. - Но прикол в следующем если убрать код чтения из send. - Он будет отмечен внизу, read получит свой Hello server. $./recv Before read [13]<----- [Hello client ] --- [13] End reading lets writing Sending Hello server End writing $ ./send Sending Hello server End writing lets reading - И еще один момент - read отрабатывает после sleep на send. Это блин почему так может получиться? Складыавется такое чувство что данные передаются когда соединение завершается. - Странно не правда ли? Код на одном конце:(recv.c) //Read begin for(;;) { printf("Before read\n"); len = BIO_read(sbio, tmpbuf, sizeof(tmpbuf)); printf("[%d]<-----\n",len); if(len == 0) { printf("Server is close connection\n"); return 0; } else if(len < 0) { if(! BIO_should_retry(sbio)) { printf("Read is crashed %d\n",len); return 0; } continue; } tmpbuf[len]=0; break; } printf("[%s] --- [%d] \n",tmpbuf, strlen(tmpbuf)); //Read end printf("End reading\n"); BIO_flush(sbio); sleep(5); printf("lets writing\n"); //Write begin printf("Sending Hello server\n"); strcpy(tmpbuf, "Hello client\n"); for(;;) { if(BIO_write(sbio, tmpbuf, strlen(tmpbuf)) <= 0) { if(! BIO_should_retry(sbio)) { printf("Write is crashed\n"); return 0; } continue; } break; } // Write end printf("End writing\n"); ___________________________А вот на другом__________________________________________(send.c)
//Write begin printf("Sending Hello server\n"); strcpy(tmpbuf, "Hello client\n"); for(;;) { if(BIO_write(sbio, tmpbuf, strlen(tmpbuf)) <= 0) { if(! BIO_should_retry(sbio)) { printf("Write is crashed\n"); return 0; } continue; } break; } // Write end printf("End writing\n"); sleep(5); printf("lets reading\n"); //Read begin <----------------------- for(;;) { printf("Before read\n"); len = BIO_read(sbio, tmpbuf, sizeof(tmpbuf)); printf("[%d]<-----\n",len); if(len == 0) { printf("Server is close connection\n"); return 0; } else if(len < 0) { if(! BIO_should_retry(sbio)) { printf("Read is crashed %d\n",len); return 0; } continue; } tmpbuf[len]=0; break; } printf("[%s] --- [%d] \n",tmpbuf, strlen(tmpbuf)); //Read end printf("End reading\n"); BIO_flush(sbio);<--------------------------------------
- Программирование openssl, Towellie, 07:35 , 19-Янв-09 (12)
Ну вот я уже можно сказать скурил все маны оказалось что int BIO_read(BIO *b, void *buf, int len); Пытается прочесть из объекта b len байт данных в буфер buf. Возвращает количество прочитанных байт. - И будет пытаться пока соединение не завершится(Поэтому данные передавались в конце соединения - соединение рвется BIO_read выходит из цикла и показывает что получла) в отличие от int BIO_gets(BIO *b, char *buf, int size); Для большинства типов BIO выполняет операцию, аналогичную fgets — читает из b в buf до ближайшего конца строки, но не более size байт. Тоесть функция read ждет а gets не ждет. - Поскольку я не знаю сколько мне должно придти (параметр len мне узнать не откуда) функция gets выглядит более предпочтительно - НО! Функция BIO_set_conn_hostname которая определяет объект ввода вывода не поддерживает BIO_gets Connect BIOs support BIO_puts() but not BIO_gets(). Как мне быть? Куда смотреть теперь?
- Программирование openssl, angra, 08:17 , 19-Янв-09 (13)
Много несколько вариантов. 1. изменить свой протокол добавив туда посылку размера сообщения 2. использовать буферизованный ввод при помощи BIO_f_buffer 3. использовать nonblocking io на основе select в комбинации с BIO_should_retry
|