#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "url.h"
#include "ssl.h"
-#ifndef errno
-extern int errno;
-#endif
-
/* Application-wide SSL context. This is common to all SSL
connections. */
SSL_CTX *ssl_ctx;
{
SSL *ssl;
+ DEBUGP (("Initiating SSL handshake.\n"));
+
assert (ssl_ctx != NULL);
ssl = SSL_new (ssl_ctx);
if (!ssl)
functions are used for reading, writing, and polling. */
fd_register_transport (fd, openssl_read, openssl_write, openssl_poll,
openssl_peek, openssl_close, ssl);
- DEBUGP (("Connected %d to SSL 0x%0*lx\n", fd, 2 * sizeof (void *),
- (unsigned long) ssl));
+ DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
+ fd, PTR_FORMAT (ssl)));
return 1;
error:
+ DEBUGP (("SSL handshake failed.\n"));
print_errors ();
if (ssl)
SSL_free (ssl);
X509 *cert;
char common_name[256];
long vresult;
- int success;
+ int success = 1;
/* If the user has specified --no-check-cert, we still want to warn
him about problems with the server's certificate. */
logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
severity, escnonprint (host));
success = 0;
- goto out;
+ goto no_cert; /* must bail out since CERT is NULL */
}
#ifdef ENABLE_DEBUG
vresult = SSL_get_verify_result (ssl);
if (vresult != X509_V_OK)
{
+ /* #### We might want to print saner (and translatable) error
+ messages for several frequently encountered errors. The
+ candidates would include
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+ X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
+ X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
+ X509_V_ERR_CERT_NOT_YET_VALID, X509_V_ERR_CERT_HAS_EXPIRED,
+ and possibly others. The current approach would still be
+ used for the less frequent failure cases. */
logprintf (LOG_NOTQUIET,
_("%s: Certificate verification error for %s: %s\n"),
severity, escnonprint (host),
X509_verify_cert_error_string (vresult));
success = 0;
- goto out;
+ /* Fall through, so that the user is warned about *all* issues
+ with the cert (important with --no-check-certificate.) */
}
- /* Check that HOST matches the common name in the certificate. ####
- The remains to be done:
+ /* Check that HOST matches the common name in the certificate.
+ #### The following remains to be done:
- It should use dNSName/ipAddress subjectAltName extensions if
available; according to rfc2818: "If a subjectAltName extension
common names and choose the most specific one, i.e. the last
one, not the first one, which the current code picks.
- - Make sure that the names are encoded as UTF-8 which, being
- ASCII-compatible, can be easily compared against HOST. */
+ - Ensure that ASN1 strings from the certificate are encoded as
+ UTF-8 which can be meaningfully compared to HOST. */
common_name[0] = '\0';
X509_NAME_get_text_by_NID (X509_get_subject_name (cert),
%s: certificate common name `%s' doesn't match requested host name `%s'.\n"),
severity, escnonprint (common_name), escnonprint (host));
success = 0;
- goto out;
}
- /* The certificate was found, verified, and matched HOST. */
- success = 1;
-
- out:
- if (cert)
- X509_free (cert);
+ if (success)
+ DEBUGP (("X509 certificate successfully verified and matches host %s\n",
+ escnonprint (host)));
+ X509_free (cert);
+ no_cert:
if (opt.check_cert && !success)
logprintf (LOG_NOTQUIET, _("\
To connect to %s insecurely, use `--no-check-certificate'.\n"),