title: SSL server certificate verification fails in code but not with openssl
body: <p>I am trying to code a web service client in a RHEL 4 system (openssl 0.9.8b) (upgrade is not an option). I got the CA cert file to use, with two certificates, one is a self-signed root certificate. It works with "openssl s_client", but not from code. There I get error 7 (SSL certificate validation failed) from SSL_get_verify_result.</p>
  
  <p>I made a test program, here are the basic parts:</p>
  
  <pre><code>SSL_library_init();
  SSL_load_error_strings();
  ctx = SSL_CTX_new(SSLv23_method());
  SSL_CTX_load_verify_locations(ctx, "/etc/pki/mycert/cacert.pem", 0);
  ssl = SSL_new(ctx);
  sbio = BIO_new_socket(sock, BIO_NOCLOSE); /* The socket is already connected */
  SSL_set_bio(ssl, sbio, sbio);
  SSL_connect(ssl);
  err = SSL_get_verify_result(ssl);
  </code></pre>
  
  <p>The connection works and the server sends its certificate; I have dumped it out with PEM_write_X509 and verified that it is accepted by "openssl verify".</p>
  
  <p>I have used</p>
  
  <pre><code>SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
  </code></pre>
  
  <p>to write out the steps of the verification in a callback function:</p>
  
  <pre><code>static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
  {
      char    buf[256];
      X509   *err_cert;
      int     err, depth;
  
      err_cert = X509_STORE_CTX_get_current_cert(ctx);
      err = X509_STORE_CTX_get_error(ctx);
      depth = X509_STORE_CTX_get_error_depth(ctx);
  
      X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
  
  if (!preverify_ok)
      printf("verify error:num=%d:%s:depth=%d:%s\n", err,
               X509_verify_cert_error_string(err), depth, buf);
  else
      printf("Preverify OK, depth=%d:%s, err=%d\n", depth, buf, err);
  ...
  </code></pre>
  
  <p>The output of this is (some certificate data replaced with "..."):</p>
  
  <pre><code>Preverify OK, depth=2:/ST=GP/L=JHB/C ... QA Root CA 01, err=0
  Preverify OK, depth=1:/C=ZA/DC=za/DC ... QA Issue CA 01, err=0
  verify error:num=7:certificate signature failure:depth=0:/C=ZA ...
  </code></pre>
  
  <p>When running "openssl s_client" with this CA cert file as "-CAfile", the output starts with:</p>
  
  <pre><code>depth=2 /ST=GP/L=JHB/C ... QA Root CA 01
  verify return:1
  depth=1 /C=ZA/DC=za/DC ... QA Issue CA 01
  verify return:1
  depth=0 /C=ZA/ST ...
  verify return:1
  </code></pre>
  
  <p>So what is the difference between what "openssl s_client" is doing, and what the code is doing?</p>