new urldata ssl layout and T. Bharath brought the new SSL cert verify function
authorDaniel Stenberg <daniel@haxx.se>
Mon, 30 Oct 2000 11:53:40 +0000 (11:53 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 30 Oct 2000 11:53:40 +0000 (11:53 +0000)
lib/ftp.c
lib/getinfo.c
lib/sendf.c
lib/ssluse.c
lib/telnet.c
lib/url.c
lib/urldata.h

index ea984a6..3469c33 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -273,8 +273,8 @@ int GetLastResponse(int sockfd, char *buf,
         break;
       default:
 #ifdef USE_SSLEAY
-        if (data->use_ssl) {
-          keepon = SSL_read(data->ssl, ptr, 1);
+        if (data->ssl.use) {
+          keepon = SSL_read(data->ssl.handle, ptr, 1);
         }
         else {
 #endif
index 177af97..dbcaa1b 100644 (file)
@@ -117,6 +117,9 @@ CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...)
   case CURLINFO_SPEED_UPLOAD:
     *param_doublep = data->progress.ulspeed;
     break;
+  case CURLINFO_SSL_VERIFYRESULT:
+    *param_longp = data->ssl.certverifyresult;
+    break;
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
index 4984bd7..447a473 100644 (file)
@@ -111,8 +111,8 @@ size_t sendf(int fd, struct UrlData *data, char *fmt, ...)
 #ifndef USE_SSLEAY
   bytes_written = swrite(fd, s, strlen(s));
 #else /* USE_SSLEAY */
-  if (data->use_ssl) {
-    bytes_written = SSL_write(data->ssl, s, strlen(s));
+  if (data->ssl.use) {
+    bytes_written = SSL_write(data->ssl.handle, s, strlen(s));
   } else {
     bytes_written = swrite(fd, s, strlen(s));
   }
@@ -161,8 +161,8 @@ size_t ssend(int fd, struct connectdata *conn, void *mem, size_t len)
   struct UrlData *data=conn->data; /* conn knows data, not vice versa */
 
 #ifdef USE_SSLEAY
-  if (data->use_ssl) {
-    bytes_written = SSL_write(data->ssl, mem, len);
+  if (data->ssl.use) {
+    bytes_written = SSL_write(data->ssl.handle, mem, len);
   }
   else {
 #endif
index 7933fc2..c9adc27 100644 (file)
@@ -94,10 +94,10 @@ int SSL_cert_stuff(struct UrlData *data,
        */
       strcpy(global_passwd, data->cert_passwd);
       /* Set passwd callback: */
-      SSL_CTX_set_default_passwd_cb(data->ctx, passwd_callback);
+      SSL_CTX_set_default_passwd_cb(data->ssl.ctx, passwd_callback);
     }
 
-    if (SSL_CTX_use_certificate_file(data->ctx,
+    if (SSL_CTX_use_certificate_file(data->ssl.ctx,
                                     cert_file,
                                     SSL_FILETYPE_PEM) <= 0) {
       failf(data, "unable to set certificate file (wrong password?)\n");
@@ -106,14 +106,14 @@ int SSL_cert_stuff(struct UrlData *data,
     if (key_file == NULL)
       key_file=cert_file;
 
-    if (SSL_CTX_use_PrivateKey_file(data->ctx,
+    if (SSL_CTX_use_PrivateKey_file(data->ssl.ctx,
                                    key_file,
                                    SSL_FILETYPE_PEM) <= 0) {
       failf(data, "unable to set public key file\n");
       return(0);
     }
     
-    ssl=SSL_new(data->ctx);
+    ssl=SSL_new(data->ssl.ctx);
     x509=SSL_get_certificate(ssl);
     
     if (x509 != NULL)
@@ -127,7 +127,7 @@ int SSL_cert_stuff(struct UrlData *data,
     
     /* Now we know that a key and cert have been set against
      * the SSL context */
-    if (!SSL_CTX_check_private_key(data->ctx)) {
+    if (!SSL_CTX_check_private_key(data->ssl.ctx)) {
       failf(data, "Private key does not match the certificate public key\n");
       return(0);
     }
@@ -140,7 +140,7 @@ int SSL_cert_stuff(struct UrlData *data,
 
 #endif
 
-#if SSL_VERIFY_CERT
+#ifdef USE_SSLEAY
 int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
 {
   X509 *err_cert;
@@ -164,7 +164,7 @@ UrgSSLConnect (struct UrlData *data)
     SSL_METHOD *req_method;
 
     /* mark this is being ssl enabled from here on out. */
-    data->use_ssl = 1;
+    data->ssl.use = TRUE;
 
     /* Lets get nice error messages */
     SSL_load_error_strings();
@@ -195,7 +195,7 @@ UrgSSLConnect (struct UrlData *data)
     /* Setup all the global SSL stuff */
     SSLeay_add_ssl_algorithms();
 
-    switch(data->ssl_version) {
+    switch(data->ssl.version) {
     default:
       req_method = SSLv23_client_method();
       break;
@@ -207,9 +207,9 @@ UrgSSLConnect (struct UrlData *data)
       break;
     }
     
-    data->ctx = SSL_CTX_new(req_method);
+    data->ssl.ctx = SSL_CTX_new(req_method);
 
-    if(!data->ctx) {
+    if(!data->ssl.ctx) {
       failf(data, "SSL: couldn't create a context!");
       return 1;
     }
@@ -221,22 +221,31 @@ UrgSSLConnect (struct UrlData *data)
       }
     }
 
-#if SSL_VERIFY_CERT
-    SSL_CTX_set_verify(data->ctx,
-                       SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
-                       SSL_VERIFY_CLIENT_ONCE,
-                       cert_verify_callback);
-#endif
+    if(data->ssl.verifypeer){
+      SSL_CTX_set_verify(data->ssl.ctx,
+                         SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
+                         SSL_VERIFY_CLIENT_ONCE,
+                         cert_verify_callback);
+      if (!SSL_CTX_load_verify_locations(data->ssl.ctx,
+                                         data->ssl.CAfile,
+                                         data->ssl.CApath)) {
+        failf(data,"error setting cerficate verify locations\n");
+        return 2;
+      }
+    }
+    else
+      SSL_CTX_set_verify(data->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
+
 
     /* Lets make an SSL structure */
-    data->ssl = SSL_new (data->ctx);
-    SSL_set_connect_state (data->ssl);
+    data->ssl.handle = SSL_new (data->ssl.ctx);
+    SSL_set_connect_state (data->ssl.handle);
 
-    data->server_cert = 0x0;
+    data->ssl.server_cert = 0x0;
 
     /* pass the raw socket into the SSL layers */
-    SSL_set_fd (data->ssl, data->firstsocket);
-    err = SSL_connect (data->ssl);
+    SSL_set_fd (data->ssl.handle, data->firstsocket);
+    err = SSL_connect (data->ssl.handle);
 
     if (-1 == err) {
       err = ERR_get_error(); 
@@ -244,8 +253,9 @@ UrgSSLConnect (struct UrlData *data)
       return 10;
     }
 
-
-    infof (data, "SSL connection using %s\n", SSL_get_cipher (data->ssl));
+    /* Informational message */
+    infof (data, "SSL connection using %s\n",
+           SSL_get_cipher(data->ssl.handle));
   
     /* Get server's certificate (note: beware of dynamic allocation) - opt */
     /* major serious hack alert -- we should check certificates
@@ -253,14 +263,15 @@ UrgSSLConnect (struct UrlData *data)
      * attack
      */
 
-    data->server_cert = SSL_get_peer_certificate (data->ssl);
-    if(!data->server_cert) {
+    data->ssl.server_cert = SSL_get_peer_certificate (data->ssl.handle);
+    if(!data->ssl.server_cert) {
       failf(data, "SSL: couldn't get peer certificate!");
       return 3;
     }
     infof (data, "Server certificate:\n");
   
-    str = X509_NAME_oneline (X509_get_subject_name (data->server_cert), NULL, 0);
+    str = X509_NAME_oneline (X509_get_subject_name (data->ssl.server_cert),
+                             NULL, 0);
     if(!str) {
       failf(data, "SSL: couldn't get X509-subject!");
       return 4;
@@ -268,7 +279,8 @@ UrgSSLConnect (struct UrlData *data)
     infof(data, "\t subject: %s\n", str);
     CRYPTO_free(str);
 
-    str = X509_NAME_oneline (X509_get_issuer_name  (data->server_cert), NULL, 0);
+    str = X509_NAME_oneline (X509_get_issuer_name  (data->ssl.server_cert),
+                             NULL, 0);
     if(!str) {
       failf(data, "SSL: couldn't get X509-issuer name!");
       return 5;
@@ -279,11 +291,14 @@ UrgSSLConnect (struct UrlData *data)
     /* We could do all sorts of certificate verification stuff here before
        deallocating the certificate. */
 
-#if SSL_VERIFY_CERT
-    infof(data, "Verify result: %d\n", SSL_get_verify_result(data->ssl));
-#endif
+    if(data->ssl.verifypeer) {
+      data->ssl.certverifyresult=SSL_get_verify_result(data->ssl.handle);
+      infof(data, "Verify result: %d\n", data->ssl.certverifyresult);
+    }
+    else
+      data->ssl.certverifyresult=0;
 
-    X509_free(data->server_cert);
+    X509_free(data->ssl.server_cert);
 #else /* USE_SSLEAY */
     /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
     (void) data;
index 486d69d..e8fa874 100644 (file)
@@ -861,8 +861,9 @@ void telwrite(struct UrlData *data,
 #ifndef USE_SSLEAY
       bytes_written = swrite(data->firstsocket, outbuf, out_count);
 #else
-      if (data->use_ssl) {
-        bytes_written = SSL_write(data->ssl, (char *)outbuf, out_count);
+      if (data->ssl.use) {
+        bytes_written = SSL_write(data->ssl.handle, (char *)outbuf,
+                                  out_count);
       }
       else {
         bytes_written = swrite(data->firstsocket, outbuf, out_count);
@@ -918,8 +919,8 @@ CURLcode telnet(struct connectdata *conn)
 #ifndef USE_SSLEAY
            nread = sread (sockfd, buf, BUFSIZE - 1);
 #else
-           if (data->use_ssl) {
-              nread = SSL_read (data->ssl, buf, BUFSIZE - 1);
+           if (data->ssl.use) {
+              nread = SSL_read (data->ssl.handle, buf, BUFSIZE - 1);
            }
            else {
               nread = sread (sockfd, buf, BUFSIZE - 1);
index c941e99..76b8f4e 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -150,19 +150,19 @@ void curl_free(void)
 void static urlfree(struct UrlData *data, bool totally)
 {
 #ifdef USE_SSLEAY
-  if (data->use_ssl) {
-    if(data->ssl) {
-      (void)SSL_shutdown(data->ssl);
-      SSL_set_connect_state(data->ssl);
+  if (data->ssl.use) {
+    if(data->ssl.handle) {
+      (void)SSL_shutdown(data->ssl.handle);
+      SSL_set_connect_state(data->ssl.handle);
 
-      SSL_free (data->ssl);
-      data->ssl = NULL;
+      SSL_free (data->ssl.handle);
+      data->ssl.handle = NULL;
     }
-    if(data->ctx) {
-      SSL_CTX_free (data->ctx);
-      data->ctx = NULL;
+    if(data->ssl.ctx) {
+      SSL_CTX_free (data->ssl.ctx);
+      data->ssl.ctx = NULL;
     }
-    data->use_ssl = FALSE; /* get back to ordinary socket usage */
+    data->ssl.use = FALSE; /* get back to ordinary socket usage */
   }
 #endif /* USE_SSLEAY */
 
@@ -380,7 +380,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
     break;
 
   case CURLOPT_SSLVERSION:
-    data->ssl_version = va_arg(param, long);
+    data->ssl.version = va_arg(param, long);
     break;
 
   case CURLOPT_COOKIEFILE:
@@ -522,6 +522,13 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
     data->krb4_level = va_arg(param, char *);
     data->bits.krb4=data->krb4_level?TRUE:FALSE;
     break;
+  case CURLOPT_SSL_VERIFYPEER:
+    data->ssl.verifypeer = va_arg(param, long);
+    break;
+  case CURLOPT_CAINFO:
+    data->ssl.CAfile = va_arg(param, char *);
+    data->ssl.CApath = NULL; /*This does not work on windows.*/
+    break;
   default:
     /* unknown tag and its companion, just ignore: */
     return CURLE_READ_ERROR; /* correct this */
@@ -546,8 +553,8 @@ int GetLine(int sockfd, char *buf, struct UrlData *data)
       (nread<BUFSIZE) && read_rc;
       nread++, ptr++) {
 #ifdef USE_SSLEAY
-    if (data->use_ssl) {
-      read_rc = SSL_read(data->ssl, ptr, 1);
+    if (data->ssl.use) {
+      read_rc = SSL_read(data->ssl.handle, ptr, 1);
     }
     else {
 #endif
@@ -593,8 +600,8 @@ CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
   data = conn->data;
 
 #ifdef USE_SSLEAY
-  if (data->use_ssl) {
-    bytes_written = SSL_write(data->ssl, buf, amount);
+  if (data->ssl.use) {
+    bytes_written = SSL_write(data->ssl.handle, buf, amount);
   }
   else {
 #endif
@@ -624,8 +631,8 @@ CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
   data = conn->data;
 
 #ifdef USE_SSLEAY
-  if (data->use_ssl) {
-    nread = SSL_read (data->ssl, buf, buffersize);
+  if (data->ssl.use) {
+    nread = SSL_read (data->ssl.handle, buf, buffersize);
   }
   else {
 #endif
index 5b5da4d..12046bf 100644 (file)
@@ -326,6 +326,21 @@ typedef enum {
   CURLI_LAST
 } CurlInterface;
 
+struct ssldata {
+  bool use;              /* use ssl encrypted communications TRUE/FALSE */
+  long version;          /* what version the client wants to use */
+  long certverifyresult; /* result from the certificate verification */
+  bool verifypeer;       /* set TRUE if this is desired */
+  char *CApath;          /* DOES NOT WORK ON WINDOWS */
+  char *CAfile;          /* cerficate to verify peer against */
+#ifdef USE_SSLEAY
+  /* these ones requires specific SSL-types */
+  SSL_CTX* ctx;
+  SSL*     handle;
+  X509*    server_cert;
+#endif /* USE_SSLEAY */
+};
+
 /*
  * As of April 11, 2000 we're now trying to split up the urldata struct in
  * three different parts:
@@ -438,8 +453,6 @@ struct UrlData {
 
   char *cookie;       /* HTTP cookie string to send */
 
-  short    use_ssl;   /* use ssl encrypted communications */
-
   char *newurl; /* This can only be set if a Location: was in the
                   document headers */
 
@@ -451,12 +464,8 @@ struct UrlData {
 
   struct CookieInfo *cookies;
 
-  long ssl_version; /* what version the client wants to use */
-#ifdef USE_SSLEAY
-  SSL_CTX* ctx;
-  SSL*     ssl;
-  X509*    server_cert;
-#endif /* USE_SSLEAY */
+  struct ssldata ssl; /* this is for ssl-stuff */
+
   long crlf;
   struct curl_slist *quote;     /* before the transfer */
   struct curl_slist *postquote; /* after the transfer */