diff --git a/docs/curl.1 b/docs/curl.1 index 01b89fb50..10ff68f4a 100644 --- a/docs/curl.1 +++ b/docs/curl.1 @@ -211,7 +211,17 @@ certificate concatenated! If this option is used several times, the last one will be used. .IP "--cacert " (HTTPS) Tells curl to use the specified certificate file to verify the -peer. The certificate must be in PEM format. +peer. The file may contain multiple CA certificates. The certificate(s) must +be in PEM format. + +If this option is used several times, the last one will be used. +.IP "--capath " +(HTTPS) Tells curl to use the specified certificate directory to verify the +peer. The certificates must be in PEM format, and the directory must have been +processed using the c_rehash utility supplied with openssl. Certificate directories +are not supported under Windows (because c_rehash uses symbolink links to +create them). Using --capath can allow curl to make https connections much +more efficiently than using --cacert if the --cacert file contains many CA certificates. If this option is used several times, the last one will be used. .IP "-f/--fail" diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index 5635ebdb4..a118a15d6 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -514,12 +514,20 @@ argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP. .B CURLOPT_SSL_VERIFYPEER Pass a long that is set to a non-zero value to make curl verify the peer's certificate. The certificate to verify against must be specified with the -CURLOPT_CAINFO option. (Added in 7.4.2) +CURLOPT_CAINFO option (Added in 7.4.2) or a certificate directory must be specified +with the CURLOPT_CAPATH option (Added in 7.9.8). .TP .B CURLOPT_CAINFO -Pass a char * to a zero terminated file naming holding the certificate to -verify the peer with. This only makes sense when used in combination with the -CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2) +Pass a char * to a zero terminated string naming a file holding one or more +certificates to verify the peer with. This only makes sense when used in +combination with the CURLOPT_SSL_VERIFYPEER option. (Added in 7.4.2) +.TP +.B CURLOPT_CAPATH +Pass a char * to a zero terminated string naming a directory holding multiple CA +certificates to verify the peer with. The certificate directory must be prepared using +the openssl c_rehash utility. This only makes sense when used in combination with the +CURLOPT_SSL_VERIFYPEER option. The CAPATH function apparently does not work in Windows +due to some limitation in openssl. (Added in 7.9.8) .TP .B CURLOPT_PASSWDFUNCTION Pass a pointer to a \fIcurl_passwd_callback\fP function that will be called diff --git a/include/curl/curl.h b/include/curl/curl.h index ea975c68b..23065c70f 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -544,6 +544,10 @@ typedef enum { /* mark this as start of a cookie session */ CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, OBJECTPOINT, 97), CURLOPT_LASTENTRY /* the last unusued */ } CURLoption; @@ -728,8 +732,8 @@ CURLcode curl_global_init(long flags); void curl_global_cleanup(void); /* This is the version number */ -#define LIBCURL_VERSION "7.9.7" -#define LIBCURL_VERSION_NUM 0x070907 +#define LIBCURL_VERSION "7.9.8-pre1" +#define LIBCURL_VERSION_NUM 0x070908 /* linked-list structure for the CURLOPT_QUOTE option (and other) */ struct curl_slist { diff --git a/lib/url.c b/lib/url.c index 62e727e93..d008ba459 100644 --- a/lib/url.c +++ b/lib/url.c @@ -981,7 +981,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set CA info for SSL connection. Specify file name of the CA certificate */ data->set.ssl.CAfile = va_arg(param, char *); - data->set.ssl.CApath = NULL; /*This does not work on windows.*/ + break; + case CURLOPT_CAPATH: + /* + * Set CA path info for SSL connection. Specify directory name of the CA certificates + * which have been prepared using openssl c_rehash utility. + */ + data->set.ssl.CApath = va_arg(param, char *); /*This does not work on windows.*/ break; case CURLOPT_TELNETOPTIONS: /* diff --git a/src/main.c b/src/main.c index 606b9e341..9254e941b 100644 --- a/src/main.c +++ b/src/main.c @@ -345,6 +345,7 @@ static void help(void) " --pass Specifies your passphrase for the private key (HTTPS)"); puts(" --engine Specifies the crypto engine to use (HTTPS)\n" " --cacert CA certifciate to verify peer against (SSL)\n" + " --capath CA directory (made using c_rehash) to verify peer against (SSL, NOT Windows)\n" " --ciphers What SSL ciphers to use (SSL)\n" " --connect-timeout Maximum time allowed for connection\n" " -f/--fail Fail silently (no output at all) on errors (H)\n" @@ -454,6 +455,7 @@ struct Configurable { char *cert; char *cert_type; char *cacert; + char *capath; char *key; char *key_type; char *key_passwd; @@ -999,6 +1001,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"Ed","key-type", TRUE}, {"Ee","pass", TRUE}, {"Ef","engine", TRUE}, + {"Eg","capath ", TRUE}, {"f", "fail", FALSE}, {"F", "form", TRUE}, {"g", "globoff", FALSE}, @@ -1335,6 +1338,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ case 'f': /* crypto engine */ GetStr(&config->engine, nextarg); break; + case 'g': /* CA info PEM file */ + /* CA cert directory */ + GetStr(&config->capath, nextarg); + break; default: /* certificate file */ { char *ptr = strchr(nextarg, ':'); @@ -2082,6 +2089,8 @@ void free_config_fields(struct Configurable *config) curl_formfree(config->httppost); if(config->cacert) free(config->cacert); + if(config->capath) + free(config->capath); if(config->cookiejar) free(config->cookiejar); @@ -2558,8 +2567,9 @@ operate(struct Configurable *config, int argc, char *argv[]) curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type); curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd); - if(config->cacert) { - curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert); + if(config->cacert || config->capath) { + if (config->cacert) curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert); + if (config->capath) curl_easy_setopt(curl, CURLOPT_CAPATH, config->capath); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); }