Rename the CyaSSL directory to WolfSSL

This commit is contained in:
Richard Barry 2015-08-28 13:27:31 +00:00
parent 1b010fbaa7
commit 8af1ad9bac
391 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,715 @@
/* crl.c
*
* Copyright (C) 2006-2014 wolfSSL Inc.
*
* This file is part of CyaSSL.
*
* CyaSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* CyaSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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., 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-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)
{
CYASSL_ENTER("InitCRL");
crl->cm = cm;
crl->crlList = NULL;
crl->monitors[0].path = NULL;
crl->monitors[1].path = NULL;
#ifdef HAVE_CRL_MONITOR
crl->tid = 0;
crl->mfd = -1; /* mfd for bsd is kqueue fd, eventfd for linux */
#endif
if (InitMutex(&crl->crlLock) != 0)
return BAD_MUTEX_E;
return 0;
}
/* Initialze CRL Entry */
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, 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;
crle->nextDateFormat = dcrl->nextDateFormat;
crle->certs = dcrl->certs; /* take ownsership */
dcrl->certs = NULL;
crle->totalCerts = dcrl->totalCerts;
return 0;
}
/* Free all CRL Entry resources */
static void FreeCRL_Entry(CRL_Entry* crle)
{
RevokedCert* tmp = crle->certs;
CYASSL_ENTER("FreeCRL_Entry");
while(tmp) {
RevokedCert* next = tmp->next;
XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
tmp = next;
}
}
/* Free all CRL resources */
void FreeCRL(CYASSL_CRL* crl, int dynamic)
{
CRL_Entry* tmp = crl->crlList;
CYASSL_ENTER("FreeCRL");
if (crl->monitors[0].path)
XFREE(crl->monitors[0].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
if (crl->monitors[1].path)
XFREE(crl->monitors[1].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
while(tmp) {
CRL_Entry* next = tmp->next;
FreeCRL_Entry(tmp);
XFREE(tmp, NULL, DYNAMIC_TYPE_CRL_ENTRY);
tmp = next;
}
#ifdef HAVE_CRL_MONITOR
if (crl->tid != 0) {
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);
}
/* Is the cert ok with CRL, return 0 on success */
int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert)
{
CRL_Entry* crle;
int foundEntry = 0;
int ret = 0;
CYASSL_ENTER("CheckCertCRL");
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
return BAD_MUTEX_E;
}
crle = crl->crlList;
while (crle) {
if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) {
CYASSL_MSG("Found CRL Entry on list");
CYASSL_MSG("Checking next date validity");
if (!ValidateDate(crle->nextDate, crle->nextDateFormat, AFTER)) {
CYASSL_MSG("CRL next date is no longer valid");
ret = ASN_AFTER_DATE_E;
}
else
foundEntry = 1;
break;
}
crle = crle->next;
}
if (foundEntry) {
RevokedCert* rc = crle->certs;
while (rc) {
if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
CYASSL_MSG("Cert revoked");
ret = CRL_CERT_REVOKED;
break;
}
rc = rc->next;
}
}
UnLockMutex(&crl->crlLock);
if (foundEntry == 0) {
CYASSL_MSG("Couldn't find CRL for status check");
ret = CRL_MISSING;
if (crl->cm->cbMissingCRL) {
char url[256];
CYASSL_MSG("Issuing missing CRL callback");
url[0] = '\0';
if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
url[cert->extCrlInfoSz] = '\0';
}
else {
CYASSL_MSG("CRL url too long");
}
crl->cm->cbMissingCRL(url);
}
}
return ret;
}
/* Add Decoded CRL, 0 on success */
static int AddCRL(CYASSL_CRL* crl, DecodedCRL* dcrl)
{
CRL_Entry* crle;
CYASSL_ENTER("AddCRL");
crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY);
if (crle == NULL) {
CYASSL_MSG("alloc CRL Entry failed");
return -1;
}
if (InitCRL_Entry(crle, dcrl) < 0) {
CYASSL_MSG("Init CRL Entry failed");
XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
return -1;
}
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
FreeCRL_Entry(crle);
XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
return BAD_MUTEX_E;
}
crle->next = crl->crlList;
crl->crlList = crle;
UnLockMutex(&crl->crlLock);
return 0;
}
/* Load CRL File of type, SSL_SUCCESS on ok */
int BufferLoadCRL(CYASSL_CRL* crl, const byte* buff, long sz, int type)
{
int ret = SSL_SUCCESS;
const byte* myBuffer = buff; /* if DER ok, otherwise switch */
buffer der;
DecodedCRL dcrl;
der.buffer = NULL;
CYASSL_ENTER("BufferLoadCRL");
if (crl == NULL || buff == NULL || sz == 0)
return BAD_FUNC_ARG;
if (type == SSL_FILETYPE_PEM) {
int eccKey = 0; /* not used */
EncryptedInfo info;
info.ctx = NULL;
ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
if (ret == 0) {
myBuffer = der.buffer;
sz = der.length;
}
else {
CYASSL_MSG("Pem to Der failed");
return -1;
}
}
InitDecodedCRL(&dcrl);
ret = ParseCRL(&dcrl, myBuffer, (word32)sz, crl->cm);
if (ret != 0) {
CYASSL_MSG("ParseCRL error");
}
else {
ret = AddCRL(crl, &dcrl);
if (ret != 0) {
CYASSL_MSG("AddCRL error");
}
}
FreeDecodedCRL(&dcrl);
if (der.buffer)
XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
if (ret == 0)
return SSL_SUCCESS; /* convert */
return ret;
}
#ifdef HAVE_CRL_MONITOR
/* read in new CRL entries and save new list */
static int SwapLists(CYASSL_CRL* crl)
{
int ret;
CYASSL_CRL tmp;
CRL_Entry* newList;
if (InitCRL(&tmp, crl->cm) < 0) {
CYASSL_MSG("Init tmp CRL failed");
return -1;
}
if (crl->monitors[0].path) {
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, 0);
return -1;
}
}
if (crl->monitors[1].path) {
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, 0);
return -1;
}
}
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
FreeCRL(&tmp, 0);
return -1;
}
newList = tmp.crlList;
/* swap lists */
tmp.crlList = crl->crlList;
crl->crlList = newList;
UnLockMutex(&crl->crlLock);
FreeCRL(&tmp, 0);
return 0;
}
#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;
struct kevent change;
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
CYASSL_ENTER("DoMonitor");
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, 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, XEVENT_MODE);
if (fDER == -1) {
CYASSL_MSG("DER event dir open failed");
close(crl->mfd);
return NULL;
}
}
if (fPEM != -1)
EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
if (fDER != -1)
EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
for (;;) {
struct kevent event;
int numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
CYASSL_MSG("Got kevent");
if (numEvents == -1) {
CYASSL_MSG("kevent problem, continue");
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 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 = -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;
}
if (crl->monitors[0].path) {
wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
IN_DELETE);
if (wd < 0) {
CYASSL_MSG("PEM notify add watch failed");
close(crl->mfd);
close(notifyFd);
return NULL;
}
}
if (crl->monitors[1].path) {
wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
IN_DELETE);
if (wd < 0) {
CYASSL_MSG("DER notify add watch failed");
close(crl->mfd);
close(notifyFd);
return NULL;
}
}
for (;;) {
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;
}
if (SwapLists(crl) < 0) {
CYASSL_MSG("SwapLists problem, continue");
}
}
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 */
/* Start Monitoring the CRL path(s) in a thread */
static int StartMonitorCRL(CYASSL_CRL* crl)
{
pthread_attr_t attr;
CYASSL_ENTER("StartMonitorCRL");
if (crl == NULL)
return BAD_FUNC_ARG;
if (crl->tid != 0) {
CYASSL_MSG("Monitor thread already running");
return MONITOR_RUNNING_E;
}
pthread_attr_init(&attr);
if (pthread_create(&crl->tid, &attr, DoMonitor, crl) != 0) {
CYASSL_MSG("Thread creation error");
return THREAD_CREATE_E;
}
return SSL_SUCCESS;
}
#else /* HAVE_CRL_MONITOR */
static int StartMonitorCRL(CYASSL_CRL* crl)
{
(void)crl;
CYASSL_ENTER("StartMonitorCRL");
CYASSL_MSG("Not compiled in");
return NOT_COMPILED_IN;
}
#endif /* HAVE_CRL_MONITOR */
/* Load CRL path files of type, SSL_SUCCESS on ok */
int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
{
struct dirent* entry;
DIR* dir;
int ret = SSL_SUCCESS;
CYASSL_ENTER("LoadCRL");
if (crl == NULL)
return BAD_FUNC_ARG;
dir = opendir(path);
if (dir == NULL) {
CYASSL_MSG("opendir path crl load failed");
return BAD_PATH_ERROR;
}
while ( (entry = readdir(dir)) != NULL) {
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) {
CYASSL_MSG("not .pem file, skipping");
continue;
}
}
else {
if (strstr(entry->d_name, ".der") == NULL &&
strstr(entry->d_name, ".crl") == NULL) {
CYASSL_MSG("not .der or .crl file, skipping");
continue;
}
}
if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
!= SSL_SUCCESS) {
CYASSL_MSG("CRL file load failed, continuing");
}
}
}
if (monitor & CYASSL_CRL_MONITOR) {
CYASSL_MSG("monitor path requested");
if (type == SSL_FILETYPE_PEM) {
crl->monitors[0].path = strdup(path);
crl->monitors[0].type = SSL_FILETYPE_PEM;
if (crl->monitors[0].path == NULL)
ret = MEMORY_E;
} else {
crl->monitors[1].path = strdup(path);
crl->monitors[1].type = SSL_FILETYPE_ASN1;
if (crl->monitors[1].path == NULL)
ret = MEMORY_E;
}
if (monitor & CYASSL_CRL_START_MON) {
CYASSL_MSG("start monitoring requested");
ret = StartMonitorCRL(crl);
}
}
closedir(dir);
return ret;
}
#endif /* HAVE_CRL */

View file

@ -0,0 +1,157 @@
# vim:ft=automake
# included from Top Level Makefile.am
# All paths should be given relative to the root
lib_LTLIBRARIES+= src/libcyassl.la
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
if BUILD_RIPEMD
src_libcyassl_la_SOURCES += ctaocrypt/src/ripemd.c
endif
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
if BUILD_HC128
src_libcyassl_la_SOURCES += ctaocrypt/src/hc128.c
endif
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
endif
if BUILD_SLOWMATH
src_libcyassl_la_SOURCES += ctaocrypt/src/integer.c
endif
if BUILD_ECC
src_libcyassl_la_SOURCES += ctaocrypt/src/ecc.c
endif
if BUILD_OCSP
src_libcyassl_la_SOURCES += src/ocsp.c
endif
if BUILD_CRL
src_libcyassl_la_SOURCES += src/crl.c
endif
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

View file

@ -0,0 +1,269 @@
/* ocsp.c
*
* Copyright (C) 2006-2014 wolfSSL Inc.
*
* This file is part of CyaSSL.
*
* CyaSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* CyaSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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., 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-ssl.h>
#include <cyassl/ocsp.h>
#include <cyassl/internal.h>
int InitOCSP(CYASSL_OCSP* ocsp, CYASSL_CERT_MANAGER* cm)
{
CYASSL_ENTER("InitOCSP");
XMEMSET(ocsp, 0, sizeof(*ocsp));
ocsp->cm = cm;
if (InitMutex(&ocsp->ocspLock) != 0)
return BAD_MUTEX_E;
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;
}
static void FreeOCSP_Entry(OCSP_Entry* ocspe)
{
CertStatus* tmp = ocspe->status;
CYASSL_ENTER("FreeOCSP_Entry");
while (tmp) {
CertStatus* next = tmp->next;
XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS);
tmp = next;
}
}
void FreeOCSP(CYASSL_OCSP* ocsp, int dynamic)
{
OCSP_Entry* tmp = ocsp->ocspList;
CYASSL_ENTER("FreeOCSP");
while (tmp) {
OCSP_Entry* next = tmp->next;
FreeOCSP_Entry(tmp);
XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
tmp = next;
}
FreeMutex(&ocsp->ocspLock);
if (dynamic)
XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP);
}
static int xstat2err(int stat)
{
switch (stat) {
case CERT_GOOD:
return 0;
case CERT_REVOKED:
return OCSP_CERT_REVOKED;
default:
return OCSP_CERT_UNKNOWN;
}
}
int CheckCertOCSP(CYASSL_OCSP* ocsp, DecodedCert* cert)
{
byte* ocspReqBuf = NULL;
int ocspReqSz = 2048;
byte* ocspRespBuf = NULL;
OcspRequest ocspRequest;
OcspResponse ocspResponse;
int result = -1;
OCSP_Entry* ocspe;
CertStatus* certStatus = NULL;
CertStatus newStatus;
const char *url;
int urlSz;
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;
}
if (ocspe == NULL) {
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;
}
}
if (certStatus != NULL) {
if (!ValidateDate(certStatus->thisDate,
certStatus->thisDateFormat, BEFORE) ||
(certStatus->nextDate[0] == 0) ||
!ValidateDate(certStatus->nextDate,
certStatus->nextDateFormat, AFTER)) {
CYASSL_MSG("\tinvalid status date, looking up cert");
}
else {
result = xstat2err(certStatus->status);
UnLockMutex(&ocsp->ocspLock);
CYASSL_LEAVE("CheckCertOCSP", result);
return result;
}
}
UnLockMutex(&ocsp->ocspLock);
if (ocsp->cm->ocspUseOverrideURL) {
url = ocsp->cm->ocspOverrideURL;
if (url != NULL && url[0] != '\0')
urlSz = (int)XSTRLEN(url);
else
return OCSP_NEED_URL;
}
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