mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-11 13:54:16 -04:00
Add FreeRTOS-Plus directory with new directory structure so it matches the FreeRTOS directory.
This commit is contained in:
parent
80f7e8cdd4
commit
64a3ab321a
528 changed files with 228252 additions and 0 deletions
576
FreeRTOS-Plus/Source/CyaSSL/src/crl.c
Normal file
576
FreeRTOS-Plus/Source/CyaSSL/src/crl.c
Normal file
|
@ -0,0 +1,576 @@
|
|||
/* crl.c
|
||||
*
|
||||
* Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CRL
|
||||
|
||||
#include <cyassl/internal.h>
|
||||
#include <cyassl/error.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* 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;
|
||||
#endif
|
||||
if (InitMutex(&crl->crlLock) != 0)
|
||||
return BAD_MUTEX_ERROR;
|
||||
|
||||
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, MD5_DIGEST_SIZE);
|
||||
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)
|
||||
{
|
||||
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("Canceling monitor thread");
|
||||
pthread_cancel(crl->tid);
|
||||
}
|
||||
#endif
|
||||
FreeMutex(&crl->crlLock);
|
||||
}
|
||||
|
||||
|
||||
/* Is the cert ok with CRL, return 0 on success */
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
revoked = 1;
|
||||
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_ERROR;
|
||||
}
|
||||
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, 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);
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (LockMutex(&crl->crlLock) != 0) {
|
||||
CYASSL_MSG("LockMutex failed");
|
||||
FreeCRL(&tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
newList = tmp.crlList;
|
||||
|
||||
/* swap lists */
|
||||
tmp.crlList = crl->crlList;
|
||||
crl->crlList = newList;
|
||||
|
||||
UnLockMutex(&crl->crlLock);
|
||||
|
||||
FreeCRL(&tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __MACH__
|
||||
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/* OS X monitoring */
|
||||
static void* DoMonitor(void* arg)
|
||||
{
|
||||
int fPEM, fDER, kq;
|
||||
struct kevent change;
|
||||
|
||||
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
|
||||
|
||||
CYASSL_ENTER("DoMonitor");
|
||||
|
||||
kq = kqueue();
|
||||
if (kq == -1) {
|
||||
CYASSL_MSG("kqueue failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fPEM = -1;
|
||||
fDER = -1;
|
||||
|
||||
if (crl->monitors[0].path) {
|
||||
fPEM = open(crl->monitors[0].path, O_EVTONLY);
|
||||
if (fPEM == -1) {
|
||||
CYASSL_MSG("PEM event dir open failed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (crl->monitors[1].path) {
|
||||
fDER = open(crl->monitors[1].path, O_EVTONLY);
|
||||
if (fDER == -1) {
|
||||
CYASSL_MSG("DER event dir open failed");
|
||||
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(kq, &change, 1, &event, 1, NULL);
|
||||
|
||||
CYASSL_MSG("Got kevent");
|
||||
|
||||
if (numEvents == -1) {
|
||||
CYASSL_MSG("kevent problem, continue");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SwapLists(crl) < 0) {
|
||||
CYASSL_MSG("SwapLists problem, continue");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#elif __linux__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* linux monitoring */
|
||||
static void* DoMonitor(void* arg)
|
||||
{
|
||||
int notifyFd;
|
||||
int wd;
|
||||
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
|
||||
|
||||
CYASSL_ENTER("DoMonitor");
|
||||
|
||||
notifyFd = inotify_init();
|
||||
if (notifyFd < 0) {
|
||||
CYASSL_MSG("inotify failed");
|
||||
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");
|
||||
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");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
char buffer[8192];
|
||||
int length = read(notifyFd, buffer, sizeof(buffer));
|
||||
|
||||
CYASSL_MSG("Got notify event");
|
||||
|
||||
if (length < 0) {
|
||||
CYASSL_MSG("notify read problem, continue");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SwapLists(crl) < 0) {
|
||||
CYASSL_MSG("SwapLists problem, continue");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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)
|
||||
{
|
||||
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) {
|
||||
if (entry->d_type & DT_REG) {
|
||||
char name[MAX_FILENAME_SZ];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CRL */
|
85
FreeRTOS-Plus/Source/CyaSSL/src/include.am
Normal file
85
FreeRTOS-Plus/Source/CyaSSL/src/include.am
Normal file
|
@ -0,0 +1,85 @@
|
|||
# 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 = \
|
||||
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_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_AESNI
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/aes_asm.s
|
||||
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_SNIFFER
|
||||
src_libcyassl_la_SOURCES += src/sniffer.c
|
||||
endif
|
||||
|
||||
if BUILD_HC128
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/hc128.c
|
||||
endif
|
||||
|
||||
if BUILD_NOINLINE
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/misc.c
|
||||
endif
|
||||
|
||||
if BUILD_FASTMATH
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/tfm.c
|
||||
else
|
||||
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_CRL_MONITOR
|
||||
src_libcyassl_la_CFLAGS += $(PTHREAD_CFLAGS)
|
||||
src_libcyassl_la_LIBADD += $(PTHREAD_LIBS)
|
||||
endif
|
||||
|
7102
FreeRTOS-Plus/Source/CyaSSL/src/internal.c
Normal file
7102
FreeRTOS-Plus/Source/CyaSSL/src/internal.c
Normal file
File diff suppressed because it is too large
Load diff
273
FreeRTOS-Plus/Source/CyaSSL/src/io.c
Normal file
273
FreeRTOS-Plus/Source/CyaSSL/src/io.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
/* io.c
|
||||
*
|
||||
* Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
/* On WinCE winsock2.h must be included before windows.h for socket stuff */
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/internal.h>
|
||||
|
||||
/* if user writes own I/O callbacks they can define CYASSL_USER_IO to remove
|
||||
automatic setting of default I/O functions EmbedSend() and EmbedReceive()
|
||||
but they'll still need SetCallback xxx() at end of file
|
||||
*/
|
||||
#ifndef CYASSL_USER_IO
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
#ifdef CYASSL_LWIP
|
||||
/* lwIP needs to be configured to use sockets API in this mode */
|
||||
/* LWIP_SOCKET 1 && LWIP_COMPAT_SOCKETS 1 in lwip/opt.h or in build */
|
||||
#define LWIP_PROVIDE_ERRNO 1
|
||||
#include "sockets.h"
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#if !(defined(DEVKITPRO) || defined(THREADX))
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#ifdef __PPU
|
||||
#include <netex/errno.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef THREADX
|
||||
#include <socket.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
#ifdef __sun
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_API
|
||||
/* no epipe yet */
|
||||
#ifndef WSAEPIPE
|
||||
#define WSAEPIPE -12345
|
||||
#endif
|
||||
#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define SOCKET_EAGAIN WSAEWOULDBLOCK
|
||||
#define SOCKET_ECONNRESET WSAECONNRESET
|
||||
#define SOCKET_EINTR WSAEINTR
|
||||
#define SOCKET_EPIPE WSAEPIPE
|
||||
#elif defined(__PPU)
|
||||
#define SOCKET_EWOULDBLOCK SYS_NET_EWOULDBLOCK
|
||||
#define SOCKET_EAGAIN SYS_NET_EAGAIN
|
||||
#define SOCKET_ECONNRESET SYS_NET_ECONNRESET
|
||||
#define SOCKET_EINTR SYS_NET_EINTR
|
||||
#define SOCKET_EPIPE SYS_NET_EPIPE
|
||||
#else
|
||||
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
|
||||
#define SOCKET_EAGAIN EAGAIN
|
||||
#define SOCKET_ECONNRESET ECONNRESET
|
||||
#define SOCKET_EINTR EINTR
|
||||
#define SOCKET_EPIPE EPIPE
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
#ifdef DEVKITPRO
|
||||
/* from network.h */
|
||||
int net_send(int, const void*, int, unsigned int);
|
||||
int net_recv(int, void*, int, unsigned int);
|
||||
#define SEND_FUNCTION net_send
|
||||
#define RECV_FUNCTION net_recv
|
||||
#else
|
||||
#define SEND_FUNCTION send
|
||||
#define RECV_FUNCTION recv
|
||||
#endif
|
||||
|
||||
|
||||
static INLINE int LastError(void)
|
||||
{
|
||||
#ifdef USE_WINDOWS_API
|
||||
return WSAGetLastError();
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The receive embedded callback
|
||||
* return : nb bytes read, or error
|
||||
*/
|
||||
int EmbedReceive(char *buf, int sz, void *ctx)
|
||||
{
|
||||
int recvd;
|
||||
int err;
|
||||
int sd = *(int*)ctx;
|
||||
|
||||
recvd = RECV_FUNCTION(sd, (char *)buf, sz, 0);
|
||||
|
||||
if (recvd < 0) {
|
||||
err = LastError();
|
||||
CYASSL_MSG("Embed Receive error");
|
||||
|
||||
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
|
||||
CYASSL_MSG(" Would block");
|
||||
return IO_ERR_WANT_READ;
|
||||
}
|
||||
else if (err == SOCKET_ECONNRESET) {
|
||||
CYASSL_MSG(" Connection reset");
|
||||
return IO_ERR_CONN_RST;
|
||||
}
|
||||
else if (err == SOCKET_EINTR) {
|
||||
CYASSL_MSG(" Socket interrupted");
|
||||
return IO_ERR_ISR;
|
||||
}
|
||||
else {
|
||||
CYASSL_MSG(" General error");
|
||||
return IO_ERR_GENERAL;
|
||||
}
|
||||
}
|
||||
else if (recvd == 0) {
|
||||
CYASSL_MSG("Embed receive connection closed");
|
||||
return IO_ERR_CONN_CLOSE;
|
||||
}
|
||||
|
||||
return recvd;
|
||||
}
|
||||
|
||||
/* The send embedded callback
|
||||
* return : nb bytes sent, or error
|
||||
*/
|
||||
int EmbedSend(char *buf, int sz, void *ctx)
|
||||
{
|
||||
int sd = *(int*)ctx;
|
||||
int sent;
|
||||
int len = sz;
|
||||
int err;
|
||||
|
||||
sent = SEND_FUNCTION(sd, &buf[sz - len], len, 0);
|
||||
|
||||
if (sent < 0) {
|
||||
err = LastError();
|
||||
CYASSL_MSG("Embed Send error");
|
||||
|
||||
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
|
||||
CYASSL_MSG(" Would Block");
|
||||
return IO_ERR_WANT_WRITE;
|
||||
}
|
||||
else if (err == SOCKET_ECONNRESET) {
|
||||
CYASSL_MSG(" Connection reset");
|
||||
return IO_ERR_CONN_RST;
|
||||
}
|
||||
else if (err == SOCKET_EINTR) {
|
||||
CYASSL_MSG(" Socket interrupted");
|
||||
return IO_ERR_ISR;
|
||||
}
|
||||
else if (err == SOCKET_EPIPE) {
|
||||
CYASSL_MSG(" Socket EPIPE");
|
||||
return IO_ERR_CONN_CLOSE;
|
||||
}
|
||||
else {
|
||||
CYASSL_MSG(" General error");
|
||||
return IO_ERR_GENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
|
||||
#include <cyassl/ctaocrypt/sha.h>
|
||||
|
||||
/* The DTLS Generate Cookie callback
|
||||
* return : number of bytes copied into buf, or error
|
||||
*/
|
||||
int EmbedGenerateCookie(byte *buf, int sz, void *ctx)
|
||||
{
|
||||
CYASSL* ssl = (CYASSL*)ctx;
|
||||
int sd = ssl->wfd;
|
||||
struct sockaddr_storage peer;
|
||||
socklen_t peerSz = sizeof(peer);
|
||||
byte cookieSrc[sizeof(struct in6_addr) + sizeof(int)];
|
||||
int cookieSrcSz = 0;
|
||||
Sha sha;
|
||||
|
||||
getpeername(sd, (struct sockaddr*)&peer, &peerSz);
|
||||
|
||||
if (peer.ss_family == AF_INET) {
|
||||
struct sockaddr_in *s = (struct sockaddr_in*)&peer;
|
||||
|
||||
cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port);
|
||||
XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port));
|
||||
XMEMCPY(cookieSrc + sizeof(s->sin_port),
|
||||
&s->sin_addr, sizeof(struct in_addr));
|
||||
}
|
||||
else if (peer.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s = (struct sockaddr_in6*)&peer;
|
||||
|
||||
cookieSrcSz = sizeof(struct in6_addr) + sizeof(s->sin6_port);
|
||||
XMEMCPY(cookieSrc, &s->sin6_port, sizeof(s->sin6_port));
|
||||
XMEMCPY(cookieSrc + sizeof(s->sin6_port),
|
||||
&s->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, cookieSrc, cookieSrcSz);
|
||||
ShaFinal(&sha, buf);
|
||||
|
||||
return SHA_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
#endif /* CYASSL_DTLS */
|
||||
|
||||
|
||||
#endif /* CYASSL_USER_IO */
|
||||
|
||||
CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX *ctx, CallbackIORecv CBIORecv)
|
||||
{
|
||||
ctx->CBIORecv = CBIORecv;
|
||||
}
|
||||
|
||||
|
||||
CYASSL_API void CyaSSL_SetIOSend(CYASSL_CTX *ctx, CallbackIOSend CBIOSend)
|
||||
{
|
||||
ctx->CBIOSend = CBIOSend;
|
||||
}
|
||||
|
||||
|
||||
CYASSL_API void CyaSSL_SetIOReadCtx(CYASSL* ssl, void *rctx)
|
||||
{
|
||||
ssl->IOCB_ReadCtx = rctx;
|
||||
}
|
||||
|
||||
|
||||
CYASSL_API void CyaSSL_SetIOWriteCtx(CYASSL* ssl, void *wctx)
|
||||
{
|
||||
ssl->IOCB_WriteCtx = wctx;
|
||||
}
|
||||
|
1208
FreeRTOS-Plus/Source/CyaSSL/src/keys.c
Normal file
1208
FreeRTOS-Plus/Source/CyaSSL/src/keys.c
Normal file
File diff suppressed because it is too large
Load diff
530
FreeRTOS-Plus/Source/CyaSSL/src/ocsp.c
Normal file
530
FreeRTOS-Plus/Source/CyaSSL/src/ocsp.c
Normal file
|
@ -0,0 +1,530 @@
|
|||
/* ocsp.c
|
||||
*
|
||||
* Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
|
||||
#include <cyassl/error.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)
|
||||
{
|
||||
if (ocsp != NULL) {
|
||||
XMEMSET(ocsp, 0, sizeof(*ocsp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
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 CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp)
|
||||
{
|
||||
OCSP_Entry* tmp = ocsp->ocspList;
|
||||
|
||||
ocsp->enabled = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
byte ocspReqBuf[SCRATCH_BUFFER_SIZE];
|
||||
int ocspReqSz = SCRATCH_BUFFER_SIZE;
|
||||
byte* ocspRespBuf = NULL;
|
||||
int ocspRespSz;
|
||||
OcspRequest ocspRequest;
|
||||
OcspResponse ocspResponse;
|
||||
int result = 0;
|
||||
OCSP_Entry* ocspe;
|
||||
CertStatus* certStatus;
|
||||
|
||||
/* If OCSP lookups are disabled, return success. */
|
||||
if (!ocsp->enabled) {
|
||||
CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ocspe = find_ocsp_entry(ocsp, cert);
|
||||
if (ocspe == NULL) {
|
||||
CYASSL_MSG("alloc OCSP entry failed");
|
||||
return MEMORY_ERROR;
|
||||
}
|
||||
|
||||
certStatus = find_cert_status(ocspe, cert);
|
||||
if (certStatus == NULL)
|
||||
{
|
||||
CYASSL_MSG("alloc OCSP cert status failed");
|
||||
return MEMORY_ERROR;
|
||||
}
|
||||
|
||||
if (certStatus->status != -1)
|
||||
{
|
||||
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");
|
||||
certStatus->status = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CYASSL_MSG("\tusing cached status");
|
||||
result = xstat2err(certStatus->status);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
CYASSL_MSG("OCSP Response incorrect for Request");
|
||||
result = OCSP_LOOKUP_FAIL;
|
||||
}
|
||||
}
|
||||
if (ocspReqBuf != NULL) {
|
||||
XFREE(ocspRespBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_OCSP */
|
||||
|
2405
FreeRTOS-Plus/Source/CyaSSL/src/sniffer.c
Normal file
2405
FreeRTOS-Plus/Source/CyaSSL/src/sniffer.c
Normal file
File diff suppressed because it is too large
Load diff
7852
FreeRTOS-Plus/Source/CyaSSL/src/ssl.c
Normal file
7852
FreeRTOS-Plus/Source/CyaSSL/src/ssl.c
Normal file
File diff suppressed because it is too large
Load diff
531
FreeRTOS-Plus/Source/CyaSSL/src/tls.c
Normal file
531
FreeRTOS-Plus/Source/CyaSSL/src/tls.c
Normal file
|
@ -0,0 +1,531 @@
|
|||
/* tls.c
|
||||
*
|
||||
* Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ssl.h>
|
||||
#include <cyassl/internal.h>
|
||||
#include <cyassl/error.h>
|
||||
#include <cyassl/ctaocrypt/hmac.h>
|
||||
|
||||
|
||||
|
||||
#ifndef NO_TLS
|
||||
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
/* calculate XOR for TLSv1 PRF */
|
||||
static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
|
||||
{
|
||||
word32 i;
|
||||
|
||||
for (i = 0; i < digLen; i++)
|
||||
digest[i] = md5[i] ^ sha[i];
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
#define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE
|
||||
#else
|
||||
#define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
|
||||
#endif
|
||||
|
||||
/* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
|
||||
static void p_hash(byte* result, word32 resLen, const byte* secret,
|
||||
word32 secLen, const byte* seed, word32 seedLen, int hash)
|
||||
{
|
||||
word32 len = MD5_DIGEST_SIZE;
|
||||
word32 times;
|
||||
word32 lastLen;
|
||||
word32 lastTime;
|
||||
word32 i;
|
||||
word32 idx = 0;
|
||||
byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */
|
||||
byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */
|
||||
|
||||
Hmac hmac;
|
||||
|
||||
if (hash == md5_mac) {
|
||||
hash = MD5;
|
||||
}
|
||||
else if (hash == sha_mac) {
|
||||
len = SHA_DIGEST_SIZE;
|
||||
hash = SHA;
|
||||
} else if (hash == sha256_mac) {
|
||||
len = SHA256_DIGEST_SIZE;
|
||||
hash = SHA256;
|
||||
}
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (hash == sha384_mac)
|
||||
{
|
||||
len = SHA384_DIGEST_SIZE;
|
||||
hash = SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
times = resLen / len;
|
||||
lastLen = resLen % len;
|
||||
if (lastLen) times += 1;
|
||||
lastTime = times - 1;
|
||||
|
||||
HmacSetKey(&hmac, hash, secret, secLen);
|
||||
HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
|
||||
HmacFinal(&hmac, previous); /* A1 */
|
||||
|
||||
for (i = 0; i < times; i++) {
|
||||
HmacUpdate(&hmac, previous, len);
|
||||
HmacUpdate(&hmac, seed, seedLen);
|
||||
HmacFinal(&hmac, current);
|
||||
|
||||
if ( (i == lastTime) && lastLen)
|
||||
XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
|
||||
else {
|
||||
XMEMCPY(&result[idx], current, len);
|
||||
idx += len;
|
||||
HmacUpdate(&hmac, previous, len);
|
||||
HmacFinal(&hmac, previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* compute TLSv1 PRF (pseudo random function using HMAC) */
|
||||
static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
||||
const byte* label, word32 labLen, const byte* seed, word32 seedLen,
|
||||
int useAtLeastSha256, int hash_type)
|
||||
{
|
||||
word32 half = (secLen + 1) / 2;
|
||||
|
||||
byte md5_half[MAX_PRF_HALF]; /* half is real size */
|
||||
byte sha_half[MAX_PRF_HALF]; /* half is real size */
|
||||
byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
|
||||
byte md5_result[MAX_PRF_DIG]; /* digLen is real size */
|
||||
byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
|
||||
|
||||
if (half > MAX_PRF_HALF)
|
||||
return;
|
||||
if (labLen + seedLen > MAX_PRF_LABSEED)
|
||||
return;
|
||||
if (digLen > MAX_PRF_DIG)
|
||||
return;
|
||||
|
||||
XMEMCPY(md5_half, secret, half);
|
||||
XMEMCPY(sha_half, secret + half - secLen % 2, half);
|
||||
|
||||
XMEMCPY(labelSeed, label, labLen);
|
||||
XMEMCPY(labelSeed + labLen, seed, seedLen);
|
||||
|
||||
if (useAtLeastSha256) {
|
||||
/* If a cipher suite wants an algorithm better than sha256, it
|
||||
* should use better. */
|
||||
if (hash_type < sha256_mac)
|
||||
hash_type = sha256_mac;
|
||||
p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen,
|
||||
hash_type);
|
||||
return;
|
||||
}
|
||||
|
||||
p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen,
|
||||
md5_mac);
|
||||
p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen,
|
||||
sha_mac);
|
||||
get_xor(digest, digLen, md5_result, sha_result);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
#define HSHASH_SZ SHA384_DIGEST_SIZE
|
||||
#else
|
||||
#define HSHASH_SZ FINISHED_SZ
|
||||
#endif
|
||||
|
||||
|
||||
void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
{
|
||||
const byte* side;
|
||||
byte handshake_hash[HSHASH_SZ];
|
||||
word32 hashSz = FINISHED_SZ;
|
||||
|
||||
Md5Final(&ssl->hashMd5, handshake_hash);
|
||||
ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
#ifndef NO_SHA256
|
||||
if (ssl->specs.mac_algorithm <= sha256_mac) {
|
||||
Sha256Final(&ssl->hashSha256, handshake_hash);
|
||||
hashSz = SHA256_DIGEST_SIZE;
|
||||
}
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
if (ssl->specs.mac_algorithm == sha384_mac) {
|
||||
Sha384Final(&ssl->hashSha384, handshake_hash);
|
||||
hashSz = SHA384_DIGEST_SIZE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
|
||||
side = tls_client;
|
||||
else
|
||||
side = tls_server;
|
||||
|
||||
PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays.masterSecret, SECRET_LEN,
|
||||
side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl),
|
||||
ssl->specs.mac_algorithm);
|
||||
}
|
||||
|
||||
|
||||
ProtocolVersion MakeTLSv1(void)
|
||||
{
|
||||
ProtocolVersion pv;
|
||||
pv.major = SSLv3_MAJOR;
|
||||
pv.minor = TLSv1_MINOR;
|
||||
|
||||
return pv;
|
||||
}
|
||||
|
||||
|
||||
ProtocolVersion MakeTLSv1_1(void)
|
||||
{
|
||||
ProtocolVersion pv;
|
||||
pv.major = SSLv3_MAJOR;
|
||||
pv.minor = TLSv1_1_MINOR;
|
||||
|
||||
return pv;
|
||||
}
|
||||
|
||||
|
||||
ProtocolVersion MakeTLSv1_2(void)
|
||||
{
|
||||
ProtocolVersion pv;
|
||||
pv.major = SSLv3_MAJOR;
|
||||
pv.minor = TLSv1_2_MINOR;
|
||||
|
||||
return pv;
|
||||
}
|
||||
|
||||
|
||||
static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
|
||||
static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
|
||||
|
||||
|
||||
int DeriveTlsKeys(CYASSL* ssl)
|
||||
{
|
||||
int length = 2 * ssl->specs.hash_size +
|
||||
2 * ssl->specs.key_size +
|
||||
2 * ssl->specs.iv_size;
|
||||
byte seed[SEED_LEN];
|
||||
byte key_data[MAX_PRF_DIG];
|
||||
|
||||
XMEMCPY(seed, ssl->arrays.serverRandom, RAN_LEN);
|
||||
XMEMCPY(&seed[RAN_LEN], ssl->arrays.clientRandom, RAN_LEN);
|
||||
|
||||
PRF(key_data, length, ssl->arrays.masterSecret, SECRET_LEN, key_label,
|
||||
KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl),
|
||||
ssl->specs.mac_algorithm);
|
||||
|
||||
return StoreKeys(ssl, key_data);
|
||||
}
|
||||
|
||||
|
||||
int MakeTlsMasterSecret(CYASSL* ssl)
|
||||
{
|
||||
byte seed[SEED_LEN];
|
||||
|
||||
XMEMCPY(seed, ssl->arrays.clientRandom, RAN_LEN);
|
||||
XMEMCPY(&seed[RAN_LEN], ssl->arrays.serverRandom, RAN_LEN);
|
||||
|
||||
PRF(ssl->arrays.masterSecret, SECRET_LEN,
|
||||
ssl->arrays.preMasterSecret, ssl->arrays.preMasterSz,
|
||||
master_label, MASTER_LABEL_SZ,
|
||||
seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
|
||||
|
||||
#ifdef SHOW_SECRETS
|
||||
{
|
||||
int i;
|
||||
printf("master secret: ");
|
||||
for (i = 0; i < SECRET_LEN; i++)
|
||||
printf("%02x", ssl->arrays.masterSecret[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return DeriveTlsKeys(ssl);
|
||||
}
|
||||
|
||||
|
||||
/*** next for static INLINE s copied from cyassl_int.c ***/
|
||||
|
||||
/* convert 16 bit integer to opaque */
|
||||
INLINE static void c16toa(word16 u16, byte* c)
|
||||
{
|
||||
c[0] = (u16 >> 8) & 0xff;
|
||||
c[1] = u16 & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* convert 32 bit integer to opaque */
|
||||
static INLINE void c32toa(word32 u32, byte* c)
|
||||
{
|
||||
c[0] = (u32 >> 24) & 0xff;
|
||||
c[1] = (u32 >> 16) & 0xff;
|
||||
c[2] = (u32 >> 8) & 0xff;
|
||||
c[3] = u32 & 0xff;
|
||||
}
|
||||
|
||||
|
||||
static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
|
||||
{
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (verify)
|
||||
return ssl->keys.dtls_peer_sequence_number; /* explicit from peer */
|
||||
else
|
||||
return ssl->keys.dtls_sequence_number - 1; /* already incremented */
|
||||
}
|
||||
#endif
|
||||
if (verify)
|
||||
return ssl->keys.peer_sequence_number++;
|
||||
else
|
||||
return ssl->keys.sequence_number++;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
|
||||
static INLINE word32 GetEpoch(CYASSL* ssl, int verify)
|
||||
{
|
||||
if (verify)
|
||||
return ssl->keys.dtls_peer_epoch;
|
||||
else
|
||||
return ssl->keys.dtls_epoch;
|
||||
}
|
||||
|
||||
#endif /* CYASSL_DTLS */
|
||||
|
||||
|
||||
static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
|
||||
{
|
||||
if ( (ssl->options.side == CLIENT_END && !verify) ||
|
||||
(ssl->options.side == SERVER_END && verify) )
|
||||
return ssl->keys.client_write_MAC_secret;
|
||||
else
|
||||
return ssl->keys.server_write_MAC_secret;
|
||||
}
|
||||
|
||||
/*** end copy ***/
|
||||
|
||||
|
||||
/* TLS type HMAC */
|
||||
void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
|
||||
int content, int verify)
|
||||
{
|
||||
Hmac hmac;
|
||||
byte seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
byte length[LENGTH_SZ];
|
||||
byte inner[ENUM_LEN + VERSION_SZ + LENGTH_SZ]; /* type + version +len */
|
||||
int type;
|
||||
|
||||
c16toa((word16)sz, length);
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
c16toa(GetEpoch(ssl, verify), seq);
|
||||
#endif
|
||||
c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
|
||||
|
||||
if (ssl->specs.mac_algorithm == md5_mac)
|
||||
type = MD5;
|
||||
else if (ssl->specs.mac_algorithm == sha_mac)
|
||||
type = SHA;
|
||||
else
|
||||
type = SHA256;
|
||||
HmacSetKey(&hmac, type, GetMacSecret(ssl, verify), ssl->specs.hash_size);
|
||||
|
||||
HmacUpdate(&hmac, seq, SEQ_SZ); /* seq_num */
|
||||
inner[0] = (byte)content; /* type */
|
||||
inner[ENUM_LEN] = ssl->version.major;
|
||||
inner[ENUM_LEN + ENUM_LEN] = ssl->version.minor; /* version */
|
||||
XMEMCPY(&inner[ENUM_LEN + VERSION_SZ], length, LENGTH_SZ); /* length */
|
||||
HmacUpdate(&hmac, inner, sizeof(inner));
|
||||
HmacUpdate(&hmac, in, sz); /* content */
|
||||
HmacFinal(&hmac, digest);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_CYASSL_CLIENT
|
||||
|
||||
CYASSL_METHOD* CyaTLSv1_client_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method)
|
||||
InitSSL_Method(method, MakeTLSv1());
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
CYASSL_METHOD* CyaTLSv1_1_client_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method)
|
||||
InitSSL_Method(method, MakeTLSv1_1());
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_SHA256 /* can't use without SHA256 */
|
||||
|
||||
CYASSL_METHOD* CyaTLSv1_2_client_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method)
|
||||
InitSSL_Method(method, MakeTLSv1_2());
|
||||
return method;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
CYASSL_METHOD* CyaSSLv23_client_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method) {
|
||||
#ifndef NO_SHA256 /* 1.2 requires SHA256 */
|
||||
InitSSL_Method(method, MakeTLSv1_2());
|
||||
#else
|
||||
InitSSL_Method(method, MakeTLSv1_1());
|
||||
#endif
|
||||
method->downgrade = 1;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
#endif /* NO_CYASSL_CLIENT */
|
||||
|
||||
|
||||
|
||||
#ifndef NO_CYASSL_SERVER
|
||||
|
||||
CYASSL_METHOD* CyaTLSv1_server_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method) {
|
||||
InitSSL_Method(method, MakeTLSv1());
|
||||
method->side = SERVER_END;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
CYASSL_METHOD* CyaTLSv1_1_server_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method) {
|
||||
InitSSL_Method(method, MakeTLSv1_1());
|
||||
method->side = SERVER_END;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_SHA256 /* can't use without SHA256 */
|
||||
|
||||
CYASSL_METHOD* CyaTLSv1_2_server_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method) {
|
||||
InitSSL_Method(method, MakeTLSv1_2());
|
||||
method->side = SERVER_END;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
CYASSL_METHOD* CyaSSLv23_server_method(void)
|
||||
{
|
||||
CYASSL_METHOD* method =
|
||||
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
|
||||
DYNAMIC_TYPE_METHOD);
|
||||
if (method) {
|
||||
#ifndef NO_SHA256 /* 1.2 requires SHA256 */
|
||||
InitSSL_Method(method, MakeTLSv1_2());
|
||||
#else
|
||||
InitSSL_Method(method, MakeTLSv1_1());
|
||||
#endif
|
||||
method->side = SERVER_END;
|
||||
method->downgrade = 1;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* NO_CYASSL_SERVER */
|
||||
|
||||
#else /* NO_TLS */
|
||||
|
||||
/* catch CyaSSL programming errors */
|
||||
void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int DeriveTlsKeys(CYASSL* ssl)
|
||||
{
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
|
||||
|
||||
int MakeTlsMasterSecret(CYASSL* ssl)
|
||||
{
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
|
||||
#endif /* NO_TLS */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue