mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-11 13:54:16 -04:00
Update CyaSSL to latest version.
This commit is contained in:
parent
5fcd270398
commit
3d007d0b4b
445 changed files with 162375 additions and 26182 deletions
|
@ -1,6 +1,6 @@
|
|||
/* crl.c
|
||||
*
|
||||
* Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
|
@ -16,22 +16,28 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef HAVE_CRL
|
||||
|
||||
#include <cyassl/internal.h>
|
||||
#include <cyassl/error.h>
|
||||
#include <cyassl/error-ssl.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CRL_MONITOR
|
||||
static int StopMonitor(int mfd);
|
||||
#endif
|
||||
|
||||
|
||||
/* Initialze CRL members */
|
||||
int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm)
|
||||
|
@ -43,10 +49,11 @@ int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm)
|
|||
crl->monitors[0].path = NULL;
|
||||
crl->monitors[1].path = NULL;
|
||||
#ifdef HAVE_CRL_MONITOR
|
||||
crl->tid = 0;
|
||||
crl->tid = 0;
|
||||
crl->mfd = -1; /* mfd for bsd is kqueue fd, eventfd for linux */
|
||||
#endif
|
||||
if (InitMutex(&crl->crlLock) != 0)
|
||||
return BAD_MUTEX_ERROR;
|
||||
return BAD_MUTEX_E;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,7 +65,8 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
|
|||
CYASSL_ENTER("InitCRL_Entry");
|
||||
|
||||
XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE);
|
||||
XMEMCPY(crle->crlHash, dcrl->crlHash, MD5_DIGEST_SIZE);
|
||||
/* XMEMCPY(crle->crlHash, dcrl->crlHash, SHA_DIGEST_SIZE);
|
||||
* copy the hash here if needed for optimized comparisons */
|
||||
XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
|
||||
XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
|
||||
crle->lastDateFormat = dcrl->lastDateFormat;
|
||||
|
@ -89,7 +97,7 @@ static void FreeCRL_Entry(CRL_Entry* crle)
|
|||
|
||||
|
||||
/* Free all CRL resources */
|
||||
void FreeCRL(CYASSL_CRL* crl)
|
||||
void FreeCRL(CYASSL_CRL* crl, int dynamic)
|
||||
{
|
||||
CRL_Entry* tmp = crl->crlList;
|
||||
|
||||
|
@ -110,11 +118,18 @@ void FreeCRL(CYASSL_CRL* crl)
|
|||
|
||||
#ifdef HAVE_CRL_MONITOR
|
||||
if (crl->tid != 0) {
|
||||
CYASSL_MSG("Canceling monitor thread");
|
||||
pthread_cancel(crl->tid);
|
||||
CYASSL_MSG("stopping monitor thread");
|
||||
if (StopMonitor(crl->mfd) == 0)
|
||||
pthread_join(crl->tid, NULL);
|
||||
else {
|
||||
CYASSL_MSG("stop monitor failed, cancel instead");
|
||||
pthread_cancel(crl->tid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
FreeMutex(&crl->crlLock);
|
||||
if (dynamic) /* free self */
|
||||
XFREE(crl, NULL, DYNAMIC_TYPE_CRL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,14 +138,13 @@ int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert)
|
|||
{
|
||||
CRL_Entry* crle;
|
||||
int foundEntry = 0;
|
||||
int revoked = 0;
|
||||
int ret = 0;
|
||||
|
||||
CYASSL_ENTER("CheckCertCRL");
|
||||
|
||||
if (LockMutex(&crl->crlLock) != 0) {
|
||||
CYASSL_MSG("LockMutex failed");
|
||||
return BAD_MUTEX_ERROR;
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
crle = crl->crlList;
|
||||
|
@ -157,7 +171,6 @@ int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert)
|
|||
while (rc) {
|
||||
if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
|
||||
CYASSL_MSG("Cert revoked");
|
||||
revoked = 1;
|
||||
ret = CRL_CERT_REVOKED;
|
||||
break;
|
||||
}
|
||||
|
@ -214,7 +227,7 @@ static int AddCRL(CYASSL_CRL* crl, DecodedCRL* dcrl)
|
|||
CYASSL_MSG("LockMutex failed");
|
||||
FreeCRL_Entry(crle);
|
||||
XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
return BAD_MUTEX_ERROR;
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
crle->next = crl->crlList;
|
||||
crl->crlList = crle;
|
||||
|
@ -256,7 +269,7 @@ int BufferLoadCRL(CYASSL_CRL* crl, const byte* buff, long sz, int type)
|
|||
}
|
||||
|
||||
InitDecodedCRL(&dcrl);
|
||||
ret = ParseCRL(&dcrl, myBuffer, sz, crl->cm);
|
||||
ret = ParseCRL(&dcrl, myBuffer, (word32)sz, crl->cm);
|
||||
if (ret != 0) {
|
||||
CYASSL_MSG("ParseCRL error");
|
||||
}
|
||||
|
@ -296,7 +309,7 @@ static int SwapLists(CYASSL_CRL* crl)
|
|||
ret = LoadCRL(&tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
CYASSL_MSG("PEM LoadCRL on dir change failed");
|
||||
FreeCRL(&tmp);
|
||||
FreeCRL(&tmp, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -305,14 +318,14 @@ static int SwapLists(CYASSL_CRL* crl)
|
|||
ret = LoadCRL(&tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
CYASSL_MSG("DER LoadCRL on dir change failed");
|
||||
FreeCRL(&tmp);
|
||||
FreeCRL(&tmp, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (LockMutex(&crl->crlLock) != 0) {
|
||||
CYASSL_MSG("LockMutex failed");
|
||||
FreeCRL(&tmp);
|
||||
FreeCRL(&tmp, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -324,49 +337,91 @@ static int SwapLists(CYASSL_CRL* crl)
|
|||
|
||||
UnLockMutex(&crl->crlLock);
|
||||
|
||||
FreeCRL(&tmp);
|
||||
FreeCRL(&tmp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __MACH__
|
||||
#if (defined(__MACH__) || defined(__FreeBSD__))
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __MACH__
|
||||
#define XEVENT_MODE O_EVTONLY
|
||||
#elif defined(__FreeBSD__)
|
||||
#define XEVENT_MODE EVFILT_VNODE
|
||||
#endif
|
||||
|
||||
|
||||
/* we need a unique kqueue user filter fd for crl in case user is doing custom
|
||||
* events too */
|
||||
#ifndef CRL_CUSTOM_FD
|
||||
#define CRL_CUSTOM_FD 123456
|
||||
#endif
|
||||
|
||||
|
||||
/* shutdown monitor thread, 0 on success */
|
||||
static int StopMonitor(int mfd)
|
||||
{
|
||||
struct kevent change;
|
||||
|
||||
/* trigger custom shutdown */
|
||||
EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
|
||||
if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) {
|
||||
CYASSL_MSG("kevent trigger customer event failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* OS X monitoring */
|
||||
static void* DoMonitor(void* arg)
|
||||
{
|
||||
int fPEM, fDER, kq;
|
||||
int fPEM, fDER;
|
||||
struct kevent change;
|
||||
|
||||
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
|
||||
|
||||
CYASSL_ENTER("DoMonitor");
|
||||
|
||||
kq = kqueue();
|
||||
if (kq == -1) {
|
||||
crl->mfd = kqueue();
|
||||
if (crl->mfd == -1) {
|
||||
CYASSL_MSG("kqueue failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* listen for custom shutdown event */
|
||||
EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
|
||||
if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) {
|
||||
CYASSL_MSG("kevent monitor customer event failed");
|
||||
close(crl->mfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fPEM = -1;
|
||||
fDER = -1;
|
||||
|
||||
if (crl->monitors[0].path) {
|
||||
fPEM = open(crl->monitors[0].path, O_EVTONLY);
|
||||
fPEM = open(crl->monitors[0].path, XEVENT_MODE);
|
||||
if (fPEM == -1) {
|
||||
CYASSL_MSG("PEM event dir open failed");
|
||||
close(crl->mfd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (crl->monitors[1].path) {
|
||||
fDER = open(crl->monitors[1].path, O_EVTONLY);
|
||||
fDER = open(crl->monitors[1].path, XEVENT_MODE);
|
||||
if (fDER == -1) {
|
||||
CYASSL_MSG("DER event dir open failed");
|
||||
close(crl->mfd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +436,7 @@ static void* DoMonitor(void* arg)
|
|||
|
||||
for (;;) {
|
||||
struct kevent event;
|
||||
int numEvents = kevent(kq, &change, 1, &event, 1, NULL);
|
||||
int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
|
||||
|
||||
CYASSL_MSG("Got kevent");
|
||||
|
||||
|
@ -390,33 +445,77 @@ static void* DoMonitor(void* arg)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (event.filter == EVFILT_USER) {
|
||||
CYASSL_MSG("Got user shutdown event, breaking out");
|
||||
break;
|
||||
}
|
||||
|
||||
if (SwapLists(crl) < 0) {
|
||||
CYASSL_MSG("SwapLists problem, continue");
|
||||
}
|
||||
}
|
||||
|
||||
if (fPEM != -1)
|
||||
close(fPEM);
|
||||
if (fDER != -1)
|
||||
close(fDER);
|
||||
|
||||
close(crl->mfd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#elif __linux__
|
||||
#elif defined(__linux__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#ifndef max
|
||||
static INLINE int max(int a, int b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
#endif /* max */
|
||||
|
||||
|
||||
/* shutdown monitor thread, 0 on success */
|
||||
static int StopMonitor(int mfd)
|
||||
{
|
||||
word64 w64 = 1;
|
||||
|
||||
/* write to our custom event */
|
||||
if (write(mfd, &w64, sizeof(w64)) < 0) {
|
||||
CYASSL_MSG("StopMonitor write failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* linux monitoring */
|
||||
static void* DoMonitor(void* arg)
|
||||
{
|
||||
int notifyFd;
|
||||
int wd;
|
||||
int wd = -1;
|
||||
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
|
||||
|
||||
CYASSL_ENTER("DoMonitor");
|
||||
|
||||
crl->mfd = eventfd(0, 0); /* our custom shutdown event */
|
||||
if (crl->mfd < 0) {
|
||||
CYASSL_MSG("eventfd failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
notifyFd = inotify_init();
|
||||
if (notifyFd < 0) {
|
||||
CYASSL_MSG("inotify failed");
|
||||
close(crl->mfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -425,6 +524,8 @@ static void* DoMonitor(void* arg)
|
|||
IN_DELETE);
|
||||
if (wd < 0) {
|
||||
CYASSL_MSG("PEM notify add watch failed");
|
||||
close(crl->mfd);
|
||||
close(notifyFd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -434,16 +535,36 @@ static void* DoMonitor(void* arg)
|
|||
IN_DELETE);
|
||||
if (wd < 0) {
|
||||
CYASSL_MSG("DER notify add watch failed");
|
||||
close(crl->mfd);
|
||||
close(notifyFd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
char buffer[8192];
|
||||
int length = read(notifyFd, buffer, sizeof(buffer));
|
||||
fd_set readfds;
|
||||
char buff[8192];
|
||||
int result, length;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(notifyFd, &readfds);
|
||||
FD_SET(crl->mfd, &readfds);
|
||||
|
||||
result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);
|
||||
|
||||
CYASSL_MSG("Got notify event");
|
||||
|
||||
if (result < 0) {
|
||||
CYASSL_MSG("select problem, continue");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(crl->mfd, &readfds)) {
|
||||
CYASSL_MSG("got custom shutdown event, breaking out");
|
||||
break;
|
||||
}
|
||||
|
||||
length = read(notifyFd, buff, sizeof(buff));
|
||||
if (length < 0) {
|
||||
CYASSL_MSG("notify read problem, continue");
|
||||
continue;
|
||||
|
@ -454,10 +575,18 @@ static void* DoMonitor(void* arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (wd > 0)
|
||||
inotify_rm_watch(notifyFd, wd);
|
||||
close(crl->mfd);
|
||||
close(notifyFd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#error "CRL monitor only currently supported on linux or mach"
|
||||
|
||||
#endif /* MACH or linux */
|
||||
|
||||
|
@ -492,6 +621,8 @@ static int StartMonitorCRL(CYASSL_CRL* crl)
|
|||
|
||||
static int StartMonitorCRL(CYASSL_CRL* crl)
|
||||
{
|
||||
(void)crl;
|
||||
|
||||
CYASSL_ENTER("StartMonitorCRL");
|
||||
CYASSL_MSG("Not compiled in");
|
||||
|
||||
|
@ -518,8 +649,19 @@ int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
|
|||
return BAD_PATH_ERROR;
|
||||
}
|
||||
while ( (entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_type & DT_REG) {
|
||||
char name[MAX_FILENAME_SZ];
|
||||
char name[MAX_FILENAME_SZ];
|
||||
struct stat s;
|
||||
|
||||
XMEMSET(name, 0, sizeof(name));
|
||||
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
|
||||
XSTRNCAT(name, "/", 1);
|
||||
XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
|
||||
|
||||
if (stat(name, &s) != 0) {
|
||||
CYASSL_MSG("stat on name failed");
|
||||
continue;
|
||||
}
|
||||
if (s.st_mode & S_IFREG) {
|
||||
|
||||
if (type == SSL_FILETYPE_PEM) {
|
||||
if (strstr(entry->d_name, ".pem") == NULL) {
|
||||
|
@ -536,11 +678,6 @@ int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
|
|||
}
|
||||
}
|
||||
|
||||
XMEMSET(name, 0, sizeof(name));
|
||||
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
|
||||
XSTRNCAT(name, "/", 1);
|
||||
XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
|
||||
|
||||
if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
|
||||
!= SSL_SUCCESS) {
|
||||
CYASSL_MSG("CRL file load failed, continuing");
|
||||
|
@ -569,6 +706,8 @@ int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
|
|||
ret = StartMonitorCRL(crl);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3,39 +3,94 @@
|
|||
# All paths should be given relative to the root
|
||||
|
||||
lib_LTLIBRARIES+= src/libcyassl.la
|
||||
src_libcyassl_la_SOURCES = \
|
||||
src/internal.c \
|
||||
src/io.c \
|
||||
src/keys.c \
|
||||
src/ssl.c \
|
||||
src/tls.c \
|
||||
ctaocrypt/src/asn.c \
|
||||
ctaocrypt/src/coding.c \
|
||||
ctaocrypt/src/des3.c \
|
||||
ctaocrypt/src/hmac.c \
|
||||
ctaocrypt/src/md5.c \
|
||||
ctaocrypt/src/md4.c \
|
||||
ctaocrypt/src/random.c \
|
||||
ctaocrypt/src/rsa.c \
|
||||
ctaocrypt/src/sha.c \
|
||||
ctaocrypt/src/aes.c \
|
||||
ctaocrypt/src/sha256.c \
|
||||
ctaocrypt/src/dh.c \
|
||||
ctaocrypt/src/dsa.c \
|
||||
ctaocrypt/src/arc4.c \
|
||||
ctaocrypt/src/rabbit.c \
|
||||
ctaocrypt/src/pwdbased.c \
|
||||
ctaocrypt/src/logging.c \
|
||||
ctaocrypt/src/memory.c
|
||||
src_libcyassl_la_SOURCES =
|
||||
|
||||
if BUILD_FIPS
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/wolfcrypt_first.c
|
||||
endif
|
||||
|
||||
src_libcyassl_la_SOURCES += \
|
||||
src/internal.c \
|
||||
src/io.c \
|
||||
src/keys.c \
|
||||
src/ssl.c \
|
||||
src/tls.c \
|
||||
ctaocrypt/src/hmac.c \
|
||||
ctaocrypt/src/random.c \
|
||||
ctaocrypt/src/sha256.c \
|
||||
ctaocrypt/src/logging.c \
|
||||
ctaocrypt/src/wc_port.c \
|
||||
ctaocrypt/src/error.c
|
||||
src_libcyassl_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined -version-info ${CYASSL_LIBRARY_VERSION}
|
||||
src_libcyassl_la_LIBADD = $(LIBM)
|
||||
src_libcyassl_la_CFLAGS = -DBUILDING_CYASSL $(AM_CFLAGS)
|
||||
src_libcyassl_la_CPPFLAGS = -DBUILDING_CYASSL $(AM_CPPFLAGS)
|
||||
|
||||
if BUILD_MEMORY
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/memory.c
|
||||
endif
|
||||
|
||||
if BUILD_RSA
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/rsa.c
|
||||
endif
|
||||
|
||||
if BUILD_DH
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/dh.c
|
||||
endif
|
||||
|
||||
if BUILD_ASN
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/asn.c
|
||||
endif
|
||||
|
||||
if BUILD_FIPS
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/fips.c
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/fips_test.c
|
||||
endif
|
||||
|
||||
if BUILD_CODING
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/coding.c
|
||||
endif
|
||||
|
||||
if BUILD_AES
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/aes.c
|
||||
endif
|
||||
|
||||
if BUILD_DES3
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/des3.c
|
||||
endif
|
||||
|
||||
if BUILD_SHA
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/sha.c
|
||||
endif
|
||||
|
||||
if BUILD_RC4
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/arc4.c
|
||||
endif
|
||||
|
||||
if BUILD_MD4
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/md4.c
|
||||
endif
|
||||
|
||||
if BUILD_MD5
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/md5.c
|
||||
endif
|
||||
|
||||
if BUILD_PWDBASED
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/pwdbased.c
|
||||
endif
|
||||
|
||||
if BUILD_DSA
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/dsa.c
|
||||
endif
|
||||
|
||||
if BUILD_AESNI
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/aes_asm.s
|
||||
endif
|
||||
|
||||
if BUILD_CAMELLIA
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/camellia.c
|
||||
endif
|
||||
|
||||
if BUILD_MD2
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/md2.c
|
||||
endif
|
||||
|
@ -48,6 +103,10 @@ if BUILD_SHA512
|
|||
src_libcyassl_la_SOURCES += ctaocrypt/src/sha512.c
|
||||
endif
|
||||
|
||||
if BUILD_BLAKE2
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/blake2b.c
|
||||
endif
|
||||
|
||||
if BUILD_SNIFFER
|
||||
src_libcyassl_la_SOURCES += src/sniffer.c
|
||||
endif
|
||||
|
@ -56,13 +115,19 @@ if BUILD_HC128
|
|||
src_libcyassl_la_SOURCES += ctaocrypt/src/hc128.c
|
||||
endif
|
||||
|
||||
if BUILD_NOINLINE
|
||||
if BUILD_RABBIT
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/rabbit.c
|
||||
endif
|
||||
|
||||
if !BUILD_INLINE
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/misc.c
|
||||
endif
|
||||
|
||||
if BUILD_FASTMATH
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/tfm.c
|
||||
else
|
||||
endif
|
||||
|
||||
if BUILD_SLOWMATH
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/integer.c
|
||||
endif
|
||||
|
||||
|
@ -78,8 +143,15 @@ if BUILD_CRL
|
|||
src_libcyassl_la_SOURCES += src/crl.c
|
||||
endif
|
||||
|
||||
if BUILD_CRL_MONITOR
|
||||
src_libcyassl_la_CFLAGS += $(PTHREAD_CFLAGS)
|
||||
src_libcyassl_la_LIBADD += $(PTHREAD_LIBS)
|
||||
if BUILD_LIBZ
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/compress.c
|
||||
endif
|
||||
|
||||
if BUILD_PKCS7
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/pkcs7.c
|
||||
endif
|
||||
|
||||
if BUILD_FIPS
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/wolfcrypt_last.c
|
||||
endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/* ocsp.c
|
||||
*
|
||||
* Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
|
@ -16,50 +16,43 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
|
||||
#include <cyassl/error.h>
|
||||
#include <cyassl/error-ssl.h>
|
||||
#include <cyassl/ocsp.h>
|
||||
#include <cyassl/internal.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
CYASSL_API int ocsp_test(unsigned char* buf, int sz);
|
||||
#define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */
|
||||
#define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL
|
||||
* in certificate */
|
||||
|
||||
typedef struct sockaddr_in SOCKADDR_IN_T;
|
||||
#define AF_INET_V AF_INET
|
||||
#define SOCKET_T unsigned int
|
||||
|
||||
|
||||
int CyaSSL_OCSP_Init(CYASSL_OCSP* ocsp)
|
||||
int InitOCSP(CYASSL_OCSP* ocsp, CYASSL_CERT_MANAGER* cm)
|
||||
{
|
||||
if (ocsp != NULL) {
|
||||
XMEMSET(ocsp, 0, sizeof(*ocsp));
|
||||
return 0;
|
||||
}
|
||||
CYASSL_ENTER("InitOCSP");
|
||||
XMEMSET(ocsp, 0, sizeof(*ocsp));
|
||||
ocsp->cm = cm;
|
||||
if (InitMutex(&ocsp->ocspLock) != 0)
|
||||
return BAD_MUTEX_E;
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
|
||||
{
|
||||
CYASSL_ENTER("InitOCSP_Entry");
|
||||
|
||||
XMEMSET(ocspe, 0, sizeof(*ocspe));
|
||||
XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
|
||||
XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,354 +70,22 @@ static void FreeOCSP_Entry(OCSP_Entry* ocspe)
|
|||
}
|
||||
|
||||
|
||||
void CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp)
|
||||
void FreeOCSP(CYASSL_OCSP* ocsp, int dynamic)
|
||||
{
|
||||
OCSP_Entry* tmp = ocsp->ocspList;
|
||||
|
||||
ocsp->enabled = 0;
|
||||
CYASSL_ENTER("FreeOCSP");
|
||||
|
||||
while (tmp) {
|
||||
OCSP_Entry* next = tmp->next;
|
||||
FreeOCSP_Entry(tmp);
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
|
||||
tmp = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int decode_url(const char* url, int urlSz,
|
||||
char* outName, char* outPath, int* outPort)
|
||||
{
|
||||
if (outName != NULL && outPath != NULL && outPort != NULL)
|
||||
{
|
||||
if (url == NULL || urlSz == 0)
|
||||
{
|
||||
*outName = 0;
|
||||
*outPath = 0;
|
||||
*outPort = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, cur;
|
||||
|
||||
/* need to break the url down into scheme, address, and port */
|
||||
/* "http://example.com:8080/" */
|
||||
if (XSTRNCMP(url, "http://", 7) == 0) {
|
||||
cur = 7;
|
||||
} else cur = 0;
|
||||
|
||||
i = 0;
|
||||
while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
|
||||
outName[i++] = url[cur++];
|
||||
}
|
||||
outName[i] = 0;
|
||||
/* Need to pick out the path after the domain name */
|
||||
|
||||
if (cur < urlSz && url[cur] == ':') {
|
||||
char port[6];
|
||||
int j;
|
||||
i = 0;
|
||||
cur++;
|
||||
while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
|
||||
i < 6) {
|
||||
port[i++] = url[cur++];
|
||||
}
|
||||
|
||||
*outPort = 0;
|
||||
for (j = 0; j < i; j++) {
|
||||
if (port[j] < '0' || port[j] > '9') return -1;
|
||||
*outPort = (*outPort * 10) + (port[j] - '0');
|
||||
}
|
||||
}
|
||||
else
|
||||
*outPort = 80;
|
||||
|
||||
if (cur < urlSz && url[cur] == '/') {
|
||||
i = 0;
|
||||
while (cur < urlSz && url[cur] != 0 && i < 80) {
|
||||
outPath[i++] = url[cur++];
|
||||
}
|
||||
outPath[i] = 0;
|
||||
}
|
||||
else {
|
||||
outPath[0] = '/';
|
||||
outPath[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url)
|
||||
{
|
||||
if (ocsp != NULL) {
|
||||
int urlSz = strlen(url);
|
||||
decode_url(url, urlSz,
|
||||
ocsp->overrideName, ocsp->overridePath, &ocsp->overridePort);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void tcp_socket(SOCKET_T* sockfd, SOCKADDR_IN_T* addr,
|
||||
const char* peer, word16 port)
|
||||
{
|
||||
const char* host = peer;
|
||||
|
||||
/* peer could be in human readable form */
|
||||
if (peer != INADDR_ANY && isalpha(peer[0])) {
|
||||
struct hostent* entry = gethostbyname(peer);
|
||||
|
||||
if (entry) {
|
||||
struct sockaddr_in tmp;
|
||||
memset(&tmp, 0, sizeof(struct sockaddr_in));
|
||||
memcpy(&tmp.sin_addr.s_addr, entry->h_addr_list[0],
|
||||
entry->h_length);
|
||||
host = inet_ntoa(tmp.sin_addr);
|
||||
}
|
||||
else {
|
||||
CYASSL_MSG("no entry for host");
|
||||
}
|
||||
}
|
||||
|
||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
|
||||
memset(addr, 0, sizeof(SOCKADDR_IN_T));
|
||||
|
||||
addr->sin_family = AF_INET_V;
|
||||
addr->sin_port = htons(port);
|
||||
if (host == INADDR_ANY)
|
||||
addr->sin_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
addr->sin_addr.s_addr = inet_addr(host);
|
||||
}
|
||||
|
||||
|
||||
static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
|
||||
{
|
||||
SOCKADDR_IN_T addr;
|
||||
tcp_socket(sockfd, &addr, ip, port);
|
||||
|
||||
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) {
|
||||
CYASSL_MSG("tcp connect failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int build_http_request(const char* domainName, const char* path,
|
||||
int ocspReqSz, byte* buf, int bufSize)
|
||||
{
|
||||
return snprintf((char*)buf, bufSize,
|
||||
"POST %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: application/ocsp-request\r\n"
|
||||
"\r\n",
|
||||
path, domainName, ocspReqSz);
|
||||
}
|
||||
|
||||
|
||||
static int decode_http_response(byte* httpBuf, int httpBufSz, byte** dst)
|
||||
{
|
||||
int idx = 0;
|
||||
int stop = 0;
|
||||
int len = 0;
|
||||
byte* contentType = NULL;
|
||||
byte* contentLength = NULL;
|
||||
char* buf = (char*)httpBuf; /* kludge so I'm not constantly casting */
|
||||
|
||||
if (strncasecmp(buf, "HTTP/1", 6) != 0)
|
||||
return 0;
|
||||
|
||||
idx = 9; /* sets to the first byte after "HTTP/1.X ", which should be the
|
||||
* HTTP result code */
|
||||
|
||||
if (strncasecmp(&buf[idx], "200 OK", 6) != 0)
|
||||
return 0;
|
||||
|
||||
idx += 8;
|
||||
|
||||
while (idx < httpBufSz && !stop) {
|
||||
if (buf[idx] == '\r' && buf[idx+1] == '\n') {
|
||||
stop = 1;
|
||||
idx += 2;
|
||||
}
|
||||
else {
|
||||
if (contentType == NULL &&
|
||||
strncasecmp(&buf[idx], "Content-Type:", 13) == 0) {
|
||||
idx += 13;
|
||||
if (buf[idx] == ' ') idx++;
|
||||
if (strncasecmp(&buf[idx], "application/ocsp-response", 25) != 0)
|
||||
return 0;
|
||||
idx += 27;
|
||||
} else if (contentLength == NULL &&
|
||||
strncasecmp(&buf[idx], "Content-Length:", 15) == 0) {
|
||||
idx += 15;
|
||||
if (buf[idx] == ' ') idx++;
|
||||
while (buf[idx] >= '0' && buf[idx] <= '9' && idx < httpBufSz) {
|
||||
len = (len * 10) + (buf[idx] - '0');
|
||||
idx++;
|
||||
}
|
||||
idx += 2; /* skip the crlf */
|
||||
} else {
|
||||
/* Advance idx past the next \r\n */
|
||||
char* end = strstr(&buf[idx], "\r\n");
|
||||
idx = end - buf + 2;
|
||||
stop = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
*dst = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_IN_BUFFER);
|
||||
XMEMCPY(*dst, httpBuf + idx, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
|
||||
{
|
||||
CYASSL_ENTER("InitOCSP_Entry");
|
||||
|
||||
ocspe->next = NULL;
|
||||
XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
|
||||
XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
|
||||
ocspe->status = NULL;
|
||||
ocspe->totalStatus = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static OCSP_Entry* find_ocsp_entry(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
||||
{
|
||||
OCSP_Entry* entry = ocsp->ocspList;
|
||||
|
||||
while (entry)
|
||||
{
|
||||
if (XMEMCMP(entry->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
|
||||
&& XMEMCMP(entry->issuerKeyHash, cert->issuerKeyHash,
|
||||
SHA_DIGEST_SIZE) == 0)
|
||||
{
|
||||
CYASSL_MSG("Found OCSP responder");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
CYASSL_MSG("Add a new OCSP entry");
|
||||
entry = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
|
||||
NULL, DYNAMIC_TYPE_OCSP_ENTRY);
|
||||
if (entry != NULL)
|
||||
{
|
||||
InitOCSP_Entry(entry, cert);
|
||||
entry->next = ocsp->ocspList;
|
||||
ocsp->ocspList = entry;
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
static CertStatus* find_cert_status(OCSP_Entry* ocspe, DecodedCert* cert)
|
||||
{
|
||||
CertStatus* stat = ocspe->status;
|
||||
|
||||
while (stat)
|
||||
{
|
||||
if(stat->serialSz == cert->serialSz &&
|
||||
(XMEMCMP(stat->serial, cert->serial, cert->serialSz) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
stat = stat->next;
|
||||
}
|
||||
}
|
||||
if (stat == NULL)
|
||||
{
|
||||
stat = (CertStatus*)XMALLOC(sizeof(CertStatus),
|
||||
NULL, DYNAMIC_TYPE_OCSP_STATUS);
|
||||
if (stat != NULL)
|
||||
{
|
||||
XMEMCPY(stat->serial, cert->serial, cert->serialSz);
|
||||
stat->serialSz = cert->serialSz;
|
||||
stat->status = -1;
|
||||
stat->nextDate[0] = 0;
|
||||
ocspe->totalStatus++;
|
||||
|
||||
stat->next = ocspe->status;
|
||||
ocspe->status = stat;
|
||||
}
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
#define SCRATCH_BUFFER_SIZE 2048
|
||||
|
||||
static int http_ocsp_transaction(CYASSL_OCSP* ocsp, DecodedCert* cert,
|
||||
byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
|
||||
{
|
||||
SOCKET_T sfd = -1;
|
||||
byte httpBuf[SCRATCH_BUFFER_SIZE];
|
||||
int httpBufSz = SCRATCH_BUFFER_SIZE;
|
||||
char domainName[80], path[80];
|
||||
int port, ocspRespSz;
|
||||
|
||||
if (ocsp->useOverrideUrl || cert->extAuthInfo == NULL) {
|
||||
if (ocsp->overrideName != NULL) {
|
||||
XMEMCPY(domainName, ocsp->overrideName, 80);
|
||||
XMEMCPY(path, ocsp->overridePath, 80);
|
||||
port = ocsp->overridePort;
|
||||
} else
|
||||
return OCSP_NEED_URL;
|
||||
} else {
|
||||
if (!decode_url((const char*)cert->extAuthInfo, cert->extAuthInfoSz,
|
||||
domainName, path, &port))
|
||||
return OCSP_NEED_URL;
|
||||
}
|
||||
|
||||
httpBufSz = build_http_request(domainName, path, ocspReqSz,
|
||||
httpBuf, httpBufSz);
|
||||
|
||||
tcp_connect(&sfd, domainName, port);
|
||||
if (sfd > 0) {
|
||||
int written;
|
||||
written = write(sfd, httpBuf, httpBufSz);
|
||||
if (written == httpBufSz) {
|
||||
written = write(sfd, ocspReqBuf, ocspReqSz);
|
||||
if (written == ocspReqSz) {
|
||||
httpBufSz = read(sfd, httpBuf, SCRATCH_BUFFER_SIZE);
|
||||
if (httpBufSz > 0) {
|
||||
ocspRespSz = decode_http_response(httpBuf, httpBufSz,
|
||||
ocspRespBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(sfd);
|
||||
if (ocspRespSz == 0) {
|
||||
CYASSL_MSG("HTTP response was not OK, no OCSP response");
|
||||
return OCSP_LOOKUP_FAIL;
|
||||
}
|
||||
} else {
|
||||
CYASSL_MSG("OCSP Responder connection failed");
|
||||
return OCSP_LOOKUP_FAIL;
|
||||
}
|
||||
|
||||
return ocspRespSz;
|
||||
FreeMutex(&ocsp->ocspLock);
|
||||
if (dynamic)
|
||||
XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,98 +94,176 @@ static int xstat2err(int stat)
|
|||
switch (stat) {
|
||||
case CERT_GOOD:
|
||||
return 0;
|
||||
break;
|
||||
case CERT_REVOKED:
|
||||
return OCSP_CERT_REVOKED;
|
||||
break;
|
||||
default:
|
||||
return OCSP_CERT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
||||
int CheckCertOCSP(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
||||
{
|
||||
byte ocspReqBuf[SCRATCH_BUFFER_SIZE];
|
||||
int ocspReqSz = SCRATCH_BUFFER_SIZE;
|
||||
byte* ocspReqBuf = NULL;
|
||||
int ocspReqSz = 2048;
|
||||
byte* ocspRespBuf = NULL;
|
||||
int ocspRespSz;
|
||||
OcspRequest ocspRequest;
|
||||
OcspResponse ocspResponse;
|
||||
int result = 0;
|
||||
int result = -1;
|
||||
OCSP_Entry* ocspe;
|
||||
CertStatus* certStatus;
|
||||
CertStatus* certStatus = NULL;
|
||||
CertStatus newStatus;
|
||||
const char *url;
|
||||
int urlSz;
|
||||
|
||||
/* If OCSP lookups are disabled, return success. */
|
||||
if (!ocsp->enabled) {
|
||||
CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
|
||||
return 0;
|
||||
CYASSL_ENTER("CheckCertOCSP");
|
||||
|
||||
if (LockMutex(&ocsp->ocspLock) != 0) {
|
||||
CYASSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
ocspe = ocsp->ocspList;
|
||||
while (ocspe) {
|
||||
if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
|
||||
&& XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
|
||||
SHA_DIGEST_SIZE) == 0)
|
||||
break;
|
||||
else
|
||||
ocspe = ocspe->next;
|
||||
}
|
||||
|
||||
ocspe = find_ocsp_entry(ocsp, cert);
|
||||
if (ocspe == NULL) {
|
||||
CYASSL_MSG("alloc OCSP entry failed");
|
||||
return MEMORY_ERROR;
|
||||
ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
|
||||
NULL, DYNAMIC_TYPE_OCSP_ENTRY);
|
||||
if (ocspe != NULL) {
|
||||
InitOCSP_Entry(ocspe, cert);
|
||||
ocspe->next = ocsp->ocspList;
|
||||
ocsp->ocspList = ocspe;
|
||||
}
|
||||
else {
|
||||
UnLockMutex(&ocsp->ocspLock);
|
||||
CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
|
||||
return MEMORY_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
certStatus = ocspe->status;
|
||||
while (certStatus) {
|
||||
if (certStatus->serialSz == cert->serialSz &&
|
||||
XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
|
||||
break;
|
||||
else
|
||||
certStatus = certStatus->next;
|
||||
}
|
||||
}
|
||||
|
||||
certStatus = find_cert_status(ocspe, cert);
|
||||
if (certStatus == NULL)
|
||||
{
|
||||
CYASSL_MSG("alloc OCSP cert status failed");
|
||||
return MEMORY_ERROR;
|
||||
}
|
||||
|
||||
if (certStatus->status != -1)
|
||||
{
|
||||
if (certStatus != NULL) {
|
||||
if (!ValidateDate(certStatus->thisDate,
|
||||
certStatus->thisDateFormat, BEFORE) ||
|
||||
(certStatus->nextDate[0] == 0) ||
|
||||
!ValidateDate(certStatus->nextDate,
|
||||
certStatus->nextDateFormat, AFTER))
|
||||
{
|
||||
certStatus->nextDateFormat, AFTER)) {
|
||||
CYASSL_MSG("\tinvalid status date, looking up cert");
|
||||
certStatus->status = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CYASSL_MSG("\tusing cached status");
|
||||
else {
|
||||
result = xstat2err(certStatus->status);
|
||||
UnLockMutex(&ocsp->ocspLock);
|
||||
CYASSL_LEAVE("CheckCertOCSP", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
InitOcspRequest(&ocspRequest, cert, ocspReqBuf, ocspReqSz);
|
||||
ocspReqSz = EncodeOcspRequest(&ocspRequest);
|
||||
result = http_ocsp_transaction(ocsp, cert,
|
||||
ocspReqBuf, ocspReqSz, &ocspRespBuf);
|
||||
if (result < 0) return result;
|
||||
/* If the transaction failed, return that result. */
|
||||
|
||||
InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, ocspRespSz);
|
||||
OcspResponseDecode(&ocspResponse);
|
||||
UnLockMutex(&ocsp->ocspLock);
|
||||
|
||||
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
|
||||
CYASSL_MSG("OCSP Responder failure");
|
||||
result = OCSP_LOOKUP_FAIL;
|
||||
} else {
|
||||
if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0)
|
||||
{
|
||||
result = xstat2err(ocspResponse.status->status);
|
||||
}
|
||||
if (ocsp->cm->ocspUseOverrideURL) {
|
||||
url = ocsp->cm->ocspOverrideURL;
|
||||
if (url != NULL && url[0] != '\0')
|
||||
urlSz = (int)XSTRLEN(url);
|
||||
else
|
||||
{
|
||||
CYASSL_MSG("OCSP Response incorrect for Request");
|
||||
result = OCSP_LOOKUP_FAIL;
|
||||
}
|
||||
return OCSP_NEED_URL;
|
||||
}
|
||||
if (ocspReqBuf != NULL) {
|
||||
XFREE(ocspRespBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
|
||||
else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
|
||||
url = (const char *)cert->extAuthInfo;
|
||||
urlSz = cert->extAuthInfoSz;
|
||||
}
|
||||
else {
|
||||
/* cert doesn't have extAuthInfo, assuming CERT_GOOD */
|
||||
return 0;
|
||||
}
|
||||
|
||||
ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
|
||||
if (ocspReqBuf == NULL) {
|
||||
CYASSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
|
||||
return MEMORY_ERROR;
|
||||
}
|
||||
InitOcspRequest(&ocspRequest, cert, ocsp->cm->ocspSendNonce,
|
||||
ocspReqBuf, ocspReqSz);
|
||||
ocspReqSz = EncodeOcspRequest(&ocspRequest);
|
||||
|
||||
if (ocsp->cm->ocspIOCb)
|
||||
result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
|
||||
ocspReqBuf, ocspReqSz, &ocspRespBuf);
|
||||
|
||||
if (result >= 0 && ocspRespBuf) {
|
||||
XMEMSET(&newStatus, 0, sizeof(CertStatus));
|
||||
|
||||
InitOcspResponse(&ocspResponse, &newStatus, ocspRespBuf, result);
|
||||
OcspResponseDecode(&ocspResponse);
|
||||
|
||||
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL)
|
||||
result = OCSP_LOOKUP_FAIL;
|
||||
else {
|
||||
if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) {
|
||||
result = xstat2err(ocspResponse.status->status);
|
||||
|
||||
if (LockMutex(&ocsp->ocspLock) != 0)
|
||||
result = BAD_MUTEX_E;
|
||||
else {
|
||||
if (certStatus != NULL)
|
||||
/* Replace existing certificate entry with updated */
|
||||
XMEMCPY(certStatus, &newStatus, sizeof(CertStatus));
|
||||
else {
|
||||
/* Save new certificate entry */
|
||||
certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
|
||||
NULL, DYNAMIC_TYPE_OCSP_STATUS);
|
||||
if (certStatus != NULL) {
|
||||
XMEMCPY(certStatus, &newStatus, sizeof(CertStatus));
|
||||
certStatus->next = ocspe->status;
|
||||
ocspe->status = certStatus;
|
||||
ocspe->totalStatus++;
|
||||
}
|
||||
}
|
||||
|
||||
UnLockMutex(&ocsp->ocspLock);
|
||||
}
|
||||
}
|
||||
else
|
||||
result = OCSP_LOOKUP_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = OCSP_LOOKUP_FAIL;
|
||||
|
||||
if (ocspReqBuf != NULL)
|
||||
XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
|
||||
|
||||
if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
|
||||
ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);
|
||||
|
||||
CYASSL_LEAVE("CheckCertOCSP", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#else /* HAVE_OCSP */
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* 4206 warning for blank file */
|
||||
#pragma warning(disable: 4206)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HAVE_OCSP */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue