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:
parent
9241353c50
commit
30a1970bb2
12
CHANGELOG
Normal file
12
CHANGELOG
Normal 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
|
||||||
|
*
|
14
Makefile
14
Makefile
@ -74,10 +74,20 @@ win32_demo:
|
|||||||
install: $(PREFIX) all
|
install: $(PREFIX) all
|
||||||
cp --no-dereference $(STAGE)/libax* $(PREFIX)/lib
|
cp --no-dereference $(STAGE)/libax* $(PREFIX)/lib
|
||||||
chmod 755 $(PREFIX)/lib/libax*
|
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
|
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
|
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:
|
installclean:
|
||||||
-@rm $(PREFIX)/lib/libax* > /dev/null 2>&1
|
-@rm $(PREFIX)/lib/libax* > /dev/null 2>&1
|
||||||
|
@ -79,7 +79,7 @@ LD=$(CC)
|
|||||||
|
|
||||||
# Solaris
|
# Solaris
|
||||||
ifdef CONFIG_PLATFORM_SOLARIS
|
ifdef CONFIG_PLATFORM_SOLARIS
|
||||||
CFLAGS += -DSOLARIS
|
CFLAGS += -DCONFIG_PLATFORM_SOLARIS
|
||||||
LDFLAGS += -lsocket -lnsl -lc
|
LDFLAGS += -lsocket -lnsl -lc
|
||||||
LDSHARED = -G
|
LDSHARED = -G
|
||||||
# Linux/Cygwin
|
# Linux/Cygwin
|
||||||
@ -89,7 +89,7 @@ LDSHARED = -shared
|
|||||||
ifndef CONFIG_PLATFORM_CYGWIN
|
ifndef CONFIG_PLATFORM_CYGWIN
|
||||||
CFLAGS += -fPIC
|
CFLAGS += -fPIC
|
||||||
else
|
else
|
||||||
CFLAGS += -DCYGWIN
|
CFLAGS += -DCONFIG_PLATFORM_CYGWIN
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -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
|
Select y if you want axhttp to be a static build (i.e. don't use the
|
||||||
axtls shared library or dll).
|
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
|
config CONFIG_HTTP_HTTPS_PORT
|
||||||
int "HTTPS port"
|
int "HTTPS port"
|
||||||
default 443
|
default 443
|
||||||
@ -39,14 +47,6 @@ config CONFIG_HTTP_WEBROOT
|
|||||||
The location of the web root in relation to axhttpd. This is
|
The location of the web root in relation to axhttpd. This is
|
||||||
the directory where index.html lives.
|
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
|
config CONFIG_HTTP_TIMEOUT
|
||||||
int "Timeout"
|
int "Timeout"
|
||||||
default 5
|
default 5
|
||||||
@ -79,6 +79,12 @@ config CONFIG_HTTP_PERM_CHECK
|
|||||||
Enable permissions checking on the directories before reading the
|
Enable permissions checking on the directories before reading the
|
||||||
files in them.
|
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
|
config CONFIG_HTTP_HAS_IPV6
|
||||||
bool "Enable IPv6"
|
bool "Enable IPv6"
|
||||||
default n
|
default n
|
||||||
|
@ -54,7 +54,7 @@ else
|
|||||||
web_server : $(TARGET)
|
web_server : $(TARGET)
|
||||||
|
|
||||||
OBJ= \
|
OBJ= \
|
||||||
main.o \
|
axhttpd.o \
|
||||||
proc.o \
|
proc.o \
|
||||||
mime_types.o
|
mime_types.o
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@ struct connstruct
|
|||||||
uint8_t is_ssl;
|
uint8_t is_ssl;
|
||||||
uint8_t close_when_done;
|
uint8_t close_when_done;
|
||||||
uint8_t modified_since;
|
uint8_t modified_since;
|
||||||
|
#if defined(CONFIG_HTTP_HAS_AUTHORIZATION)
|
||||||
|
char authorization[MAXREQUESTLENGTH];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct serverstruct
|
struct serverstruct
|
||||||
@ -103,9 +106,6 @@ extern struct connstruct *freeconns;
|
|||||||
extern struct cgiextstruct *cgiexts;
|
extern struct cgiextstruct *cgiexts;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Conf global prototypes
|
|
||||||
extern char *webroot;
|
|
||||||
|
|
||||||
// conn.c prototypes
|
// conn.c prototypes
|
||||||
void removeconnection(struct connstruct *cn);
|
void removeconnection(struct connstruct *cn);
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
struct serverstruct *servers;
|
struct serverstruct *servers;
|
||||||
struct connstruct *usedconns;
|
struct connstruct *usedconns;
|
||||||
struct connstruct *freeconns;
|
struct connstruct *freeconns;
|
||||||
char *webroot = CONFIG_HTTP_WEBROOT;
|
|
||||||
|
|
||||||
static void addtoservers(int sd);
|
static void addtoservers(int sd);
|
||||||
static int openlistener(int port);
|
static int openlistener(int port);
|
||||||
@ -86,11 +85,12 @@ static void die(int sigtype)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
static char *webroot = CONFIG_HTTP_WEBROOT;
|
||||||
fd_set rfds, wfds;
|
fd_set rfds, wfds;
|
||||||
struct connstruct *tp, *to;
|
struct connstruct *tp, *to;
|
||||||
struct serverstruct *sp;
|
struct serverstruct *sp;
|
||||||
int rnum, wnum, active;
|
int rnum, wnum, active;
|
||||||
int webrootlen, i;
|
int i;
|
||||||
time_t currtime;
|
time_t currtime;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -98,12 +98,6 @@ int main(int argc, char *argv[])
|
|||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WSAStartup(wVersionRequested,&wsaData);
|
WSAStartup(wVersionRequested,&wsaData);
|
||||||
#else
|
#else
|
||||||
if (getuid() == 0) /* change our uid if we are root */
|
|
||||||
{
|
|
||||||
setgid(32767);
|
|
||||||
setuid(32767);
|
|
||||||
}
|
|
||||||
|
|
||||||
signal(SIGQUIT, die);
|
signal(SIGQUIT, die);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
@ -122,12 +116,8 @@ int main(int argc, char *argv[])
|
|||||||
freeconns->next = tp;
|
freeconns->next = tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
webrootlen = strlen(webroot);
|
/* change to webroot for better security */
|
||||||
|
if (chroot(webroot))
|
||||||
if (webroot[webrootlen-1] == '/')
|
|
||||||
webroot[webrootlen-1] = '\0';
|
|
||||||
|
|
||||||
if (isdir(webroot) == 0)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HTTP_VERBOSE
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
fprintf(stderr, "'%s' is not a directory\n", webroot);
|
fprintf(stderr, "'%s' is not a directory\n", webroot);
|
||||||
@ -135,6 +125,11 @@ int main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
setgid(32767);
|
||||||
|
setuid(32767);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((active = openlistener(CONFIG_HTTP_PORT)) == -1)
|
if ((active = openlistener(CONFIG_HTTP_PORT)) == -1)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HTTP_VERBOSE
|
#ifdef CONFIG_HTTP_VERBOSE
|
@ -20,7 +20,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "os_port.h"
|
#include "axhttp.h"
|
||||||
|
|
||||||
static const char mime_default[] = "text/plain";
|
static const char mime_default[] = "text/plain";
|
||||||
|
|
||||||
|
264
httpd/proc.c
264
httpd/proc.c
@ -29,8 +29,7 @@
|
|||||||
static int special_read(struct connstruct *cn, void *buf, size_t count);
|
static int special_read(struct connstruct *cn, void *buf, size_t count);
|
||||||
static int special_write(struct connstruct *cn,
|
static int special_write(struct connstruct *cn,
|
||||||
const uint8_t *buf, size_t count);
|
const uint8_t *buf, size_t count);
|
||||||
static void send404(struct connstruct *cn);
|
static void send_error(struct connstruct *cn, int err);
|
||||||
static int procindex(struct connstruct *cn, struct stat *stp);
|
|
||||||
static int hexit(char c);
|
static int hexit(char c);
|
||||||
static void urldecode(char *buf);
|
static void urldecode(char *buf);
|
||||||
static void buildactualfile(struct connstruct *cn);
|
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 void split(char *tp, char *sp[], int maxwords, char sc);
|
||||||
static int iscgi(const char *fn);
|
static int iscgi(const char *fn);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
|
static int auth_check(struct connstruct *cn);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Returns 1 if elems should continue being read, 0 otherwise */
|
/* Returns 1 if elems should continue being read, 0 otherwise */
|
||||||
static int procheadelem(struct connstruct *cn, char *buf)
|
static int procheadelem(struct connstruct *cn, char *buf)
|
||||||
@ -61,10 +63,11 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
|
|
||||||
*delim = 0;
|
*delim = 0;
|
||||||
value = delim+1;
|
value = delim+1;
|
||||||
|
printf("BUF %s - value %s\n", buf, value);
|
||||||
|
|
||||||
if (strcmp(buf, "GET")==0 ||
|
if (strcmp(buf, "GET") == 0 ||
|
||||||
strcmp(buf, "HEAD")==0 ||
|
strcmp(buf, "HEAD") == 0 ||
|
||||||
strcmp(buf, "POST")==0)
|
strcmp(buf, "POST") == 0)
|
||||||
{
|
{
|
||||||
if (buf[0] == 'H')
|
if (buf[0] == 'H')
|
||||||
cn->reqtype = TYPE_HEAD;
|
cn->reqtype = TYPE_HEAD;
|
||||||
@ -79,8 +82,7 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
|
|
||||||
if (sanitizefile(value) == 0)
|
if (sanitizefile(value) == 0)
|
||||||
{
|
{
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +100,6 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
{
|
{
|
||||||
if (sanitizehost(value) == 0)
|
if (sanitizehost(value) == 0)
|
||||||
{
|
{
|
||||||
send404(cn);
|
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -114,6 +115,15 @@ static int procheadelem(struct connstruct *cn, char *buf)
|
|||||||
/* TODO: parse this date properly with getdate() or similar */
|
/* TODO: parse this date properly with getdate() or similar */
|
||||||
cn->modified_since = 1;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -141,15 +151,13 @@ static void procdirlisting(struct connstruct *cn)
|
|||||||
|
|
||||||
if (cn->dirp == INVALID_HANDLE_VALUE)
|
if (cn->dirp == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ((cn->dirp = opendir(actualfile)) == NULL)
|
if ((cn->dirp = opendir(actualfile)) == NULL)
|
||||||
{
|
{
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,11 +213,16 @@ void procdodir(struct connstruct *cn)
|
|||||||
if (file[0] == '.' && file[1] != '.')
|
if (file[0] == '.' && file[1] != '.')
|
||||||
continue;
|
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);
|
snprintf(buf, sizeof(buf), "%s%s", cn->actualfile, file);
|
||||||
if (isdir(buf))
|
if (isdir(buf))
|
||||||
strcat(file, "/");
|
strcat(file, "/");
|
||||||
urlencode(file, encbuf);
|
|
||||||
|
|
||||||
|
urlencode(file, encbuf);
|
||||||
snprintf(buf, sizeof(buf), "<a href=\"%s%s\">%s</a><br />\n",
|
snprintf(buf, sizeof(buf), "<a href=\"%s%s\">%s</a><br />\n",
|
||||||
cn->filereq, encbuf, file);
|
cn->filereq, encbuf, file);
|
||||||
} while (special_write(cn, buf, strlen(buf)));
|
} while (special_write(cn, buf, strlen(buf)));
|
||||||
@ -263,6 +276,10 @@ void procreadhead(struct connstruct *cn)
|
|||||||
buf[rv] = '\0';
|
buf[rv] = '\0';
|
||||||
next = tp = buf;
|
next = tp = buf;
|
||||||
|
|
||||||
|
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
|
cn->authorization[0] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Split up lines and send to procheadelem() */
|
/* Split up lines and send to procheadelem() */
|
||||||
while (*next != '\0')
|
while (*next != '\0')
|
||||||
{
|
{
|
||||||
@ -297,22 +314,22 @@ void procreadhead(struct connstruct *cn)
|
|||||||
*/
|
*/
|
||||||
void procsendhead(struct connstruct *cn)
|
void procsendhead(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[MAXREQUESTLENGTH];
|
||||||
char actualfile[1024];
|
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
||||||
char date[32];
|
char date[32];
|
||||||
|
|
||||||
strcpy(date, ctime(&now));
|
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
|
||||||
strcpy(actualfile, cn->actualfile);
|
if (auth_check(cn))
|
||||||
|
{
|
||||||
#ifdef WIN32
|
removeconnection(cn);
|
||||||
/* stat() under win32 can't deal with trail slash */
|
return;
|
||||||
if (actualfile[strlen(actualfile)-1] == '\\')
|
}
|
||||||
actualfile[strlen(actualfile)-1] = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (stat(actualfile, &stbuf) == -1)
|
strcpy(date, ctime(&now));
|
||||||
|
|
||||||
|
if (stat(cn->actualfile, &stbuf) == -1)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
if (trycgi_withpathinfo(cn) == 0)
|
if (trycgi_withpathinfo(cn) == 0)
|
||||||
@ -323,8 +340,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,8 +351,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
/* Set up CGI script */
|
/* Set up CGI script */
|
||||||
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
{
|
{
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -346,17 +361,20 @@ void procsendhead(struct connstruct *cn)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* look for "index.html"? */
|
||||||
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
|
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
|
||||||
{
|
{
|
||||||
/* Check to see if this dir has an index file */
|
char tbuf[MAXREQUESTLENGTH];
|
||||||
if (procindex(cn, &stbuf) == 0)
|
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 defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
/* If not, we do a directory listing of it */
|
/* If not, we do a directory listing of it */
|
||||||
procdirlisting(cn);
|
procdirlisting(cn);
|
||||||
#else
|
#else
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -368,8 +386,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
/* Set up CGI script */
|
/* Set up CGI script */
|
||||||
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
{
|
{
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,14 +429,14 @@ void procsendhead(struct connstruct *cn)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int flags = O_RDONLY;
|
int flags = O_RDONLY;
|
||||||
#if defined(WIN32) || defined(CYGWIN)
|
#if defined(WIN32) || defined(CONFIG_PLATFORM_CYGWIN)
|
||||||
flags |= O_BINARY;
|
flags |= O_BINARY;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cn->filedesc = open(cn->actualfile, flags);
|
cn->filedesc = open(cn->actualfile, flags);
|
||||||
if (cn->filedesc == -1)
|
if (cn->filedesc == -1)
|
||||||
{
|
{
|
||||||
send404(cn);
|
send_error(cn, 404);
|
||||||
removeconnection(cn);
|
removeconnection(cn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -515,23 +532,6 @@ static int special_read(struct connstruct *cn, void *buf, size_t count)
|
|||||||
return res;
|
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)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
static void proccgi(struct connstruct *cn, int has_pathinfo)
|
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)
|
while (fr_rs[i] != NULL)
|
||||||
{
|
{
|
||||||
snprintf(tpfile, sizeof(tpfile), "%s/%s%s",
|
snprintf(tpfile, sizeof(tpfile), "/%s%s",
|
||||||
webroot, cn->virtualhostreq, fr_str);
|
cn->virtualhostreq, fr_str);
|
||||||
|
|
||||||
if (iscgi(tpfile) && isdir(tpfile) == 0)
|
if (iscgi(tpfile) && isdir(tpfile) == 0)
|
||||||
{
|
{
|
||||||
@ -782,18 +782,9 @@ static int hexit(char c)
|
|||||||
return 0;
|
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)
|
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 */
|
/* Add directory slash if not there */
|
||||||
if (isdir(cn->actualfile) &&
|
if (isdir(cn->actualfile) &&
|
||||||
@ -805,10 +796,8 @@ static void buildactualfile(struct connstruct *cn)
|
|||||||
{
|
{
|
||||||
char *t = cn->actualfile;
|
char *t = cn->actualfile;
|
||||||
while ((t = strchr(t, '/')))
|
while ((t = strchr(t, '/')))
|
||||||
{
|
|
||||||
*t++ = '\\';
|
*t++ = '\\';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,3 +844,146 @@ static int sanitizehost(char *buf)
|
|||||||
return 1;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ int main(int argc, char *argv[])
|
|||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WORD wVersionRequested = MAKEWORD(2, 2);
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
WSAStartup(wVersionRequested, &wsaData);
|
WSAStartup(wVersionRequested, &wsaData);
|
||||||
#elif !defined(SOLARIS)
|
#elif !defined(CONFIG_PLATFORM_SOLARIS)
|
||||||
signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */
|
signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
141
ssl/aes.c
141
ssl/aes.c
@ -62,10 +62,6 @@
|
|||||||
(f8)^=rot2(f4), \
|
(f8)^=rot2(f4), \
|
||||||
(f8)^rot1(f9))
|
(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
|
* AES S-box
|
||||||
*/
|
*/
|
||||||
@ -249,7 +245,7 @@ void AES_convert_key(AES_CTX *ctx)
|
|||||||
k = ctx->ks;
|
k = ctx->ks;
|
||||||
k += 4;
|
k += 4;
|
||||||
|
|
||||||
for (i=ctx->rounds*4; i>4; i--)
|
for (i= ctx->rounds*4; i > 4; i--)
|
||||||
{
|
{
|
||||||
w= *k;
|
w= *k;
|
||||||
w = inv_mix_col(w,t1,t2,t3,t4);
|
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)
|
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||||
{
|
{
|
||||||
uint32_t tin0, tin1, tin2, tin3;
|
int i;
|
||||||
uint32_t tout0, tout1, tout2, tout3;
|
uint32_t tin[4], tout[4], iv[4];
|
||||||
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;
|
|
||||||
|
|
||||||
n2l(iv, tout0);
|
memcpy(iv, ctx->iv, AES_IV_SIZE);
|
||||||
n2l(iv, tout1);
|
for (i = 0; i < 4; i++)
|
||||||
n2l(iv, tout2);
|
tout[i] = ntohl(iv[i]);
|
||||||
n2l(iv, tout3);
|
|
||||||
iv -= 4;
|
|
||||||
|
|
||||||
for (length -= 16; length >= 0; length -= 16)
|
for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
|
||||||
{
|
{
|
||||||
n2l(msg_32, tin0);
|
uint32_t msg_32[4];
|
||||||
n2l(msg_32, tin1);
|
uint32_t out_32[4];
|
||||||
n2l(msg_32, tin2);
|
memcpy(msg_32, msg, AES_BLOCKSIZE);
|
||||||
n2l(msg_32, tin3);
|
msg += AES_BLOCKSIZE;
|
||||||
tin[0] = tin0^tout0;
|
|
||||||
tin[1] = tin1^tout1;
|
for (i = 0; i < 4; i++)
|
||||||
tin[2] = tin2^tout2;
|
tin[i] = ntohl(msg_32[i])^tout[i];
|
||||||
tin[3] = tin3^tout3;
|
|
||||||
|
|
||||||
AES_encrypt(ctx, tin);
|
AES_encrypt(ctx, tin);
|
||||||
|
|
||||||
tout0 = tin[0];
|
for (i = 0; i < 4; i++)
|
||||||
l2n(tout0, out_32);
|
{
|
||||||
tout1 = tin[1];
|
tout[i] = tin[i];
|
||||||
l2n(tout1, out_32);
|
out_32[i] = htonl(tout[i]);
|
||||||
tout2 = tin[2];
|
|
||||||
l2n(tout2, out_32);
|
|
||||||
tout3 = tin[3];
|
|
||||||
l2n(tout3, out_32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l2n(tout0, iv);
|
memcpy(out, out_32, AES_BLOCKSIZE);
|
||||||
l2n(tout1, iv);
|
out += AES_BLOCKSIZE;
|
||||||
l2n(tout2, iv);
|
}
|
||||||
l2n(tout3, iv);
|
|
||||||
|
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)
|
void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||||
{
|
{
|
||||||
uint32_t tin0, tin1, tin2, tin3;
|
int i;
|
||||||
uint32_t xor0,xor1,xor2,xor3;
|
uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
|
||||||
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;
|
|
||||||
|
|
||||||
n2l(iv ,xor0);
|
memcpy(iv, ctx->iv, AES_IV_SIZE);
|
||||||
n2l(iv, xor1);
|
for (i = 0; i < 4; i++)
|
||||||
n2l(iv, xor2);
|
xor[i] = ntohl(iv[i]);
|
||||||
n2l(iv, xor3);
|
|
||||||
iv -= 4;
|
|
||||||
|
|
||||||
for (length-=16; length >= 0; length -= 16)
|
for (length -= 16; length >= 0; length -= 16)
|
||||||
{
|
{
|
||||||
n2l(msg_32, tin0);
|
uint32_t msg_32[4];
|
||||||
n2l(msg_32, tin1);
|
uint32_t out_32[4];
|
||||||
n2l(msg_32, tin2);
|
memcpy(msg_32, msg, AES_BLOCKSIZE);
|
||||||
n2l(msg_32, tin3);
|
msg += AES_BLOCKSIZE;
|
||||||
|
|
||||||
data[0] = tin0;
|
for (i = 0; i < 4; i++)
|
||||||
data[1] = tin1;
|
{
|
||||||
data[2] = tin2;
|
tin[i] = ntohl(msg_32[i]);
|
||||||
data[3] = tin3;
|
data[i] = tin[i];
|
||||||
|
}
|
||||||
|
|
||||||
AES_decrypt(ctx, data);
|
AES_decrypt(ctx, data);
|
||||||
|
|
||||||
tout0 = data[0]^xor0;
|
for (i = 0; i < 4; i++)
|
||||||
tout1 = data[1]^xor1;
|
{
|
||||||
tout2 = data[2]^xor2;
|
tout[i] = data[i]^xor[i];
|
||||||
tout3 = data[3]^xor3;
|
xor[i] = tin[i];
|
||||||
|
out_32[i] = htonl(tout[i]);
|
||||||
xor0 = tin0;
|
|
||||||
xor1 = tin1;
|
|
||||||
xor2 = tin2;
|
|
||||||
xor3 = tin3;
|
|
||||||
|
|
||||||
l2n(tout0, out_32);
|
|
||||||
l2n(tout1, out_32);
|
|
||||||
l2n(tout2, out_32);
|
|
||||||
l2n(tout3, out_32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l2n(xor0, iv);
|
memcpy(out, out_32, AES_BLOCKSIZE);
|
||||||
l2n(xor1, iv);
|
out += AES_BLOCKSIZE;
|
||||||
l2n(xor2, iv);
|
}
|
||||||
l2n(xor3, iv);
|
|
||||||
|
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 */
|
/* Pre-round key addition */
|
||||||
for (row = 0; row < 4; row++)
|
for (row = 0; row < 4; row++)
|
||||||
{
|
|
||||||
data[row] ^= *(k++);
|
data[row] ^= *(k++);
|
||||||
}
|
|
||||||
|
|
||||||
/* Encrypt one block. */
|
/* Encrypt one block. */
|
||||||
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
|
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;
|
tmp1 = a0 ^ a1 ^ a2 ^ a3;
|
||||||
old_a0 = a0;
|
old_a0 = a0;
|
||||||
|
|
||||||
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
|
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
|
||||||
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
|
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
|
||||||
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
|
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
|
/* KeyAddition - note that it is vital that this loop is separate from
|
||||||
the MixColumn operation, which must be atomic...*/
|
the MixColumn operation, which must be atomic...*/
|
||||||
for (row = 0; row < 4; row++)
|
for (row = 0; row < 4; row++)
|
||||||
{
|
|
||||||
data[row] = tmp[row] ^ *(k++);
|
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;
|
uint32_t a0, a1, a2, a3, row;
|
||||||
int curr_rnd;
|
int curr_rnd;
|
||||||
int rounds = ctx->rounds;
|
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 */
|
/* pre-round key addition */
|
||||||
for (row=4; row > 0;row--)
|
for (row=4; row > 0;row--)
|
||||||
{
|
|
||||||
data[row-1] ^= *(--k);
|
data[row-1] ^= *(--k);
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrypt one block */
|
/* 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 */
|
/* Perform ByteSub and ShiftRow operations together */
|
||||||
for (row = 4; row > 0; row--)
|
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--)
|
for (row = 4; row > 0; row--)
|
||||||
{
|
|
||||||
data[row-1] = tmp[row-1] ^ *(--k);
|
data[row-1] = tmp[row-1] ^ *(--k);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
13
ssl/crypto.h
13
ssl/crypto.h
@ -34,13 +34,15 @@ extern "C" {
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define AES_MAXROUNDS 14
|
#define AES_MAXROUNDS 14
|
||||||
|
#define AES_BLOCKSIZE 16
|
||||||
|
#define AES_IV_SIZE 16
|
||||||
|
|
||||||
typedef struct aes_key_st
|
typedef struct aes_key_st
|
||||||
{
|
{
|
||||||
uint16_t rounds;
|
uint16_t rounds;
|
||||||
uint16_t key_size;
|
uint16_t key_size;
|
||||||
uint32_t ks[(AES_MAXROUNDS+1)*8];
|
uint32_t ks[(AES_MAXROUNDS+1)*8];
|
||||||
uint8_t iv[16];
|
uint8_t iv[AES_IV_SIZE];
|
||||||
} AES_CTX;
|
} AES_CTX;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -106,9 +108,9 @@ typedef struct
|
|||||||
uint8_t buffer[64]; /* input buffer */
|
uint8_t buffer[64]; /* input buffer */
|
||||||
} MD5_CTX;
|
} MD5_CTX;
|
||||||
|
|
||||||
void MD5Init(MD5_CTX *);
|
EXP_FUNC void STDCALL MD5Init(MD5_CTX *);
|
||||||
void MD5Update(MD5_CTX *, const uint8_t *msg, int len);
|
EXP_FUNC void STDCALL MD5Update(MD5_CTX *, const uint8_t *msg, int len);
|
||||||
void MD5Final(MD5_CTX *, uint8_t *digest);
|
EXP_FUNC void STDCALL MD5Final(MD5_CTX *, uint8_t *digest);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* HMAC declarations
|
* HMAC declarations
|
||||||
@ -273,6 +275,9 @@ void print_blob(const char *format, const uint8_t *data, int size, ...);
|
|||||||
#define print_blob(...)
|
#define print_blob(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
|
||||||
|
uint8_t *out, int *outlen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -267,3 +267,78 @@ void print_blob(const char *format,
|
|||||||
void print_blob(const char *format, const unsigned char *data,
|
void print_blob(const char *format, const unsigned char *data,
|
||||||
int size, ...) {}
|
int size, ...) {}
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
|
71
ssl/loader.c
71
ssl/loader.c
@ -169,22 +169,6 @@ void ssl_obj_free(SSLObjLoader *ssl_obj)
|
|||||||
#define IS_ENCRYPTED_PRIVATE_KEY 1
|
#define IS_ENCRYPTED_PRIVATE_KEY 1
|
||||||
#define IS_CERTIFICATE 2
|
#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] =
|
static const char * const begins[NUM_PEM_TYPES] =
|
||||||
{
|
{
|
||||||
"-----BEGIN RSA PRIVATE KEY-----",
|
"-----BEGIN RSA PRIVATE KEY-----",
|
||||||
@ -205,59 +189,6 @@ static const char * const aes_str[2] =
|
|||||||
"DEK-Info: AES-256-CBC,"
|
"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
|
* Take a base64 blob of data and decrypt it (using AES) into its
|
||||||
* proper ASN.1 form.
|
* 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"))
|
strstr((const char *)start, "4,ENCRYPTED"))
|
||||||
{
|
{
|
||||||
/* check for encrypted PEM file */
|
/* 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;
|
goto error;
|
||||||
}
|
}
|
||||||
else if (base64_decode(start, pem_size,
|
else if (base64_decode(start, pem_size,
|
||||||
|
@ -90,7 +90,7 @@ static const uint8_t PADDING[64] =
|
|||||||
/**
|
/**
|
||||||
* MD5 initialization - begins an MD5 operation, writing a new ctx.
|
* 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;
|
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.
|
* 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;
|
uint32_t x;
|
||||||
int i, partLen;
|
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
|
* 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];
|
uint8_t bits[8];
|
||||||
uint32_t x, padLen;
|
uint32_t x, padLen;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIN32) || defined(CYGWIN)
|
#if defined(WIN32) || defined(CONFIG_PLATFORM_CYGWIN)
|
||||||
#define STDCALL __stdcall
|
#define STDCALL __stdcall
|
||||||
#define EXP_FUNC __declspec(dllexport)
|
#define EXP_FUNC __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
@ -56,6 +56,7 @@ extern "C" {
|
|||||||
#endif /* _WIN32_WCE */
|
#endif /* _WIN32_WCE */
|
||||||
|
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
|
#include <direct.h>
|
||||||
#undef getpid
|
#undef getpid
|
||||||
#undef open
|
#undef open
|
||||||
#undef close
|
#undef close
|
||||||
@ -81,6 +82,7 @@ extern "C" {
|
|||||||
#define usleep(A) Sleep(A/1000)
|
#define usleep(A) Sleep(A/1000)
|
||||||
#define lseek(A,B,C) _lseek(A,B,C)
|
#define lseek(A,B,C) _lseek(A,B,C)
|
||||||
#define strdup(A) _strdup(A)
|
#define strdup(A) _strdup(A)
|
||||||
|
#define chroot(A) _chdir(A)
|
||||||
|
|
||||||
/* This fix gets around a problem where a win32 application on a cygwin xterm
|
/* 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
|
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 */
|
#else /* Not Win32 */
|
||||||
|
|
||||||
#ifdef SOLARIS
|
#ifdef CONFIG_PLATFORM_SOLARIS
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -1123,6 +1123,7 @@ static void set_key_block(SSL *ssl, int is_write)
|
|||||||
/* clean up if possible */
|
/* clean up if possible */
|
||||||
if (key_block_existed)
|
if (key_block_existed)
|
||||||
{
|
{
|
||||||
|
memset(ssl->key_block, 0, ciph_info->key_block_size);
|
||||||
free(ssl->key_block);
|
free(ssl->key_block);
|
||||||
ssl->key_block = NULL;
|
ssl->key_block = NULL;
|
||||||
}
|
}
|
||||||
@ -1454,9 +1455,11 @@ int process_finished(SSL *ssl, int hs_len)
|
|||||||
ssl->all_pkts = NULL;
|
ssl->all_pkts = NULL;
|
||||||
ssl->all_pkts_len = 0;
|
ssl->all_pkts_len = 0;
|
||||||
|
|
||||||
|
memset(ssl->master_secret, 0, SSL_SECRET_SIZE);
|
||||||
free(ssl->master_secret);
|
free(ssl->master_secret);
|
||||||
ssl->master_secret = NULL;
|
ssl->master_secret = NULL;
|
||||||
|
|
||||||
|
memset(ssl->final_finish_mac, 0, SSL_FINISHED_HASH_SIZE);
|
||||||
free(ssl->final_finish_mac);
|
free(ssl->final_finish_mac);
|
||||||
ssl->final_finish_mac = NULL;
|
ssl->final_finish_mac = NULL;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user