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

changed x509 verification code

git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@151 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
cameronrich 2008-11-05 12:01:50 +00:00
parent bc1e70c101
commit 0abda1ca64
6 changed files with 141 additions and 103 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Cameron Rich
* Copyright (c) 2007-2008, Cameron Rich
*
* All rights reserved.
*
@ -137,6 +137,11 @@ static int procheadelem(struct connstruct *cn, char *buf)
{
cn->if_modified_since = tdate_parse(value);
}
else if (strcmp(buf, "Expect:") == 0)
{
send_error(cn, 417); /* expectation failed */
return 0;
}
#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
else if (strcmp(buf, "Authorization:") == 0 &&
strncmp(value, "Basic ", 6) == 0)

View File

@ -770,7 +770,7 @@ static int SSL_server_test(
const char *private_key,
const char *ca_cert,
const char *password,
int axolotls_option)
int axtls_option)
{
int server_fd, ret = 0;
SSL_CTX *ssl_ctx = NULL;
@ -791,10 +791,10 @@ static int SSL_server_test(
if (private_key)
{
axolotls_option |= SSL_NO_DEFAULT_KEY;
axtls_option |= SSL_NO_DEFAULT_KEY;
}
if ((ssl_ctx = ssl_ctx_new(axolotls_option, SSL_DEFAULT_SVR_SESS)) == NULL)
if ((ssl_ctx = ssl_ctx_new(axtls_option, SSL_DEFAULT_SVR_SESS)) == NULL)
{
ret = SSL_ERROR_INVALID_KEY;
goto error;
@ -1012,7 +1012,7 @@ int SSL_server_tests(void)
/* this test should fail */
if (stat("../ssl/test/axTLS.x509_bad_before.pem", &stat_buf) >= 0)
{
if ((ret = SSL_server_test("Bad Before Cert",
if ((ret = SSL_server_test("Error: Bad Before Cert",
"-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_bad_before.pem "
"-key ../ssl/test/axTLS.key_512.pem ",
@ -1028,7 +1028,7 @@ int SSL_server_tests(void)
}
/* this test should fail */
if ((ret = SSL_server_test("Bad After Cert",
if ((ret = SSL_server_test("Error: Bad After Cert",
"-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_bad_after.pem "
"-key ../ssl/test/axTLS.key_512.pem ",
@ -1041,6 +1041,53 @@ int SSL_server_tests(void)
printf("SSL server test \"%s\" passed\n", "Bad After Cert");
TTY_FLUSH();
/*
* No trusted cert
*/
if ((ret = SSL_server_test("Error: No trusted certificate",
"-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_512.pem "
"-key ../ssl/test/axTLS.key_512.pem ",
NULL, NULL, NULL,
NULL, NULL,
DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) !=
SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT))
goto cleanup;
printf("SSL server test \"%s\" passed\n", "No trusted certificate");
TTY_FLUSH();
/*
* Self-signed (from the server)
*/
if ((ret = SSL_server_test("Error: Self-signed certificate (from server)",
"-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_512.pem "
"-key ../ssl/test/axTLS.key_512.pem "
"-CAfile ../ssl/test/axTLS.ca_x509.pem ",
NULL, NULL, NULL,
NULL, NULL,
DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)) !=
SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED))
goto cleanup;
printf("SSL server test \"%s\" passed\n",
"Self-signed certificate (from server)");
TTY_FLUSH();
/*
* Self-signed (from the client)
*/
if ((ret = SSL_server_test("Self-signed certificate (from client)",
"-cipher RC4-SHA -tls1 "
"-cert ../ssl/test/axTLS.x509_512.pem "
"-key ../ssl/test/axTLS.key_512.pem ",
NULL, NULL, NULL,
"../ssl/test/axTLS.ca_x509.cer",
NULL,
DEFAULT_SVR_OPTION|SSL_CLIENT_AUTHENTICATION)))
goto cleanup;
/*
* Key in PEM format
*/
@ -1434,13 +1481,12 @@ int SSL_client_tests(void)
"-CAfile ../ssl/test/axTLS.ca_x509.pem "
"-verify 1 ", NULL, DEFAULT_CLNT_OPTION,
"../ssl/test/axTLS.key_1024", NULL,
"../ssl/test/axTLS.x509_1024.cer"))
!= SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED))
"../ssl/test/axTLS.x509_1024.cer")))
goto cleanup;
/* Should get an "ERROR" from openssl (as the handshake fails as soon as
* the certificate verification fails) */
if ((ret = SSL_client_test("Expired cert (verify now) should fail!",
if ((ret = SSL_client_test("Error: Expired cert (verify now)",
&ssl_ctx,
"-cert ../ssl/test/axTLS.x509_bad_after.pem "
"-key ../ssl/test/axTLS.key_512.pem", NULL,
@ -1452,10 +1498,9 @@ int SSL_client_tests(void)
}
printf("SSL client test \"Expired cert (verify now)\" passed\n");
ret = 0;
/* There is no "ERROR" from openssl */
if ((ret = SSL_client_test("Expired cert (verify later) should fail!",
if ((ret = SSL_client_test("Error: Expired cert (verify later)",
&ssl_ctx,
"-cert ../ssl/test/axTLS.x509_bad_after.pem "
"-key ../ssl/test/axTLS.key_512.pem", NULL,
@ -1467,7 +1512,6 @@ int SSL_client_tests(void)
}
printf("SSL client test \"Expired cert (verify later)\" passed\n");
ret = 0;
cleanup:

View File

@ -386,7 +386,6 @@ int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len)
int ret = SSL_ERROR_NO_CERT_DEFINED;
int i = 0;
int offset;
X509_CTX *cert = NULL;
CA_CERT_CTX *ca_cert_ctx;
if (ssl_ctx->ca_cert_ctx == NULL)
@ -409,22 +408,6 @@ int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len)
if ((ret = x509_new(buf, &offset, &ca_cert_ctx->cert[i])))
goto error;
/* make sure the cert is valid */
cert = ca_cert_ctx->cert[i];
SSL_CTX_LOCK(ssl_ctx->mutex);
if ((ret = x509_verify(ca_cert_ctx, cert)) != X509_VFY_ERROR_SELF_SIGNED)
{
SSL_CTX_UNLOCK(ssl_ctx->mutex);
x509_free(cert); /* get rid of it */
ca_cert_ctx->cert[i] = NULL;
#ifdef CONFIG_SSL_FULL_MODE
printf("Error: %s\n", x509_display_error(ret)); TTY_FLUSH();
#endif
goto error;
}
SSL_CTX_UNLOCK(ssl_ctx->mutex);
len -= offset;
ret = SSL_OK; /* ok so far */
@ -1751,6 +1734,7 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
goto error;
}
DISPLAY_CERT(ssl, *chain);
chain = &((*chain)->next);
offset += cert_size;
}
@ -1763,7 +1747,6 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
ret = ssl_verify_cert(ssl);
}
DISPLAY_CERT(ssl, *x509_ctx);
ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG;
ssl->dc->bm_proc_index += offset;
error:

View File

@ -378,6 +378,12 @@ static int process_client_key_xchg(SSL *ssl)
int offset = 4;
int ret = SSL_OK;
if (rsa_ctx == NULL)
{
ret = SSL_ERROR_NO_CERT_DEFINED;
goto error;
}
DISPLAY_RSA(ssl, rsa_ctx);
/* is there an extra size field? */

View File

@ -251,11 +251,11 @@ static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
* Do some basic checks on the certificate chain.
*
* Certificate verification consists of a number of checks:
* - A root certificate exists in the certificate store.
* - The date of the certificate is after the start date.
* - The date of the certificate is before the finish date.
* - The certificate chain is valid.
* - A root certificate exists in the certificate store.
* - That the certificate(s) are not self-signed.
* - The certificate chain is valid.
* - The signature of the certificate is valid.
*/
int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
@ -263,44 +263,26 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
int ret = X509_OK, i = 0;
bigint *cert_sig;
X509_CTX *next_cert = NULL;
BI_CTX *ctx;
BI_CTX *ctx = NULL;
bigint *mod = NULL, *expn = NULL;
struct timeval tv;
int match_ca_cert = 0;
struct timeval tv;
uint8_t is_self_signed = 0;
if (cert == NULL || ca_cert_ctx == NULL)
if (cert == NULL)
{
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
goto end_verify;
}
/* last cert in the chain - look for a trusted cert */
if (cert->next == NULL && ca_cert_ctx)
/* a self-signed certificate that is not in the CA store - use this
to check the signature */
if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
{
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{
if (asn1_compare_dn(cert->ca_cert_dn,
ca_cert_ctx->cert[i]->cert_dn) == 0)
{
match_ca_cert = 1;
next_cert = ca_cert_ctx->cert[i];
break;
}
i++;
}
/* trusted cert not found */
if (match_ca_cert == 0)
{
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
goto end_verify;
}
}
else
{
next_cert = cert->next;
is_self_signed = 1;
ctx = cert->rsa_ctx->bi_ctx;
mod = cert->rsa_ctx->m;
expn = cert->rsa_ctx->e;
}
gettimeofday(&tv, NULL);
@ -319,61 +301,76 @@ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
goto end_verify;
}
ctx = cert->rsa_ctx->bi_ctx;
next_cert = cert->next;
/* check for self-signing */
if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
/* last cert in the chain - look for a trusted cert */
if (next_cert == NULL)
{
is_self_signed = 1;
mod = cert->rsa_ctx->m;
expn = cert->rsa_ctx->e;
if (ca_cert_ctx != NULL)
{
/* go thu the CA store */
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{
if (asn1_compare_dn(cert->ca_cert_dn,
ca_cert_ctx->cert[i]->cert_dn) == 0)
{
/* use this CA certificate for signature verification */
match_ca_cert = 1;
ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
break;
}
i++;
}
}
/* couldn't find a trusted cert (& let self-signed errors be returned) */
if (!match_ca_cert && !is_self_signed)
{
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
goto end_verify;
}
}
else if (next_cert != NULL)
else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
{
/* check the chain */
ret = X509_VFY_ERROR_INVALID_CHAIN;
goto end_verify;
}
else /* use the next certificate in the chain for signature verify */
{
ctx = next_cert->rsa_ctx->bi_ctx;
mod = next_cert->rsa_ctx->m;
expn = next_cert->rsa_ctx->e;
/* check the chain integrity */
if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
{
ret = X509_VFY_ERROR_INVALID_CHAIN;
goto end_verify;
}
}
/* check the signature */
if (mod != NULL)
{
cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
bi_clone(ctx, mod), bi_clone(ctx, expn));
if (cert_sig && cert->digest)
{
if (bi_compare(cert_sig, cert->digest))
{
ret = X509_VFY_ERROR_BAD_SIGNATURE;
}
bi_free(ctx, cert_sig);
if (ret)
goto end_verify;
}
else
{
ret = X509_VFY_ERROR_BAD_SIGNATURE;
goto end_verify;
}
}
if (is_self_signed)
/* cert is self signed */
if (!match_ca_cert && is_self_signed)
{
ret = X509_VFY_ERROR_SELF_SIGNED;
goto end_verify;
}
/* check the signature */
cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
bi_clone(ctx, mod), bi_clone(ctx, expn));
if (cert_sig && cert->digest)
{
if (bi_compare(cert_sig, cert->digest) != 0)
ret = X509_VFY_ERROR_BAD_SIGNATURE;
bi_free(ctx, cert_sig);
}
if (ret)
goto end_verify;
/* go down the certificate chain using recursion. */
if (ret == 0 && cert->next)
if (next_cert != NULL)
{
ret = x509_verify(ca_cert_ctx, next_cert);
}
@ -441,7 +438,7 @@ void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
if (ca_cert_ctx)
{
printf("Verify:\t\t\t%s\n",
printf("Verify:\t\t\t\t%s\n",
x509_display_error(x509_verify(ca_cert_ctx, cert)));
}
@ -463,6 +460,9 @@ const char * x509_display_error(int error)
{
switch (error)
{
case X509_OK:
return "Certificate verify successful";
case X509_NOT_OK:
return "X509 not ok";

View File

@ -7087,7 +7087,7 @@ if (useJavaSaver)
<div id="storeArea">
<div tiddler="(built-in shadow tiddler)" modifier="CameronRich" modified="200702240024" created="200702240024" tags="">changes, notes and errata</div>
<div tiddler="Cam" modifier="YourName" modified="200804011313" created="200804011313" tags="">Type the text for 'YourName'</div>
<div tiddler="Changelog" modifier="YourName" modified="200804011304" created="200702240022" tags="">@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.9@@\n\n!!__SSL Library__\n* Now support MS IIS resource kit certificates (thanks to Carsten Sørensen).\n* Fixed a memory leak when freeing more than one CA certificate.\n* The bigint library had a problem with squaring which affected classical reduction (thanks to Manuel Klimek).\n\n!!__axhttpd__\n* Brought back setuid()/setgid() as an option.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.8@@\n\n!!__SSL Library__\n* Now using a BSD style license.\n* Self-signed certificates can now be automatically generated (the keys still need to be provided).\n* A new API call //ssl_x509_create()// can be used to programatically create the certificate.\n* Certificate/keys can be loaded automatically given a file location.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.7@@\n\n!!__SSL Library__\n\n* Variable sized session id's is now better handled for session caching. It has meant a new API call //ssl_get_session_id_size()// and a change to //ssl_client_new()// to define the session id size.\n* Muliple records with a single header are now better supported (thanks to Hervé Sibert).\n* ~MD2 added for Verisign root cert verification (thanks to Byron Rakitzis).\n* The ~MD5/~SHA1 digests are calculated incrementally to reduce memory (thanks to Byron Rakitzis).\n* The bigint cache is now cleared regularly to reduce memory.\n\n!!__axhttpd__\n\n* Improved the POST handling (thanks to Christian Melki).\n* CSS files now work properly.\n* Lua's CGI launcher location is configurable.\n* //vfork()// is now used for CGI for performance reasons.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.6@@\n\n!!__SSL Library__\n\n* ~RC4 speed improvements\n* Lua samples/bindings now work properly\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.5@@\n\n!!__SSL Library__\n\n* Session id's can now be variable lengths in server hello messages.\n* 0 length client certificates are now supported.\n* ssl_version() now returns just the version and not the date.\n* ssl_write() was not sending complete packets under load.\n\n!!__axhttpd__\n\n* Completely updated the CGI code.\n* Lua now integrated - Lua scripts and Lua Pages now run.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.4@@\n\n!!__SSL Library__\n\n* Fixed a Win32 crypto library issue with non-Administrator users\n* Removed compiler warnings that showed up in ~FC6.\n* GNU TLS certificates are now accepted.\n* Separated the send/receive headers for HMAC calculations.\n* Fixed a compilation problem with swig/perl/~FC6.\n* Fixed an issue with loading PEM CA certificates.\n\n!!__axhttpd__\n\n* Made //setuid()/setgid()// call an mconf option.\n* Made //chroot()// an mconf option. Default to //chdir()// instead.\n* Removed optional permissions checking.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.1@@\n\n!!__SSL Library__\n\n* AES should now work on 16bit processors (there was an alignment problem).\n* Various freed objects are cleared before freeing.\n* Header files now installed in ///usr/local/include/axTLS//.\n* -DCYGWIN replaced with -~DCONFIG_PLATFORM_CYGWIN (and the same for Solaris).\n* removed &quot;-noextern&quot; option in Swig. Fixed some other warnings in Win32.\n* SSLCTX changed to ~SSL_CTX (to be consistent with openssl). SSLCTX still exists for backwards compatibility.\n* malloc() and friends call abort() on failure.\n* Fixed a memory leak in directory listings.\n* Added openssl() compatibility functions.\n* Fixed Cygwin 'make install' issue.\n\n!!__axhttpd__\n\n* main.c now becomes axhttpd.c.\n* Header file issue fixed (in mime_types.c).\n* //chroot()// now used for better security.\n* Basic authentication implemented (via .htpasswd).\n* SSL access/denial protection implemented (via .htaccess).\n* Directory access protection implemented (via .htaccess).\n* Can now have more than one CGI file extension in mconf.\n* &quot;~If-Modified-Since&quot; request now handled properly.\n* Performance tweaks to remove //ssl_find()//.</div>
<div tiddler="Changelog" modifier="YourName" modified="200811051153" created="200702240022" tags="">@@bgcolor(#ff0000):color(#ffffff):Changes for 1.2@@\n\n!!__SSL Library__\n* A self-signed certificate will be verified as ok provided that that it is on the certificate authority list.\n* Certificates are not verified when added as certificate authorities (since self-signed and expired certificates can be added to browsers etc)\n\n@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.9@@\n\n!!__SSL Library__\n* Now support MS IIS resource kit certificates (thanks to Carsten Sørensen).\n* Fixed a memory leak when freeing more than one CA certificate.\n* The bigint library had a problem with squaring which affected classical reduction (thanks to Manuel Klimek).\n\n!!__axhttpd__\n* Brought back setuid()/setgid() as an option.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.8@@\n\n!!__SSL Library__\n* Now using a BSD style license.\n* Self-signed certificates can now be automatically generated (the keys still need to be provided).\n* A new API call //ssl_x509_create()// can be used to programatically create the certificate.\n* Certificate/keys can be loaded automatically given a file location.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.7@@\n\n!!__SSL Library__\n\n* Variable sized session id's is now better handled for session caching. It has meant a new API call //ssl_get_session_id_size()// and a change to //ssl_client_new()// to define the session id size.\n* Muliple records with a single header are now better supported (thanks to Hervé Sibert).\n* ~MD2 added for Verisign root cert verification (thanks to Byron Rakitzis).\n* The ~MD5/~SHA1 digests are calculated incrementally to reduce memory (thanks to Byron Rakitzis).\n* The bigint cache is now cleared regularly to reduce memory.\n\n!!__axhttpd__\n\n* Improved the POST handling (thanks to Christian Melki).\n* CSS files now work properly.\n* Lua's CGI launcher location is configurable.\n* //vfork()// is now used for CGI for performance reasons.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.6@@\n\n!!__SSL Library__\n\n* ~RC4 speed improvements\n* Lua samples/bindings now work properly\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.5@@\n\n!!__SSL Library__\n\n* Session id's can now be variable lengths in server hello messages.\n* 0 length client certificates are now supported.\n* ssl_version() now returns just the version and not the date.\n* ssl_write() was not sending complete packets under load.\n\n!!__axhttpd__\n\n* Completely updated the CGI code.\n* Lua now integrated - Lua scripts and Lua Pages now run.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.4@@\n\n!!__SSL Library__\n\n* Fixed a Win32 crypto library issue with non-Administrator users\n* Removed compiler warnings that showed up in ~FC6.\n* GNU TLS certificates are now accepted.\n* Separated the send/receive headers for HMAC calculations.\n* Fixed a compilation problem with swig/perl/~FC6.\n* Fixed an issue with loading PEM CA certificates.\n\n!!__axhttpd__\n\n* Made //setuid()/setgid()// call an mconf option.\n* Made //chroot()// an mconf option. Default to //chdir()// instead.\n* Removed optional permissions checking.\n\n!@@bgcolor(#ff0000):color(#ffffff):Changes for 1.1.1@@\n\n!!__SSL Library__\n\n* AES should now work on 16bit processors (there was an alignment problem).\n* Various freed objects are cleared before freeing.\n* Header files now installed in ///usr/local/include/axTLS//.\n* -DCYGWIN replaced with -~DCONFIG_PLATFORM_CYGWIN (and the same for Solaris).\n* removed &quot;-noextern&quot; option in Swig. Fixed some other warnings in Win32.\n* SSLCTX changed to ~SSL_CTX (to be consistent with openssl). SSLCTX still exists for backwards compatibility.\n* malloc() and friends call abort() on failure.\n* Fixed a memory leak in directory listings.\n* Added openssl() compatibility functions.\n* Fixed Cygwin 'make install' issue.\n\n!!__axhttpd__\n\n* main.c now becomes axhttpd.c.\n* Header file issue fixed (in mime_types.c).\n* //chroot()// now used for better security.\n* Basic authentication implemented (via .htpasswd).\n* SSL access/denial protection implemented (via .htaccess).\n* Directory access protection implemented (via .htaccess).\n* Can now have more than one CGI file extension in mconf.\n* &quot;~If-Modified-Since&quot; request now handled properly.\n* Performance tweaks to remove //ssl_find()//.</div>
<div tiddler="DefaultTiddlers" modifier="CameronRich" modified="200702240019" created="200702240019" tags="">[[Read Me]]</div>
<div tiddler="License" modifier="YourName" modified="200804011309" created="200702240022" tags="">axTLS uses a BSD style license:\n\nCopyright (c) 2008, Cameron Rich All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer. Redistributions in binary\nform must reproduce the above copyright notice, this list of conditions and\nthe following disclaimer in the documentation and/or other materials\nprovided with the distribution. Neither the name of the axTLS Project nor\nthe names of its contributors may be used to endorse or promote products\nderived from this software without specific prior written permission. \n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.</div>
<div tiddler="MainMenu" modifier="CameronRich" modified="200702250353" created="200702240021" tags="">[[Read Me]] \n[[Changelog]]\n[[axhttpd]]\n[[License]]</div>