mirror of
https://github.com/esp8266/Arduino.git
synced 2025-10-16 22:27:59 +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:
@@ -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:
|
||||
|
19
ssl/tls1.c
19
ssl/tls1.c
@@ -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:
|
||||
|
@@ -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? */
|
||||
|
144
ssl/x509.c
144
ssl/x509.c
@@ -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";
|
||||
|
||||
|
Reference in New Issue
Block a user