SSL_read在第一次读取时返回-1

时间:2015-12-14 12:16:34

标签: c++ ssl openssl client

问题:当我第一次调用bytes = SSL_read(ssl, buf, sizeof(buf));时,它总是返回-1,但是下一次调用会返回标题等。 你能帮我找一下我的错误吗?

  1. 我创建了SSL对象
  2. 致电请求
  3. 示例请求:

    POST /some/page HTTP/1.1
    Connection: keep-alive
    Content-Type: text/html;charset=UTF-8
    Host: example.com
    Content-Length: 123 (just for ex.)
    
    <mytag /> <mysecondtag />
    

    创建SSL对象

      SSLConnection::SSLConnection(string _server, int _port)
    {
      int err = 0;
      struct sockaddr_in address;
      X509* scert;
      char* txt;
      char buff[4096];
      SSL_METHOD *meth;
      WORD wVersionRequested;
      WSADATA wsaData;
      SSLeay_add_ssl_algorithms();
      meth = SSLv23_method();
      SSL_load_error_strings();
      ctx = SSL_CTX_new(meth);
    
      printf("ctx created\n");
    
      if (ctx == NULL) {
        bad_ = true;
        error_message_ = L"Context is NULL";
        return;
      }
      if (err == -1) {
        ERR_print_errors_fp(stdout);
        bad_ = true;
        return;
      }
    
      // Socket initialization and connection to the server.
      wVersionRequested = MAKEWORD(1, 1);
      err = WSAStartup(wVersionRequested, &wsaData);
      if (err != 0)
      {
        error_message_ = wprintf_s(L"///eRROR EN WSASstartup//%d\n", err);
        bad_ = true;
        return;
      }
    
      sd = socket(AF_INET, SOCK_STREAM, 0);
      if (sd == -1) {
        bad_ = true;
        error_message_ = L"Socket not initialized";
        return;
      }
    
      memset(&address, '\0', sizeof(address));
      address.sin_family = AF_INET;
      address.sin_addr.s_addr = inet_addr(_server.c_str());
      address.sin_port = htons(_port);
      address.sin_addr.S_un.S_addr = inet_addr(_server.c_str());
    
      err = connect(sd, (struct sockaddr*) &address, sizeof(address));
      if (err == -1) {
        bad_ = true;
        error_message_ = L"Connection not created";
        return;
      }
    
      // We started the SSL negotiation
      ssl = SSL_new(ctx);
      if (ssl == NULL) {
        bad_ = true;
        error_message_ = L"SSL not created";
        return;
      }
      SSL_set_fd(ssl, sd);
    
    
    
      // Setting client certificate and key
      int res = 0;
      res = SSL_use_certificate_file(ssl, "path1", SSL_FILETYPE_PEM);
      printf("Cert assigned: %d\n", res);
      if (res <= 0) {
        ERR_print_errors_fp(stdout);
        bad_ = true;
        return;
      }
      res = SSL_use_PrivateKey_file(ssl, "path2", SSL_FILETYPE_PEM);
      printf("Key assigned: %d\n", res);
      if (res <= 0) {
        ERR_print_errors_fp(stdout);
        bad_ = true;
        return;
      }
      err = SSL_connect(ssl);
      if (err == -1) {
        ERR_print_errors_fp(stdout);
        bad_ = true;
        return;
      } else printf("SSL Connection established\n");
    
      if (!SSL_CTX_check_private_key(ctx)) {
        printf("private key is not valid\r");
      }
    
      /* The next two steps are optional */
    
      /* We get the cipher - optional */
      // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
      printf("SSL connection using %s\n", SSL_get_cipher(ssl));
      cipher = SSL_get_cipher(ssl);
    
      /* We get the Server certificate - optional */
      scert = SSL_get_peer_certificate(ssl);
      CHK_NULL(scert);
    
      txt = X509_NAME_oneline(X509_get_subject_name(scert), 0, 0);
      CHK_NULL(txt);
      cert_subject = txt;
      OPENSSL_free(txt);
    
      txt = X509_NAME_oneline(X509_get_issuer_name(scert), 0, 0);
      CHK_NULL(txt);
      cert_issuer = txt;
      OPENSSL_free(txt);
    
      X509_free(scert);
    }
    

    请求方法

    int SSLConnection::request(const char *_request, 
                           map<char *, char *> &_response_headers,
                           string &_response_body) {
        if (bad_) { 
          bad_ = true;
          error_message_ = L"There is no connection"; 
          return -2; 
        }
    
        // Sending request
        printf("Sending request\n");
        char buf[100000];
        int bytes;
        string _tmp_response;
        SSL_write(ssl, _request, strlen(_request));
    
        // Reading response
        printf("Reading response\n");
        int response_size = 0;
        bool flag = 0;
        int error_count = 0;
        while (true) {
          Sleep(1000);
          bytes = SSL_read(ssl, buf, sizeof(buf));
          printf("Bytes: %d\n", bytes);
          if (bytes < 0) {
            error_count++;
            if (error_count > 3) {
              bad_ = true;
              error_message_ = L"SSL_read: something went wrong!";
              printf("SSL_read: something went wrong!\n");
              return -1;
            }
          }
          if (bytes == 0) break;
          printf("--------- Response (%d)---------\n", bytes);
          for (int i = 0; i<bytes; ++i) printf("%c", buf[i]);
          printf("\n--------- End response ---------\n");
          //if (!flag) flag = 1;
          //else {
            for (int i = 0; i<bytes; ++i)
              _tmp_response += buf[i];
            response_size += bytes;
          //}
          buf[0] = 0;
        }
        _tmp_response.resize(response_size);
    
        closesocket(sd);
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        return 1;
      }
    

0 个答案:

没有答案