title: TLS server doesn't receive certificate from client, fails to terminate handshake
body: <p>I have a client and a server attempting to mutually authenticate one another and initiate a TLS connection. The certificates I'm using right now are self-signed.</p>
  
  <p>In the server code I have <code>SSL_VERIFY_FAIL_IF_NO_PEER_CERT</code> set. The handshake succeeds, but <code>SSL_get_peer_certificate</code> returns a NULL pointer on the server side. If the client didn't return a certificate, why did the handshake not fail?</p>
  
  <p>If I comment out the <code>SSL_get_peer_certificate</code> check on the server side, the client and server do connect and are able to communicate, but it isn't a TLS connection. When I watch them exchange packets over wireshark, I only see TCP traffic.</p>
  
  <p>Server code:</p>
  
  <pre><code>BIO *acceptTLSConnection(char *port) {
  
    BIO *sbio, *bbio, *acpt = NULL;
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
  
    SSL_library_init();
  
    ctx = SSL_CTX_new(TLSv1_server_method());
  
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
  
    if(!SSL_CTX_use_certificate_file(ctx,"servercert.pem",SSL_FILETYPE_PEM)
      || !SSL_CTX_use_PrivateKey_file(ctx,"serverkey.pem",SSL_FILETYPE_PEM)
      || !SSL_CTX_check_private_key(ctx)) {
      ERR_print_errors_fp(stderr);
      fatalError("Error setting up SSL_CTX.");
    }
  
    if(!SSL_CTX_load_verify_locations(ctx, "clientcert.pem", NULL))
      fatalError("Could not load trusted CA certificates.");
  
    sbio=BIO_new_ssl(ctx,0);
  
    BIO_get_ssl(sbio, &amp;ssl);
  
    if(!ssl) {
      fatalError("Can't locate BIO SSL pointer.");
    }
  
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
  
    bbio = BIO_new(BIO_f_buffer());
    sbio = BIO_push(bbio, sbio);
  
    acpt=BIO_new_accept(port);
    BIO_set_accept_bios(acpt,sbio);
  
    /* Setup accept BIO */
    if(BIO_do_accept(acpt) &lt;= 0) {
      ERR_print_errors_fp(stderr);
      fatalError("Error in setting up accept BIO");
    }
  
    /* Now wait for incoming connection */
    if(BIO_do_accept(acpt) &lt;= 0) {
      ERR_print_errors_fp(stderr);
      fatalError("Error in connection");
    }
  
    sbio = BIO_pop(acpt);
    BIO_free_all(acpt);
  
    if(BIO_do_handshake(sbio) &lt;= 0) {
      ERR_print_errors_fp(stderr);
      fatalError("Error in SSL handshake");
    }
  
    /* Verify a client certificate was presented during the negotiation */
    X509* cert = SSL_get_peer_certificate(ssl);
    if(cert) { X509_free(cert); } /* Free immediately */
    if(NULL == cert) fatalError("Client did not present a cert during handshake.");
  
    /* Verify the result of chain verification */
    int res = SSL_get_verify_result(ssl);
    if(!(X509_V_OK == res)) fatalError("Cert presented by client couldn't be verified.");
  
    return sbio;
  }
  </code></pre>
  
  <p>Client code:</p>
  
  <pre><code>BIO *makeTLSConnection(char *servIP, char *servPort) {
  
    char *servLoc = calloc(strlen(servIP) + strlen(servPort) + 2, sizeof(char));
    strcat(servLoc, servIP);
    strcat(servLoc, ":");
    strcat(servLoc, servPort);
  
    BIO *sbio = NULL;
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
  
    SSL_library_init();
  
    ctx = SSL_CTX_new(TLSv1_client_method());
  
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
  
    if(!SSL_CTX_use_certificate_file(ctx,"clientcert.pem",SSL_FILETYPE_PEM)
      || !SSL_CTX_use_PrivateKey_file(ctx,"clientkey.pem",SSL_FILETYPE_PEM)
      || !SSL_CTX_check_private_key(ctx)) {
      ERR_print_errors_fp(stderr);
      fatalError("Error setting up SSL_CTX.");
    }
  
    if(!SSL_CTX_load_verify_locations(ctx, "servercert.pem", NULL))
      fatalError("Could not load trusted CA certificates.");
  
    sbio = BIO_new_ssl_connect(ctx);
  
    BIO_get_ssl(sbio, &amp;ssl);
  
    if(!ssl) {
      fatalError("Can't locate SSL pointer.");
    }
  
    BIO_set_conn_hostname(sbio, servLoc);
  
    if(BIO_do_connect(sbio) &lt;= 0) {
      ERR_print_errors_fp(stderr);
      fatalError("Error connecting to server.");
    }
  
    if(BIO_do_handshake(sbio) &lt;= 0) {
      ERR_print_errors_fp(stderr);
      fatalError("Error establishing SSL connection.");
    }
  
    /* Verify a server certificate was presented during the negotiation */
    X509* cert = SSL_get_peer_certificate(ssl);
    if(cert) { X509_free(cert); } /* Free immediately */
    if(NULL == cert) fatalError("Server did not present a cert during handshake.");
  
    /* Verify the result of chain verification */
    int res = SSL_get_verify_result(ssl);
    if(!(X509_V_OK == res)) fatalError("Cert presented by server couldn't be verified.");
  
    return sbio;
  }
  </code></pre>