mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
- Axel Tillequin and Arnaud Ebalard added support for CURLOPT_CRLFILE, for
OpenSSL, NSS and GnuTLS-built libcurls.
This commit is contained in:
parent
930a45e7a9
commit
3fe8251dfb
3
CHANGES
3
CHANGES
@ -8,6 +8,9 @@
|
||||
|
||||
|
||||
Daniel Stenberg (6 Jun 2008)
|
||||
- Axel Tillequin and Arnaud Ebalard added support for CURLOPT_CRLFILE, for
|
||||
OpenSSL, NSS and GnuTLS-built libcurls.
|
||||
|
||||
- Added CURLINFO_PRIMARY_IP as a new information retrievable with
|
||||
curl_easy_getinfo. It returns a pointer to a string with the most recently
|
||||
used IP address. Modified test case 500 to also verify this feature. The
|
||||
|
@ -2,7 +2,7 @@ Curl and libcurl 7.18.3
|
||||
|
||||
Public curl releases: 106
|
||||
Command line options: 126
|
||||
curl_easy_setopt() options: 150
|
||||
curl_easy_setopt() options: 151
|
||||
Public functions in libcurl: 58
|
||||
Public web site mirrors: 37
|
||||
Known libcurl bindings: 36
|
||||
@ -11,6 +11,7 @@ Curl and libcurl 7.18.3
|
||||
This release includes the following changes:
|
||||
|
||||
o Added CURLINFO_PRIMARY_IP
|
||||
o Added CURLOPT_CRLFILE
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
@ -31,6 +32,6 @@ New curl mirrors:
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Lenny Rachitsky
|
||||
Lenny Rachitsky, Axel Tillequin, Arnaud Ebalard
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@ -5,9 +5,6 @@ To be addressed before 7.18.3 (planned release: August 2008)
|
||||
|
||||
140 - Arnaud Ebalard and Axel Tillequin's CRL support and issuer check patches
|
||||
|
||||
141 - The sponsored feature CURLINFO_PRIMARY_IP that returns the IP address
|
||||
as a string for the most recently used connection.
|
||||
|
||||
144 - Help apps use 64bit/LFS libcurl!
|
||||
|
||||
145 -
|
||||
|
@ -1452,6 +1452,24 @@ in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
||||
indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently
|
||||
does not work in Windows due to some limitation in openssl. This option is
|
||||
OpenSSL-specific and does nothing if libcurl is built to use GnuTLS.
|
||||
.IP CURLOPT_CRLFILE
|
||||
Pass a char * to a zero terminated string naming a file with the concatenation
|
||||
of CRL (in PEM format) to use in the certificate validation that occurs during
|
||||
the SSL exchange.
|
||||
|
||||
When curl is built to use NSS or GnuTLS, there is no way to influence the use
|
||||
of CRL passed to help in the verification process. When libcurl is built with
|
||||
OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both
|
||||
set, requiring CRL check against all the elements of the certificate chain if
|
||||
a CRL file is passed.
|
||||
|
||||
This option makes sense only when used in combination with the
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP option.
|
||||
|
||||
A specific error code (CURLE_SSL_CRL_BADFILE) is defined with the option. It
|
||||
is returned when the SSL exchange fails because the CRL file cannot be loaded.
|
||||
Note that a failure in certificate verification due to a revocation information
|
||||
found in the CRL does not trigger this specific error.
|
||||
.IP CURLOPT_RANDOM_FILE
|
||||
Pass a char * to a zero terminated file name. The file will be used to read
|
||||
from to seed the random engine for SSL. The more random the specified file is,
|
||||
|
@ -212,6 +212,8 @@ Failed to shut down the SSL connection
|
||||
Socket is not ready for send/recv wait till it's ready and try again. This
|
||||
return code is only returned from \fIcurl_easy_recv(3)\fP and
|
||||
\fIcurl_easy_send(3)\fP (Added in 7.18.2)
|
||||
.IP "CURLE_SSL_CRL_BADFILE (82)"
|
||||
Failed to load CRL file (Added in 7.18.3)
|
||||
.IP "CURLE_OBSOLETE*"
|
||||
These error codes will never be returned. They used to be used in an old libcurl
|
||||
version and are currently unused.
|
||||
|
@ -452,7 +452,10 @@ typedef enum {
|
||||
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
|
||||
connection */
|
||||
CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
|
||||
wait till it's ready and try again */
|
||||
wait till it's ready and try again (Added
|
||||
in 7.18.2) */
|
||||
CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
|
||||
wrong format (Added in 7.18.3) */
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
@ -1200,6 +1203,9 @@ typedef enum {
|
||||
CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
|
||||
CINIT(SEEKDATA, OBJECTPOINT, 168),
|
||||
|
||||
/* CRL file */
|
||||
CINIT(CRLFILE, OBJECTPOINT, 169),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
15
lib/gtls.c
15
lib/gtls.c
@ -271,6 +271,21 @@ Curl_gtls_connect(struct connectdata *conn,
|
||||
rc, data->set.ssl.CAfile);
|
||||
}
|
||||
|
||||
if(data->set.ssl.CRLfile) {
|
||||
/* set the CRL list file */
|
||||
rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
|
||||
data->set.ssl.CRLfile,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
failf(data, "error reading crl file %s (%s)\n",
|
||||
data->set.ssl.CRLfile, gnutls_strerror(rc));
|
||||
return CURLE_SSL_CRL_BADFILE;
|
||||
}
|
||||
else
|
||||
infof(data, "found %d CRL in %s\n",
|
||||
rc, data->set.ssl.CRLfile);
|
||||
}
|
||||
|
||||
/* Initialize TLS session as a client */
|
||||
rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
|
||||
if(rc) {
|
||||
|
77
lib/nss.c
77
lib/nss.c
@ -59,6 +59,9 @@
|
||||
#include <sslproto.h>
|
||||
#include <prtypes.h>
|
||||
#include <pk11pub.h>
|
||||
#include <prio.h>
|
||||
#include <secitem.h>
|
||||
#include <secport.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "easyif.h" /* for Curl_convert_from_utf8 prototype */
|
||||
@ -362,6 +365,69 @@ done:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nss_load_crl(char* crlfilename, PRBool ascii)
|
||||
{
|
||||
PRFileDesc *infile;
|
||||
PRStatus prstat;
|
||||
PRFileInfo info;
|
||||
PRInt32 nb;
|
||||
int rv;
|
||||
SECItem crlDER;
|
||||
CERTSignedCrl *crl=NULL;
|
||||
PK11SlotInfo *slot=NULL;
|
||||
|
||||
infile = PR_Open(crlfilename,PR_RDONLY,0);
|
||||
if (!infile) {
|
||||
return 0;
|
||||
}
|
||||
crlDER.data = NULL;
|
||||
prstat = PR_GetOpenFileInfo(infile,&info);
|
||||
if (prstat!=PR_SUCCESS) return 0;
|
||||
if (ascii) {
|
||||
SECItem filedata;
|
||||
char *asc,*body;
|
||||
filedata.data = NULL;
|
||||
if (!SECITEM_AllocItem(NULL,&filedata,info.size)) return 0;
|
||||
nb = PR_Read(infile,filedata.data,info.size);
|
||||
if (nb!=info.size) return 0;
|
||||
asc = (char*)filedata.data;
|
||||
if (!asc) {
|
||||
return 0;
|
||||
}
|
||||
if ((body=strstr(asc,"-----BEGIN")) != NULL) {
|
||||
char *trailer=NULL;
|
||||
asc = body;
|
||||
body = PORT_Strchr(asc,'\n');
|
||||
if (!body) body = PORT_Strchr(asc,'\r');
|
||||
if (body) trailer = strstr(++body,"-----END");
|
||||
if (trailer!=NULL) *trailer='\0';
|
||||
else return 0;
|
||||
}
|
||||
else {
|
||||
body = asc;
|
||||
}
|
||||
rv = ATOB_ConvertAsciiToItem(&crlDER,body);
|
||||
PORT_Free(filedata.data);
|
||||
if (rv) return 0;
|
||||
}
|
||||
else {
|
||||
if (!SECITEM_AllocItem(NULL,&crlDER,info.size)) return 0;
|
||||
nb = PR_Read(infile,crlDER.data,info.size);
|
||||
if (nb!=info.size) return 0;
|
||||
}
|
||||
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
crl = PK11_ImportCRL(slot,&crlDER,
|
||||
NULL,SEC_CRL_TYPE,
|
||||
NULL,CRL_IMPORT_DEFAULT_OPTIONS,
|
||||
NULL,(CRL_DECODE_DEFAULT_OPTIONS|
|
||||
CRL_DECODE_DONT_COPY_DER));
|
||||
if (slot) PK11_FreeSlot(slot);
|
||||
if (!crl) return 0;
|
||||
SEC_DestroyCrl(crl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nss_load_key(struct connectdata *conn, char *key_file)
|
||||
{
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
@ -955,6 +1021,17 @@ CURLcode Curl_nss_connect(struct connectdata * conn, int sockindex)
|
||||
data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
|
||||
data->set.ssl.CApath ? data->set.ssl.CApath : "none");
|
||||
|
||||
if (data->set.ssl.CRLfile) {
|
||||
int rc = nss_load_crl(data->set.ssl.CRLfile, PR_FALSE);
|
||||
if (!rc) {
|
||||
curlerr = CURLE_SSL_CRL_BADFILE;
|
||||
goto error;
|
||||
}
|
||||
infof(data,
|
||||
" CRLfile: %s\n",
|
||||
data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none");
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
char *n;
|
||||
char *nickname;
|
||||
|
26
lib/ssluse.c
26
lib/ssluse.c
@ -1293,6 +1293,7 @@ ossl_connect_step1(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
|
||||
void *ssl_sessionid=NULL;
|
||||
X509_LOOKUP *lookup=NULL;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||
@ -1429,6 +1430,31 @@ ossl_connect_step1(struct connectdata *conn,
|
||||
data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
|
||||
"none");
|
||||
}
|
||||
|
||||
if (data->set.str[STRING_SSL_CRLFILE]) {
|
||||
/* tell SSL where to find CRL file that is used to check certificate
|
||||
* revocation */
|
||||
lookup=X509_STORE_add_lookup(connssl->ctx->cert_store,X509_LOOKUP_file());
|
||||
if ( !lookup ||
|
||||
(X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
|
||||
X509_FILETYPE_PEM)!=1) ) {
|
||||
failf(data,"error loading CRL file :\n"
|
||||
" CRLfile: %s\n",
|
||||
data->set.str[STRING_SSL_CRLFILE]?
|
||||
data->set.str[STRING_SSL_CRLFILE]: "none");
|
||||
return CURLE_SSL_CRL_BADFILE;
|
||||
}
|
||||
else {
|
||||
/* Everything is fine. */
|
||||
infof(data, "successfully load CRL file:\n");
|
||||
X509_STORE_set_flags(connssl->ctx->cert_store,
|
||||
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
|
||||
}
|
||||
infof(data,
|
||||
" CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
|
||||
data->set.str[STRING_SSL_CRLFILE]: "none");
|
||||
}
|
||||
|
||||
/* SSL always tries to verify the peer, this only says whether it should
|
||||
* fail to connect if the verification fails, or if it should continue
|
||||
* anyway. In the latter case the result of the verification is checked with
|
||||
|
@ -222,6 +222,9 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_SSL_SHUTDOWN_FAILED:
|
||||
return "Failed to shut down the SSL connection";
|
||||
|
||||
case CURLE_SSL_CRL_BADFILE:
|
||||
return "Failed to load CRL file (path? access rights?, format?)";
|
||||
|
||||
case CURLE_SEND_FAIL_REWIND:
|
||||
return "Send failed since rewinding of the data stream failed";
|
||||
|
||||
|
@ -1811,6 +1811,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
result = setstropt(&data->set.str[STRING_SSL_CAPATH],
|
||||
va_arg(param, char *));
|
||||
break;
|
||||
case CURLOPT_CRLFILE:
|
||||
/*
|
||||
* Set CRL file info for SSL connection. Specify file name of the CRL
|
||||
* to check certificates revocation
|
||||
*/
|
||||
result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
|
||||
va_arg(param, char *));
|
||||
break;
|
||||
case CURLOPT_TELNETOPTIONS:
|
||||
/*
|
||||
* Set a linked list of telnet options
|
||||
@ -3951,6 +3959,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
*/
|
||||
data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
|
||||
data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
|
||||
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
|
||||
data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
|
||||
data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
|
||||
data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
|
||||
|
@ -212,6 +212,7 @@ struct ssl_config_data {
|
||||
2: CN must match hostname */
|
||||
char *CApath; /* certificate dir (doesn't work on windows) */
|
||||
char *CAfile; /* cerficate to verify peer against */
|
||||
char *CRLfile; /* CRL to check cerficate revocation */
|
||||
char *random_file; /* path to file containing "random" data */
|
||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||
char *cipher_list; /* list of ciphers to use */
|
||||
@ -1317,6 +1318,7 @@ enum dupstring {
|
||||
STRING_USERAGENT, /* User-Agent string */
|
||||
STRING_USERPWD, /* <user:password>, if used */
|
||||
STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
|
||||
STRING_SSL_CRLFILE, /* crl file to check certificate */
|
||||
|
||||
/* -- end of strings -- */
|
||||
STRING_LAST /* not used, just an end-of-list marker */
|
||||
|
Loading…
Reference in New Issue
Block a user