The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Программирование 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)
    Студентам здесь не подают. Если уж стырил код, то напряги то, что замещает у тебя мозг, и почитай хотя бы лекции.
  • Программирование 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



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру