- Axel Tillequin and Arnaud Ebalard added support for CURLOPT_CRLFILE, for
OpenSSL, NSS and GnuTLS-built libcurls.
This commit is contained in:
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 */
|
||||
|
||||
Reference in New Issue
Block a user