1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

adding authentication, AES alignment issue, MACRO issue

git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@59 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
cameronrich 2007-02-07 12:22:35 +00:00
parent 9241353c50
commit 30a1970bb2
17 changed files with 401 additions and 263 deletions

12
CHANGELOG Normal file
View File

@ -0,0 +1,12 @@
Changes since 1.0.0
* AES should now work on 16bit processors (there was an alignment problem)
* Various freed objects are cleared before freeing.
* Header files now installed in /usr/local/include/axTLS
* -DCYGWIN replaced with -DCONFIG_PLATFORM_CYGWIN (and the same for solaris)
axhttpd Changes
* Header file issue fixed (in mime_types.c)
* chroot() now used for better security
* Authentication implemented
*

View File

@ -74,10 +74,20 @@ win32_demo:
install: $(PREFIX) all
cp --no-dereference $(STAGE)/libax* $(PREFIX)/lib
chmod 755 $(PREFIX)/lib/libax*
-install -m 755 $(STAGE)/ax* $(PREFIX)/bin > /dev/null 2>&1
-install -m 755 $(STAGE)/ax* $(PREFIX)/bin
ifdef CONFIG_PERL_BINDINGS
-install -m 755 $(STAGE)/axtlsp.pm `perl -e 'use Config; print $$Config{installarchlib};'` > /dev/null 2>&1
-install -m 755 $(STAGE)/axtlsp.pm `perl -e 'use Config; print $$Config{installarchlib};'`
endif
@mkdir -p -m 755 $(PREFIX)/include/axTLS
-install -m 644 ssl/bigint.h $(PREFIX)/include/axTLS
-install -m 644 ssl/bigint_impl.h $(PREFIX)/include/axTLS
-install -m 644 ssl/crypto.h $(PREFIX)/include/axTLS
-install -m 644 ssl/os_port.h $(PREFIX)/include/axTLS
-install -m 644 ssl/bigint.h $(PREFIX)/include/axTLS
-install -m 644 ssl/ssl.h $(PREFIX)/include/axTLS
-install -m 644 ssl/tls1.h $(PREFIX)/include/axTLS
-install -m 644 ssl/version.h $(PREFIX)/include/axTLS
-install -m 644 config/config.h $(PREFIX)/include/axTLS
installclean:
-@rm $(PREFIX)/lib/libax* > /dev/null 2>&1

View File

@ -79,7 +79,7 @@ LD=$(CC)
# Solaris
ifdef CONFIG_PLATFORM_SOLARIS
CFLAGS += -DSOLARIS
CFLAGS += -DCONFIG_PLATFORM_SOLARIS
LDFLAGS += -lsocket -lnsl -lc
LDSHARED = -G
# Linux/Cygwin
@ -89,7 +89,7 @@ LDSHARED = -shared
ifndef CONFIG_PLATFORM_CYGWIN
CFLAGS += -fPIC
else
CFLAGS += -DCYGWIN
CFLAGS += -DCONFIG_PLATFORM_CYGWIN
endif
endif

View File

@ -13,6 +13,14 @@ config CONFIG_HTTP_STATIC_BUILD
Select y if you want axhttp to be a static build (i.e. don't use the
axtls shared library or dll).
config CONFIG_HTTP_PORT
int "HTTP port"
default 80
help
The port number of the normal HTTP server.
You must be a root user in order to use the default port.
config CONFIG_HTTP_HTTPS_PORT
int "HTTPS port"
default 443
@ -39,14 +47,6 @@ config CONFIG_HTTP_WEBROOT
The location of the web root in relation to axhttpd. This is
the directory where index.html lives.
config CONFIG_HTTP_PORT
int "HTTP port"
default 80
help
The port number of the normal HTTP server.
You must be a root user in order to use the default port.
config CONFIG_HTTP_TIMEOUT
int "Timeout"
default 5
@ -79,6 +79,12 @@ config CONFIG_HTTP_PERM_CHECK
Enable permissions checking on the directories before reading the
files in them.
config CONFIG_HTTP_HAS_AUTHORIZATION
bool "Enable authorization"
default n
help
Pages/directories can have passwords associated with them.
config CONFIG_HTTP_HAS_IPV6
bool "Enable IPv6"
default n

View File

@ -54,7 +54,7 @@ else
web_server : $(TARGET)
OBJ= \
main.o \
axhttpd.o \
proc.o \
mime_types.o

View File

@ -77,6 +77,9 @@ struct connstruct
uint8_t is_ssl;
uint8_t close_when_done;
uint8_t modified_since;
#if defined(CONFIG_HTTP_HAS_AUTHORIZATION)
char authorization[MAXREQUESTLENGTH];
#endif
};
struct serverstruct
@ -103,9 +106,6 @@ extern struct connstruct *freeconns;
extern struct cgiextstruct *cgiexts;
#endif
// Conf global prototypes
extern char *webroot;
// conn.c prototypes
void removeconnection(struct connstruct *cn);

View File

@ -27,7 +27,6 @@
struct serverstruct *servers;
struct connstruct *usedconns;
struct connstruct *freeconns;
char *webroot = CONFIG_HTTP_WEBROOT;
static void addtoservers(int sd);
static int openlistener(int port);
@ -86,11 +85,12 @@ static void die(int sigtype)
int main(int argc, char *argv[])
{
static char *webroot = CONFIG_HTTP_WEBROOT;
fd_set rfds, wfds;
struct connstruct *tp, *to;
struct serverstruct *sp;
int rnum, wnum, active;
int webrootlen, i;
int i;
time_t currtime;
#ifdef WIN32
@ -98,12 +98,6 @@ int main(int argc, char *argv[])
WSADATA wsaData;
WSAStartup(wVersionRequested,&wsaData);
#else
if (getuid() == 0) /* change our uid if we are root */
{
setgid(32767);
setuid(32767);
}
signal(SIGQUIT, die);
signal(SIGPIPE, SIG_IGN);
#if defined(CONFIG_HTTP_HAS_CGI)
@ -122,12 +116,8 @@ int main(int argc, char *argv[])
freeconns->next = tp;
}
webrootlen = strlen(webroot);
if (webroot[webrootlen-1] == '/')
webroot[webrootlen-1] = '\0';
if (isdir(webroot) == 0)
/* change to webroot for better security */
if (chroot(webroot))
{
#ifdef CONFIG_HTTP_VERBOSE
fprintf(stderr, "'%s' is not a directory\n", webroot);
@ -135,6 +125,11 @@ int main(int argc, char *argv[])
exit(1);
}
#ifndef WIN32
setgid(32767);
setuid(32767);
#endif
if ((active = openlistener(CONFIG_HTTP_PORT)) == -1)
{
#ifdef CONFIG_HTTP_VERBOSE

View File

@ -20,7 +20,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "os_port.h"
#include "axhttp.h"
static const char mime_default[] = "text/plain";

View File

@ -29,8 +29,7 @@
static int special_read(struct connstruct *cn, void *buf, size_t count);
static int special_write(struct connstruct *cn,
const uint8_t *buf, size_t count);
static void send404(struct connstruct *cn);
static int procindex(struct connstruct *cn, struct stat *stp);
static void send_error(struct connstruct *cn, int err);
static int hexit(char c);
static void urldecode(char *buf);
static void buildactualfile(struct connstruct *cn);
@ -47,6 +46,9 @@ static int trycgi_withpathinfo(struct connstruct *cn);
static void split(char *tp, char *sp[], int maxwords, char sc);
static int iscgi(const char *fn);
#endif
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
static int auth_check(struct connstruct *cn);
#endif
/* Returns 1 if elems should continue being read, 0 otherwise */
static int procheadelem(struct connstruct *cn, char *buf)
@ -61,10 +63,11 @@ static int procheadelem(struct connstruct *cn, char *buf)
*delim = 0;
value = delim+1;
printf("BUF %s - value %s\n", buf, value);
if (strcmp(buf, "GET")==0 ||
strcmp(buf, "HEAD")==0 ||
strcmp(buf, "POST")==0)
if (strcmp(buf, "GET") == 0 ||
strcmp(buf, "HEAD") == 0 ||
strcmp(buf, "POST") == 0)
{
if (buf[0] == 'H')
cn->reqtype = TYPE_HEAD;
@ -79,8 +82,7 @@ static int procheadelem(struct connstruct *cn, char *buf)
if (sanitizefile(value) == 0)
{
send404(cn);
removeconnection(cn);
send_error(cn, 404);
return 0;
}
@ -98,7 +100,6 @@ static int procheadelem(struct connstruct *cn, char *buf)
{
if (sanitizehost(value) == 0)
{
send404(cn);
removeconnection(cn);
return 0;
}
@ -114,6 +115,15 @@ static int procheadelem(struct connstruct *cn, char *buf)
/* TODO: parse this date properly with getdate() or similar */
cn->modified_since = 1;
}
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
else if (strcmp(buf, "Authorization:") == 0 &&
strncmp(value, "Basic ", 6) == 0)
{
if (base64_decode(&value[6], strlen(&value[6]),
cn->authorization, NULL))
cn->authorization[0] = 0; /* error */
}
#endif
return 1;
}
@ -141,15 +151,13 @@ static void procdirlisting(struct connstruct *cn)
if (cn->dirp == INVALID_HANDLE_VALUE)
{
send404(cn);
removeconnection(cn);
send_error(cn, 404);
return;
}
#else
if ((cn->dirp = opendir(actualfile)) == NULL)
{
send404(cn);
removeconnection(cn);
send_error(cn, 404);
return;
}
@ -205,11 +213,16 @@ void procdodir(struct connstruct *cn)
if (file[0] == '.' && file[1] != '.')
continue;
/* make sure a '/' is at the end of a directory */
if (cn->filereq[strlen(cn->filereq)-1] != '/')
strcat(cn->filereq, "/");
/* see if the dir + file is another directory */
snprintf(buf, sizeof(buf), "%s%s", cn->actualfile, file);
if (isdir(buf))
strcat(file, "/");
urlencode(file, encbuf);
urlencode(file, encbuf);
snprintf(buf, sizeof(buf), "<a href=\"%s%s\">%s</a><br />\n",
cn->filereq, encbuf, file);
} while (special_write(cn, buf, strlen(buf)));
@ -263,6 +276,10 @@ void procreadhead(struct connstruct *cn)
buf[rv] = '\0';
next = tp = buf;
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
cn->authorization[0] = 0;
#endif
/* Split up lines and send to procheadelem() */
while (*next != '\0')
{
@ -297,22 +314,22 @@ void procreadhead(struct connstruct *cn)
*/
void procsendhead(struct connstruct *cn)
{
char buf[1024];
char actualfile[1024];
char buf[MAXREQUESTLENGTH];
struct stat stbuf;
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
char date[32];
strcpy(date, ctime(&now));
strcpy(actualfile, cn->actualfile);
#ifdef WIN32
/* stat() under win32 can't deal with trail slash */
if (actualfile[strlen(actualfile)-1] == '\\')
actualfile[strlen(actualfile)-1] = 0;
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
if (auth_check(cn))
{
removeconnection(cn);
return;
}
#endif
if (stat(actualfile, &stbuf) == -1)
strcpy(date, ctime(&now));
if (stat(cn->actualfile, &stbuf) == -1)
{
#if defined(CONFIG_HTTP_HAS_CGI)
if (trycgi_withpathinfo(cn) == 0)
@ -323,8 +340,7 @@ void procsendhead(struct connstruct *cn)
}
#endif
send404(cn);
removeconnection(cn);
send_error(cn, 404);
return;
}
@ -335,8 +351,7 @@ void procsendhead(struct connstruct *cn)
/* Set up CGI script */
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
{
send404(cn);
removeconnection(cn);
send_error(cn, 404);
return;
}
#endif
@ -346,17 +361,20 @@ void procsendhead(struct connstruct *cn)
}
#endif
/* look for "index.html"? */
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
{
/* Check to see if this dir has an index file */
if (procindex(cn, &stbuf) == 0)
char tbuf[MAXREQUESTLENGTH];
sprintf(tbuf, "%s%s", cn->actualfile, "index.html");
if (stat(tbuf, &stbuf) != -1)
strcat(cn->actualfile, "index.html");
else
{
#if defined(CONFIG_HTTP_DIRECTORIES)
/* If not, we do a directory listing of it */
procdirlisting(cn);
#else
send404(cn);
removeconnection(cn);
send_error(cn, 404);
#endif
return;
}
@ -368,8 +386,7 @@ void procsendhead(struct connstruct *cn)
/* Set up CGI script */
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
{
send404(cn);
removeconnection(cn);
send_error(cn, 404);
return;
}
@ -412,14 +429,14 @@ void procsendhead(struct connstruct *cn)
else
{
int flags = O_RDONLY;
#if defined(WIN32) || defined(CYGWIN)
#if defined(WIN32) || defined(CONFIG_PLATFORM_CYGWIN)
flags |= O_BINARY;
#endif
cn->filedesc = open(cn->actualfile, flags);
if (cn->filedesc == -1)
{
send404(cn);
send_error(cn, 404);
removeconnection(cn);
return;
}
@ -515,23 +532,6 @@ static int special_read(struct connstruct *cn, void *buf, size_t count)
return res;
}
/* Returns 0 if no index was found and doesn't modify cn->actualfile
Returns 1 if an index was found and puts the index in cn->actualfile
and puts its stat info into stp */
static int procindex(struct connstruct *cn, struct stat *stp)
{
char tbuf[MAXREQUESTLENGTH];
sprintf(tbuf, "%s%s", cn->actualfile, "index.html");
if (stat(tbuf, stp) != -1)
{
my_strncpy(cn->actualfile, tbuf, MAXREQUESTLENGTH);
return 1;
}
return 0;
}
#if defined(CONFIG_HTTP_HAS_CGI)
static void proccgi(struct connstruct *cn, int has_pathinfo)
{
@ -651,8 +651,8 @@ static int trycgi_withpathinfo(struct connstruct *cn)
while (fr_rs[i] != NULL)
{
snprintf(tpfile, sizeof(tpfile), "%s/%s%s",
webroot, cn->virtualhostreq, fr_str);
snprintf(tpfile, sizeof(tpfile), "/%s%s",
cn->virtualhostreq, fr_str);
if (iscgi(tpfile) && isdir(tpfile) == 0)
{
@ -782,18 +782,9 @@ static int hexit(char c)
return 0;
}
static void send404(struct connstruct *cn)
{
char buf[1024];
strcpy(buf, "HTTP/1.0 404 Not Found\nContent-Type: text/html\n\n"
"<html><body>\n<title>404 Not Found</title><h1>"
"404 Not Found</h1>\n</body></html>\n");
special_write(cn, buf, strlen(buf));
}
static void buildactualfile(struct connstruct *cn)
{
snprintf(cn->actualfile, MAXREQUESTLENGTH, "%s%s", webroot, cn->filereq);
snprintf(cn->actualfile, MAXREQUESTLENGTH, "%s", cn->filereq);
/* Add directory slash if not there */
if (isdir(cn->actualfile) &&
@ -805,10 +796,8 @@ static void buildactualfile(struct connstruct *cn)
{
char *t = cn->actualfile;
while ((t = strchr(t, '/')))
{
*t++ = '\\';
}
}
#endif
}
@ -855,3 +844,146 @@ static int sanitizehost(char *buf)
return 1;
}
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
#define AUTH_FILE ".htpasswd"
static void send_authenticate(struct connstruct *cn, const char *realm)
{
char buf[1024];
snprintf(buf, sizeof(buf), "HTTP/1.1 401 Unauthorized\n"
"WWW-Authenticate: Basic\n"
"realm=\"%s\"\n", realm);
special_write(cn, buf, strlen(buf));
}
static int check_digest(char *b64_file_passwd, const char *msg_passwd)
{
uint8_t real_salt[MAXREQUESTLENGTH];
uint8_t real_passwd[MAXREQUESTLENGTH];
int real_passwd_size, real_salt_size;
char *b64_pwd;
uint8_t md5_result[MD5_SIZE];
MD5_CTX ctx;
/* retrieve the salt */
if ((b64_pwd = strchr(b64_file_passwd, '$')) == NULL)
return -1;
*b64_pwd++ = 0;
if (base64_decode(b64_file_passwd, strlen(b64_file_passwd),
real_salt, &real_salt_size))
return -1;
if (base64_decode(b64_pwd, strlen(b64_pwd), real_passwd, &real_passwd_size))
return -1;
/* very simple MD5 crypt algorithm, but then the salt we use is large */
MD5Init(&ctx);
MD5Update(&ctx, real_salt, real_salt_size); /* process the salt */
MD5Update(&ctx, msg_passwd, strlen(msg_passwd)); /* process the password */
MD5Final(&ctx, md5_result);
return memcmp(md5_result, real_passwd, MD5_SIZE);/* 0 = ok */
}
static int auth_check(struct connstruct *cn)
{
char dirname[MAXREQUESTLENGTH];
char authpath[MAXREQUESTLENGTH];
char line[MAXREQUESTLENGTH];
char *cp;
FILE *fp = NULL;
struct stat auth_stat;
strncpy(dirname, cn->actualfile, MAXREQUESTLENGTH);
cp = strrchr(dirname, '/');
if (cp == NULL)
dirname[0] = 0;
else
*cp = 0;
/* check that the file is not the AUTH_FILE itself */
if (strcmp(cn->actualfile, AUTH_FILE) == 0)
{
send_error(cn, 403);
goto error;
}
snprintf(authpath, MAXREQUESTLENGTH, "%s/%s", dirname, AUTH_FILE);
if (stat(authpath, &auth_stat) < 0) /* no auth file, so let though */
return 0;
if (cn->authorization[0] == 0)
{
send_authenticate(cn, dirname);
return -1;
}
/* cn->authorization is in form "username:password" */
if ((cp = strchr(cn->authorization, ':')) == NULL)
goto error;
else
*cp++ = 0; /* cp becomes the password */
fp = fopen(authpath, "r");
while (fgets(line, sizeof(line), fp) != NULL)
{
char *b64_file_passwd;
int l = strlen(line);
/* nuke newline */
if (line[l-1] == '\n')
line[l-1] = 0;
/* line is form "username:salt(b64)$password(b64)" */
if ((b64_file_passwd = strchr(line, ':')) == NULL)
continue;
*b64_file_passwd++ = 0;
if (strcmp(line, cn->authorization)) /* our user? */
continue;
if (check_digest(b64_file_passwd, cp) == 0)
{
fclose(fp);
return 0;
}
}
fclose(fp);
error:
send_authenticate(cn, dirname);
return -1;
}
#endif
static void send_error(struct connstruct *cn, int err)
{
char buf[1024];
char *title;
char *text;
switch (err)
{
case 403:
title = "Forbidden";
text = "File is protected";
break;
case 404:
title = "Not Found";
text = title;
break;
}
sprintf(buf, "HTTP/1.1 %d %s\nContent-Type: text/html\n"
"<html><body>\n<title>%d %s</title>"
"<h1>%d %s</h1>\n</body></html>\n",
err, title, err, title, err, text);
special_write(cn, buf, strlen(buf));
removeconnection(cn);
}

View File

@ -59,7 +59,7 @@ int main(int argc, char *argv[])
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
WSAStartup(wVersionRequested, &wsaData);
#elif !defined(SOLARIS)
#elif !defined(CONFIG_PLATFORM_SOLARIS)
signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */
#endif

141
ssl/aes.c
View File

@ -62,10 +62,6 @@
(f8)^=rot2(f4), \
(f8)^rot1(f9))
/* some macros to do endian independent byte extraction */
#define n2l(c,l) l=ntohl(*c); c++
#define l2n(l,c) *c++=htonl(l)
/*
* AES S-box
*/
@ -249,7 +245,7 @@ void AES_convert_key(AES_CTX *ctx)
k = ctx->ks;
k += 4;
for (i=ctx->rounds*4; i>4; i--)
for (i= ctx->rounds*4; i > 4; i--)
{
w= *k;
w = inv_mix_col(w,t1,t2,t3,t4);
@ -262,46 +258,38 @@ void AES_convert_key(AES_CTX *ctx)
*/
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{
uint32_t tin0, tin1, tin2, tin3;
uint32_t tout0, tout1, tout2, tout3;
uint32_t tin[4];
uint32_t *iv = (uint32_t *)ctx->iv;
uint32_t *msg_32 = (uint32_t *)msg;
uint32_t *out_32 = (uint32_t *)out;
int i;
uint32_t tin[4], tout[4], iv[4];
n2l(iv, tout0);
n2l(iv, tout1);
n2l(iv, tout2);
n2l(iv, tout3);
iv -= 4;
memcpy(iv, ctx->iv, AES_IV_SIZE);
for (i = 0; i < 4; i++)
tout[i] = ntohl(iv[i]);
for (length -= 16; length >= 0; length -= 16)
for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
{
n2l(msg_32, tin0);
n2l(msg_32, tin1);
n2l(msg_32, tin2);
n2l(msg_32, tin3);
tin[0] = tin0^tout0;
tin[1] = tin1^tout1;
tin[2] = tin2^tout2;
tin[3] = tin3^tout3;
uint32_t msg_32[4];
uint32_t out_32[4];
memcpy(msg_32, msg, AES_BLOCKSIZE);
msg += AES_BLOCKSIZE;
for (i = 0; i < 4; i++)
tin[i] = ntohl(msg_32[i])^tout[i];
AES_encrypt(ctx, tin);
tout0 = tin[0];
l2n(tout0, out_32);
tout1 = tin[1];
l2n(tout1, out_32);
tout2 = tin[2];
l2n(tout2, out_32);
tout3 = tin[3];
l2n(tout3, out_32);
for (i = 0; i < 4; i++)
{
tout[i] = tin[i];
out_32[i] = htonl(tout[i]);
}
l2n(tout0, iv);
l2n(tout1, iv);
l2n(tout2, iv);
l2n(tout3, iv);
memcpy(out, out_32, AES_BLOCKSIZE);
out += AES_BLOCKSIZE;
}
for (i = 0; i < 4; i++)
iv[i] = htonl(tout[i]);
memcpy(ctx->iv, iv, AES_IV_SIZE);
}
/**
@ -309,54 +297,42 @@ void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
*/
void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{
uint32_t tin0, tin1, tin2, tin3;
uint32_t xor0,xor1,xor2,xor3;
uint32_t tout0,tout1,tout2,tout3;
uint32_t data[4];
uint32_t *iv = (uint32_t *)ctx->iv;
uint32_t *msg_32 = (uint32_t *)msg;
uint32_t *out_32 = (uint32_t *)out;
int i;
uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
n2l(iv ,xor0);
n2l(iv, xor1);
n2l(iv, xor2);
n2l(iv, xor3);
iv -= 4;
memcpy(iv, ctx->iv, AES_IV_SIZE);
for (i = 0; i < 4; i++)
xor[i] = ntohl(iv[i]);
for (length-=16; length >= 0; length -= 16)
for (length -= 16; length >= 0; length -= 16)
{
n2l(msg_32, tin0);
n2l(msg_32, tin1);
n2l(msg_32, tin2);
n2l(msg_32, tin3);
uint32_t msg_32[4];
uint32_t out_32[4];
memcpy(msg_32, msg, AES_BLOCKSIZE);
msg += AES_BLOCKSIZE;
data[0] = tin0;
data[1] = tin1;
data[2] = tin2;
data[3] = tin3;
for (i = 0; i < 4; i++)
{
tin[i] = ntohl(msg_32[i]);
data[i] = tin[i];
}
AES_decrypt(ctx, data);
tout0 = data[0]^xor0;
tout1 = data[1]^xor1;
tout2 = data[2]^xor2;
tout3 = data[3]^xor3;
xor0 = tin0;
xor1 = tin1;
xor2 = tin2;
xor3 = tin3;
l2n(tout0, out_32);
l2n(tout1, out_32);
l2n(tout2, out_32);
l2n(tout3, out_32);
for (i = 0; i < 4; i++)
{
tout[i] = data[i]^xor[i];
xor[i] = tin[i];
out_32[i] = htonl(tout[i]);
}
l2n(xor0, iv);
l2n(xor1, iv);
l2n(xor2, iv);
l2n(xor3, iv);
memcpy(out, out_32, AES_BLOCKSIZE);
out += AES_BLOCKSIZE;
}
for (i = 0; i < 4; i++)
iv[i] = htonl(xor[i]);
memcpy(ctx->iv, iv, AES_IV_SIZE);
}
/**
@ -375,9 +351,7 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
/* Pre-round key addition */
for (row = 0; row < 4; row++)
{
data[row] ^= *(k++);
}
/* Encrypt one block. */
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
@ -395,7 +369,6 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
{
tmp1 = a0 ^ a1 ^ a2 ^ a3;
old_a0 = a0;
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
@ -408,10 +381,8 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
/* KeyAddition - note that it is vital that this loop is separate from
the MixColumn operation, which must be atomic...*/
for (row = 0; row < 4; row++)
{
data[row] = tmp[row] ^ *(k++);
}
}
}
/**
@ -424,16 +395,14 @@ static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
uint32_t a0, a1, a2, a3, row;
int curr_rnd;
int rounds = ctx->rounds;
uint32_t *k = (uint32_t*)ctx->ks + ((rounds+1)*4);
const uint32_t *k = ctx->ks + ((rounds+1)*4);
/* pre-round key addition */
for (row=4; row > 0;row--)
{
data[row-1] ^= *(--k);
}
/* Decrypt one block */
for (curr_rnd=0; curr_rnd < rounds; curr_rnd++)
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
{
/* Perform ByteSub and ShiftRow operations together */
for (row = 4; row > 0; row--)
@ -468,10 +437,8 @@ static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
}
for (row = 4; row > 0; row--)
{
data[row-1] = tmp[row-1] ^ *(--k);
}
}
}
#endif

View File

@ -34,13 +34,15 @@ extern "C" {
**************************************************************************/
#define AES_MAXROUNDS 14
#define AES_BLOCKSIZE 16
#define AES_IV_SIZE 16
typedef struct aes_key_st
{
uint16_t rounds;
uint16_t key_size;
uint32_t ks[(AES_MAXROUNDS+1)*8];
uint8_t iv[16];
uint8_t iv[AES_IV_SIZE];
} AES_CTX;
typedef enum
@ -106,9 +108,9 @@ typedef struct
uint8_t buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, const uint8_t *msg, int len);
void MD5Final(MD5_CTX *, uint8_t *digest);
EXP_FUNC void STDCALL MD5Init(MD5_CTX *);
EXP_FUNC void STDCALL MD5Update(MD5_CTX *, const uint8_t *msg, int len);
EXP_FUNC void STDCALL MD5Final(MD5_CTX *, uint8_t *digest);
/**************************************************************************
* HMAC declarations
@ -273,6 +275,9 @@ void print_blob(const char *format, const uint8_t *data, int size, ...);
#define print_blob(...)
#endif
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
uint8_t *out, int *outlen);
#ifdef __cplusplus
}
#endif

View File

@ -267,3 +267,78 @@ void print_blob(const char *format,
void print_blob(const char *format, const unsigned char *data,
int size, ...) {}
#endif
#if defined(CONFIG_SSL_HAS_PEM) || defined(CONFIG_HTTP_HAS_AUTHORIZATION)
/* base64 to binary lookup table */
static const uint8_t map[128] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255
};
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
uint8_t *out, int *outlen)
{
int g, t, x, y, z;
uint8_t c;
int ret = -1;
g = 3;
for (x = y = z = t = 0; x < len; x++)
{
if ((c = map[in[x]&0x7F]) == 0xff)
continue;
if (c == 254) /* this is the end... */
{
c = 0;
if (--g < 0)
goto error;
}
else if (g != 3) /* only allow = at end */
goto error;
t = (t<<6) | c;
if (++y == 4)
{
out[z++] = (uint8_t)((t>>16)&255);
if (g > 1)
out[z++] = (uint8_t)((t>>8)&255);
if (g > 2)
out[z++] = (uint8_t)(t&255);
y = t = 0;
}
}
if (y != 0)
goto error;
if (outlen)
*outlen = z;
ret = 0;
error:
#ifdef CONFIG_SSL_FULL_MODE
if (ret < 0)
printf("Error: Invalid base64\n"); TTY_FLUSH();
#endif
TTY_FLUSH();
return ret;
}
#endif

View File

@ -169,22 +169,6 @@ void ssl_obj_free(SSLObjLoader *ssl_obj)
#define IS_ENCRYPTED_PRIVATE_KEY 1
#define IS_CERTIFICATE 2
/* base64 to binary lookup table */
static const uint8_t map[128] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255
};
static const char * const begins[NUM_PEM_TYPES] =
{
"-----BEGIN RSA PRIVATE KEY-----",
@ -205,59 +189,6 @@ static const char * const aes_str[2] =
"DEK-Info: AES-256-CBC,"
};
static int base64_decode(const uint8_t *in, int len,
uint8_t *out, int *outlen)
{
int g, t, x, y, z;
uint8_t c;
int ret = -1;
g = 3;
for (x = y = z = t = 0; x < len; x++)
{
if ((c = map[in[x] & 0x7F]) == 0xff)
continue;
if (c == 254) /* this is the end... */
{
c = 0;
if (--g < 0)
goto error;
}
else if (g != 3) /* only allow = at end */
goto error;
t = (t<<6) | c;
if (++y == 4)
{
out[z++] = (uint8_t)((t>>16)&255);
if (g > 1)
out[z++] = (uint8_t)((t>>8)&255);
if (g > 2)
out[z++] = (uint8_t)(t&255);
y = t = 0;
}
}
if (y != 0)
goto error;
*outlen = z;
ret = 0;
error:
#ifdef CONFIG_SSL_FULL_MODE
if (ret < 0)
printf("Error: Invalid base64 file\n");
#endif
return ret;
}
/**
* Take a base64 blob of data and decrypt it (using AES) into its
* proper ASN.1 form.
@ -372,7 +303,7 @@ static int new_pem_obj(SSLCTX *ssl_ctx, int is_cacert, uint8_t *where,
strstr((const char *)start, "4,ENCRYPTED"))
{
/* check for encrypted PEM file */
if ((pem_size = pem_decrypt(start, end, password, ssl_obj)) < 0)
if (pem_decrypt(start, end, password, ssl_obj) < 0)
goto error;
}
else if (base64_decode(start, pem_size,

View File

@ -90,7 +90,7 @@ static const uint8_t PADDING[64] =
/**
* MD5 initialization - begins an MD5 operation, writing a new ctx.
*/
void MD5Init(MD5_CTX *ctx)
EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
{
ctx->count[0] = ctx->count[1] = 0;
@ -105,7 +105,7 @@ void MD5Init(MD5_CTX *ctx)
/**
* Accepts an array of octets as the next portion of the message.
*/
void MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
{
uint32_t x;
int i, partLen;
@ -141,7 +141,7 @@ void MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
/**
* Return the 128-bit message digest into the user's array
*/
void MD5Final(MD5_CTX *ctx, uint8_t *digest)
EXP_FUNC void STDCALL MD5Final(MD5_CTX *ctx, uint8_t *digest)
{
uint8_t bits[8];
uint32_t x, padLen;

View File

@ -29,7 +29,7 @@
extern "C" {
#endif
#if defined(WIN32) || defined(CYGWIN)
#if defined(WIN32) || defined(CONFIG_PLATFORM_CYGWIN)
#define STDCALL __stdcall
#define EXP_FUNC __declspec(dllexport)
#else
@ -56,6 +56,7 @@ extern "C" {
#endif /* _WIN32_WCE */
#include <winsock.h>
#include <direct.h>
#undef getpid
#undef open
#undef close
@ -81,6 +82,7 @@ extern "C" {
#define usleep(A) Sleep(A/1000)
#define lseek(A,B,C) _lseek(A,B,C)
#define strdup(A) _strdup(A)
#define chroot(A) _chdir(A)
/* This fix gets around a problem where a win32 application on a cygwin xterm
doesn't display regular output (until a certain buffer limit) - but it works
@ -113,7 +115,7 @@ extern EXP_FUNC int strcasecmp(const char *s1, const char *s2);
#else /* Not Win32 */
#ifdef SOLARIS
#ifdef CONFIG_PLATFORM_SOLARIS
#include <inttypes.h>
#else
#include <stdint.h>

View File

@ -1123,6 +1123,7 @@ static void set_key_block(SSL *ssl, int is_write)
/* clean up if possible */
if (key_block_existed)
{
memset(ssl->key_block, 0, ciph_info->key_block_size);
free(ssl->key_block);
ssl->key_block = NULL;
}
@ -1454,9 +1455,11 @@ int process_finished(SSL *ssl, int hs_len)
ssl->all_pkts = NULL;
ssl->all_pkts_len = 0;
memset(ssl->master_secret, 0, SSL_SECRET_SIZE);
free(ssl->master_secret);
ssl->master_secret = NULL;
memset(ssl->final_finish_mac, 0, SSL_FINISHED_HASH_SIZE);
free(ssl->final_finish_mac);
ssl->final_finish_mac = NULL;