Import OpenSSL 1.0.1p.

This commit is contained in:
Jung-uk Kim 2015-07-09 16:41:34 +00:00
parent 15533bcc35
commit c07d7b3a38
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor-crypto/openssl/dist/; revision=285327
svn path=/vendor-crypto/openssl/1.0.1p/; revision=285328; tag=vendor/openssl/1.0.1p
22 changed files with 477 additions and 235 deletions

15
CHANGES
View File

@ -2,6 +2,21 @@
OpenSSL CHANGES
_______________
Changes between 1.0.1o and 1.0.1p [9 Jul 2015]
*) Alternate chains certificate forgery
During certificate verfification, OpenSSL will attempt to find an
alternative certificate chain if the first attempt to build such a chain
fails. An error in the implementation of this logic can mean that an
attacker could cause certain checks on untrusted certificates to be
bypassed, such as the CA flag, enabling them to use a valid leaf
certificate to act as a CA and "issue" an invalid certificate.
This issue was reported to OpenSSL by Adam Langley/David Benjamin
(Google/BoringSSL).
[Matt Caswell]
Changes between 1.0.1n and 1.0.1o [12 Jun 2015]
*) Fix HMAC ABI incompatibility. The previous version introduced an ABI

View File

@ -11,8 +11,8 @@ First, read http://wiki.freebsd.org/SubversionPrimer/VendorImports
# Xlist
setenv XLIST /FreeBSD/work/openssl/svn-FREEBSD-files/FREEBSD-Xlist
setenv FSVN "svn+ssh://svn.freebsd.org/base"
setenv OSSLVER 1.0.1o
# OSSLTAG format: v1_0_1o
setenv OSSLVER 1.0.1p
# OSSLTAG format: v1_0_1p
###setenv OSSLTAG v`echo ${OSSLVER} | tr . _`

View File

@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
VERSION=1.0.1o
VERSION=1.0.1p
MAJOR=1
MINOR=0.1
SHLIB_VERSION_NUMBER=1.0.0
@ -270,6 +270,7 @@ reflect:
@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
sub_all: build_all
build_all: build_libs build_apps build_tests build_tools
build_libs: build_libcrypto build_libssl openssl.pc
@ -279,15 +280,15 @@ build_libssl: build_ssl libssl.pc
build_crypto:
@dir=crypto; target=all; $(BUILD_ONE_CMD)
build_ssl:
build_ssl: build_crypto
@dir=ssl; target=all; $(BUILD_ONE_CMD)
build_engines:
build_engines: build_crypto
@dir=engines; target=all; $(BUILD_ONE_CMD)
build_apps:
build_apps: build_libs
@dir=apps; target=all; $(BUILD_ONE_CMD)
build_tests:
build_tests: build_libs
@dir=test; target=all; $(BUILD_ONE_CMD)
build_tools:
build_tools: build_libs
@dir=tools; target=all; $(BUILD_ONE_CMD)
all_testapps: build_libs build_testapps

View File

@ -268,6 +268,7 @@ reflect:
@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
sub_all: build_all
build_all: build_libs build_apps build_tests build_tools
build_libs: build_libcrypto build_libssl openssl.pc
@ -277,15 +278,15 @@ build_libssl: build_ssl libssl.pc
build_crypto:
@dir=crypto; target=all; $(BUILD_ONE_CMD)
build_ssl:
build_ssl: build_crypto
@dir=ssl; target=all; $(BUILD_ONE_CMD)
build_engines:
build_engines: build_crypto
@dir=engines; target=all; $(BUILD_ONE_CMD)
build_apps:
build_apps: build_libs
@dir=apps; target=all; $(BUILD_ONE_CMD)
build_tests:
build_tests: build_libs
@dir=test; target=all; $(BUILD_ONE_CMD)
build_tools:
build_tools: build_libs
@dir=tools; target=all; $(BUILD_ONE_CMD)
all_testapps: build_libs build_testapps

4
NEWS
View File

@ -5,6 +5,10 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
Major changes between OpenSSL 1.0.1o and OpenSSL 1.0.1p [9 Jul 2015]
o Alternate chains certificate forgery (CVE-2015-1793)
Major changes between OpenSSL 1.0.1n and OpenSSL 1.0.1o [12 Jun 2015]
o Fix HMAC ABI incompatibility

2
README
View File

@ -1,5 +1,5 @@
OpenSSL 1.0.1o 12 Jun 2015
OpenSSL 1.0.1p 9 Jul 2015
Copyright (c) 1998-2011 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson

View File

@ -290,7 +290,7 @@ void BIO_clear_flags(BIO *b, int flags);
* BIO_CB_RETURN flag indicates if it is after the call
*/
# define BIO_CB_RETURN 0x80
# define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
# define BIO_CB_return(a) ((a)|BIO_CB_RETURN)
# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN))
# define BIO_cb_post(a) ((a)&BIO_CB_RETURN)

View File

@ -1146,7 +1146,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
case EVP_CTRL_CCM_SET_TAG:
if ((arg & 1) || arg < 4 || arg > 16)
return 0;
if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
if (c->encrypt && ptr)
return 0;
if (ptr) {
cctx->tag_set = 1;

View File

@ -185,7 +185,7 @@ extern "C" {
#endif
#if defined(DES_RISC1) && defined(DES_RISC2)
YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#endif
/* Unroll the inner loop, this sometimes helps, sometimes hinders.

View File

@ -101,7 +101,7 @@
#endif
#if defined(DES_RISC1) && defined(DES_RISC2)
YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#endif
/* Unroll the inner loop, this sometimes helps, sometimes hinders.

View File

@ -30,11 +30,11 @@ extern "C" {
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
# define OPENSSL_VERSION_NUMBER 0x100010ffL
# define OPENSSL_VERSION_NUMBER 0x1000110fL
# ifdef OPENSSL_FIPS
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1o-fips 12 Jun 2015"
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1p-fips 9 Jul 2015"
# else
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1o 12 Jun 2015"
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1p 9 Jul 2015"
# endif
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT

View File

@ -135,10 +135,12 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
while ((x = sk_X509_pop(ocerts))) {
if (pkey && *pkey && cert && !*cert) {
ERR_set_mark();
if (X509_check_private_key(x, *pkey)) {
*cert = x;
x = NULL;
}
ERR_pop_to_mark();
}
if (ca && x) {

View File

@ -56,7 +56,6 @@
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@ -86,17 +85,11 @@
#include <openssl/lhash.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include "../../e_os.h"
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#ifdef OPENSSL_NO_FP_API
# define APPS_WIN16
# include "../buffer/bss_file.c"
#endif
#ifdef OPENSSL_SYS_NETWARE
# define TEST_SERVER_CERT "/openssl/apps/server.pem"
# define TEST_CLIENT_CERT "/openssl/apps/client.pem"
@ -107,23 +100,23 @@
#define MAX_THREAD_NUMBER 100
int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs);
int verify_callback(int ok, X509_STORE_CTX *xs);
void thread_setup(void);
void thread_cleanup(void);
void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx);
void irix_locking_callback(int mode, int type, char *file, int line);
void solaris_locking_callback(int mode, int type, char *file, int line);
void win32_locking_callback(int mode, int type, char *file, int line);
void pthreads_locking_callback(int mode, int type, char *file, int line);
void netware_locking_callback(int mode, int type, char *file, int line);
void irix_locking_callback(int mode, int type, const char *file, int line);
void solaris_locking_callback(int mode, int type, const char *file, int line);
void win32_locking_callback(int mode, int type, const char *file, int line);
void pthreads_locking_callback(int mode, int type, const char *file, int line);
void netware_locking_callback(int mode, int type, const char *file, int line);
void beos_locking_callback(int mode, int type, const char *file, int line);
unsigned long irix_thread_id(void);
unsigned long solaris_thread_id(void);
unsigned long pthreads_thread_id(void);
unsigned long netware_thread_id(void);
unsigned long beos_thread_id(void);
void irix_thread_id(CRYPTO_THREADID *tid);
void solaris_thread_id(CRYPTO_THREADID *tid);
void pthreads_thread_id(CRYPTO_THREADID *tid);
void netware_thread_id(CRYPTO_THREADID *tid);
void beos_thread_id(CRYPTO_THREADID *tid);
#if defined(OPENSSL_SYS_NETWARE)
static MPKMutex *lock_cs;
@ -149,39 +142,39 @@ static const char rnd_seed[] =
"string to make the random number generator think it has entropy";
int doit(char *ctx[4]);
static void print_stats(FILE *fp, SSL_CTX *ctx)
static void print_stats(BIO *bio, SSL_CTX *ctx)
{
fprintf(fp, "%4ld items in the session cache\n",
SSL_CTX_sess_number(ctx));
fprintf(fp, "%4d client connects (SSL_connect())\n",
SSL_CTX_sess_connect(ctx));
fprintf(fp, "%4d client connects that finished\n",
SSL_CTX_sess_connect_good(ctx));
fprintf(fp, "%4d server connects (SSL_accept())\n",
SSL_CTX_sess_accept(ctx));
fprintf(fp, "%4d server connects that finished\n",
SSL_CTX_sess_accept_good(ctx));
fprintf(fp, "%4d session cache hits\n", SSL_CTX_sess_hits(ctx));
fprintf(fp, "%4d session cache misses\n", SSL_CTX_sess_misses(ctx));
fprintf(fp, "%4d session cache timeouts\n", SSL_CTX_sess_timeouts(ctx));
BIO_printf(bio, "%4ld items in the session cache\n",
SSL_CTX_sess_number(ctx));
BIO_printf(bio, "%4d client connects (SSL_connect())\n",
SSL_CTX_sess_connect(ctx));
BIO_printf(bio, "%4d client connects that finished\n",
SSL_CTX_sess_connect_good(ctx));
BIO_printf(bio, "%4d server connects (SSL_accept())\n",
SSL_CTX_sess_accept(ctx));
BIO_printf(bio, "%4d server connects that finished\n",
SSL_CTX_sess_accept_good(ctx));
BIO_printf(bio, "%4d session cache hits\n", SSL_CTX_sess_hits(ctx));
BIO_printf(bio, "%4d session cache misses\n", SSL_CTX_sess_misses(ctx));
BIO_printf(bio, "%4d session cache timeouts\n", SSL_CTX_sess_timeouts(ctx));
}
static void sv_usage(void)
{
fprintf(stderr, "usage: ssltest [args ...]\n");
fprintf(stderr, "\n");
fprintf(stderr, " -server_auth - check server certificate\n");
fprintf(stderr, " -client_auth - do client authentication\n");
fprintf(stderr, " -v - more output\n");
fprintf(stderr, " -CApath arg - PEM format directory of CA's\n");
fprintf(stderr, " -CAfile arg - PEM format file of CA's\n");
fprintf(stderr, " -threads arg - number of threads\n");
fprintf(stderr, " -loops arg - number of 'connections', per thread\n");
fprintf(stderr, " -reconnect - reuse session-id's\n");
fprintf(stderr, " -stats - server session-id cache stats\n");
fprintf(stderr, " -cert arg - server certificate/key\n");
fprintf(stderr, " -ccert arg - client certificate/key\n");
fprintf(stderr, " -ssl3 - just SSLv3n\n");
BIO_printf(bio_err, "usage: ssltest [args ...]\n");
BIO_printf(bio_err, "\n");
BIO_printf(bio_err, " -server_auth - check server certificate\n");
BIO_printf(bio_err, " -client_auth - do client authentication\n");
BIO_printf(bio_err, " -v - more output\n");
BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n");
BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n");
BIO_printf(bio_err, " -threads arg - number of threads\n");
BIO_printf(bio_err, " -loops arg - number of 'connections', per thread\n");
BIO_printf(bio_err, " -reconnect - reuse session-id's\n");
BIO_printf(bio_err, " -stats - server session-id cache stats\n");
BIO_printf(bio_err, " -cert arg - server certificate/key\n");
BIO_printf(bio_err, " -ccert arg - client certificate/key\n");
BIO_printf(bio_err, " -ssl3 - just SSLv3n\n");
}
int main(int argc, char *argv[])
@ -195,14 +188,14 @@ int main(int argc, char *argv[])
SSL_CTX *c_ctx = NULL;
char *scert = TEST_SERVER_CERT;
char *ccert = TEST_CLIENT_CERT;
SSL_METHOD *ssl_method = SSLv23_method();
const SSL_METHOD *ssl_method = SSLv23_method();
RAND_seed(rnd_seed, sizeof rnd_seed);
if (bio_err == NULL)
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
bio_err = BIO_new_fd(2, BIO_NOCLOSE);
if (bio_stdout == NULL)
bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
bio_stdout = BIO_new_fd(1, BIO_NOCLOSE);
argc--;
argv++;
@ -250,7 +243,7 @@ int main(int argc, char *argv[])
if (number_of_loops == 0)
number_of_loops = 1;
} else {
fprintf(stderr, "unknown option %s\n", *argv);
BIO_printf(bio_err, "unknown option %s\n", *argv);
badop = 1;
break;
}
@ -284,9 +277,12 @@ int main(int argc, char *argv[])
SSL_SESS_CACHE_SERVER);
if (!SSL_CTX_use_certificate_file(s_ctx, scert, SSL_FILETYPE_PEM)) {
BIO_printf(bio_err, "SSL_CTX_use_certificate_file (%s)\n", scert);
ERR_print_errors(bio_err);
goto end;
} else
if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx, scert, SSL_FILETYPE_PEM)) {
BIO_printf(bio_err, "SSL_CTX_use_RSAPrivateKey_file (%s)\n", scert);
ERR_print_errors(bio_err);
goto end;
}
@ -300,19 +296,19 @@ int main(int argc, char *argv[])
(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
(!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) ||
(!SSL_CTX_set_default_verify_paths(c_ctx))) {
fprintf(stderr, "SSL_load_verify_locations\n");
BIO_printf(bio_err, "SSL_load_verify_locations\n");
ERR_print_errors(bio_err);
goto end;
}
if (client_auth) {
fprintf(stderr, "client authentication\n");
BIO_printf(bio_err, "client authentication\n");
SSL_CTX_set_verify(s_ctx,
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
verify_callback);
}
if (server_auth) {
fprintf(stderr, "server authentication\n");
BIO_printf(bio_err, "server authentication\n");
SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback);
}
@ -322,24 +318,24 @@ int main(int argc, char *argv[])
end:
if (c_ctx != NULL) {
fprintf(stderr, "Client SSL_CTX stats then free it\n");
print_stats(stderr, c_ctx);
BIO_printf(bio_err, "Client SSL_CTX stats then free it\n");
print_stats(bio_err, c_ctx);
SSL_CTX_free(c_ctx);
}
if (s_ctx != NULL) {
fprintf(stderr, "Server SSL_CTX stats then free it\n");
print_stats(stderr, s_ctx);
BIO_printf(bio_err, "Server SSL_CTX stats then free it\n");
print_stats(bio_err, s_ctx);
if (cache_stats) {
fprintf(stderr, "-----\n");
lh_stats(SSL_CTX_sessions(s_ctx), stderr);
fprintf(stderr, "-----\n");
/*- lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
fprintf(stderr,"-----\n"); */
lh_node_usage_stats(SSL_CTX_sessions(s_ctx), stderr);
fprintf(stderr, "-----\n");
BIO_printf(bio_err, "-----\n");
lh_SSL_SESSION_stats_bio(SSL_CTX_sessions(s_ctx), bio_err);
BIO_printf(bio_err, "-----\n");
/*- lh_SSL_SESSION_node_stats_bio(SSL_CTX_sessions(s_ctx),bio_err);
BIO_printf(bio_err,"-----\n"); */
lh_SSL_SESSION_node_usage_stats_bio(SSL_CTX_sessions(s_ctx), bio_err);
BIO_printf(bio_err, "-----\n");
}
SSL_CTX_free(s_ctx);
fprintf(stderr, "done free\n");
BIO_printf(bio_err, "done free\n");
}
exit(ret);
return (0);
@ -355,6 +351,7 @@ int ndoit(SSL_CTX *ssl_ctx[2])
int i;
int ret;
char *ctx[4];
CRYPTO_THREADID thread_id;
ctx[0] = (char *)ssl_ctx[0];
ctx[1] = (char *)ssl_ctx[1];
@ -367,22 +364,24 @@ int ndoit(SSL_CTX *ssl_ctx[2])
ctx[3] = NULL;
}
fprintf(stdout, "started thread %lu\n", CRYPTO_thread_id());
CRYPTO_THREADID_current(&thread_id);
BIO_printf(bio_stdout, "started thread %lu\n",
CRYPTO_THREADID_hash(&thread_id));
for (i = 0; i < number_of_loops; i++) {
/*- fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
CRYPTO_thread_id(),i,
ssl_ctx[0]->references,
ssl_ctx[1]->references); */
/*- BIO_printf(bio_err,"%4d %2d ctx->ref (%3d,%3d)\n",
CRYPTO_THREADID_hash(&thread_id),i,
ssl_ctx[0]->references,
ssl_ctx[1]->references); */
/* pthread_delay_np(&tm); */
ret = doit(ctx);
if (ret != 0) {
fprintf(stdout, "error[%d] %lu - %d\n",
i, CRYPTO_thread_id(), ret);
BIO_printf(bio_stdout, "error[%d] %lu - %d\n",
i, CRYPTO_THREADID_hash(&thread_id), ret);
return (ret);
}
}
fprintf(stdout, "DONE %lu\n", CRYPTO_thread_id());
BIO_printf(bio_stdout, "DONE %lu\n", CRYPTO_THREADID_hash(&thread_id));
if (reconnect) {
SSL_free((SSL *)ctx[2]);
SSL_free((SSL *)ctx[3]);
@ -467,26 +466,26 @@ int doit(char *ctx[4])
if (do_server && verbose) {
if (SSL_in_init(s_ssl))
printf("server waiting in SSL_accept - %s\n",
SSL_state_string_long(s_ssl));
BIO_printf(bio_stdout, "server waiting in SSL_accept - %s\n",
SSL_state_string_long(s_ssl));
else if (s_write)
printf("server:SSL_write()\n");
BIO_printf(bio_stdout, "server:SSL_write()\n");
else
printf("server:SSL_read()\n");
BIO_printf(bio_stdout, "server:SSL_read()\n");
}
if (do_client && verbose) {
if (SSL_in_init(c_ssl))
printf("client waiting in SSL_connect - %s\n",
SSL_state_string_long(c_ssl));
BIO_printf(bio_stdout, "client waiting in SSL_connect - %s\n",
SSL_state_string_long(c_ssl));
else if (c_write)
printf("client:SSL_write()\n");
BIO_printf(bio_stdout, "client:SSL_write()\n");
else
printf("client:SSL_read()\n");
BIO_printf(bio_stdout, "client:SSL_read()\n");
}
if (!do_client && !do_server) {
fprintf(stdout, "ERROR IN STARTUP\n");
BIO_printf(bio_stdout, "ERROR IN STARTUP\n");
break;
}
if (do_client && !(done & C_DONE)) {
@ -501,12 +500,12 @@ int doit(char *ctx[4])
if (BIO_should_write(c_bio))
c_w = 1;
} else {
fprintf(stderr, "ERROR in CLIENT\n");
BIO_printf(bio_err, "ERROR in CLIENT\n");
ERR_print_errors_fp(stderr);
return (1);
}
} else if (i == 0) {
fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
BIO_printf(bio_err, "SSL CLIENT STARTUP FAILED\n");
return (1);
} else {
/* ok */
@ -523,19 +522,19 @@ int doit(char *ctx[4])
if (BIO_should_write(c_bio))
c_w = 1;
} else {
fprintf(stderr, "ERROR in CLIENT\n");
BIO_printf(bio_err, "ERROR in CLIENT\n");
ERR_print_errors_fp(stderr);
return (1);
}
} else if (i == 0) {
fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
BIO_printf(bio_err, "SSL CLIENT STARTUP FAILED\n");
return (1);
} else {
done |= C_DONE;
#ifdef undef
fprintf(stdout, "CLIENT:from server:");
fwrite(cbuf, 1, i, stdout);
fflush(stdout);
BIO_printf(bio_stdout, "CLIENT:from server:");
BIO_write(bio_stdout, cbuf, i);
BIO_flush(bio_stdout);
#endif
}
}
@ -553,20 +552,20 @@ int doit(char *ctx[4])
if (BIO_should_write(s_bio))
s_w = 1;
} else {
fprintf(stderr, "ERROR in SERVER\n");
BIO_printf(bio_err, "ERROR in SERVER\n");
ERR_print_errors_fp(stderr);
return (1);
}
} else if (i == 0) {
fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
BIO_printf(bio_err, "SSL SERVER STARTUP FAILED\n");
return (1);
} else {
s_write = 1;
s_w = 1;
#ifdef undef
fprintf(stdout, "SERVER:from client:");
fwrite(sbuf, 1, i, stdout);
fflush(stdout);
BIO_printf(bio_stdout, "SERVER:from client:");
BIO_write(bio_stdout, sbuf, i);
BIO_flush(bio_stdout);
#endif
}
} else {
@ -580,12 +579,12 @@ int doit(char *ctx[4])
if (BIO_should_write(s_bio))
s_w = 1;
} else {
fprintf(stderr, "ERROR in SERVER\n");
BIO_printf(bio_err, "ERROR in SERVER\n");
ERR_print_errors_fp(stderr);
return (1);
}
} else if (i == 0) {
fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
BIO_printf(bio_err, "SSL SERVER STARTUP FAILED\n");
return (1);
} else {
s_write = 0;
@ -606,7 +605,7 @@ int doit(char *ctx[4])
SSL_set_shutdown(s_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#ifdef undef
fprintf(stdout, "DONE\n");
BIO_printf(bio_stdout, "DONE\n");
#endif
err:
/*
@ -640,7 +639,7 @@ int doit(char *ctx[4])
return (0);
}
int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
int verify_callback(int ok, X509_STORE_CTX *ctx)
{
char *s, buf[256];
@ -649,9 +648,9 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
buf, 256);
if (s != NULL) {
if (ok)
fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf);
BIO_printf(bio_err, "depth=%d %s\n", ctx->error_depth, buf);
else
fprintf(stderr, "depth=%d error=%d %s\n",
BIO_printf(bio_err, "depth=%d error=%d %s\n",
ctx->error_depth, ctx->error, buf);
}
}
@ -688,7 +687,7 @@ void thread_cleanup(void)
OPENSSL_free(lock_cs);
}
void win32_locking_callback(int mode, int type, char *file, int line)
void win32_locking_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
WaitForSingleObject(lock_cs[type], INFINITE);
@ -717,7 +716,7 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
(void *)ssl_ctx, 0L, &(thread_id[i]));
}
printf("reaping\n");
BIO_printf(bio_stdout, "reaping\n");
for (i = 0; i < thread_number; i += 50) {
int j;
@ -727,7 +726,7 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
(CONST HANDLE *) & (thread_handle[i]),
TRUE, INFINITE)
== WAIT_FAILED) {
fprintf(stderr, "WaitForMultipleObjects failed:%d\n",
BIO_printf(bio_err, "WaitForMultipleObjects failed:%d\n",
GetLastError());
exit(1);
}
@ -743,7 +742,7 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
ret = (ret + end.wSecond - start.wSecond);
ret += (end.wMilliseconds - start.wMilliseconds) / 1000.0;
printf("win32 threads done - %.3f seconds\n", ret);
BIO_printf(bio_stdout, "win32 threads done - %.3f seconds\n", ret);
}
#endif /* OPENSSL_SYS_WIN32 */
@ -768,8 +767,8 @@ void thread_setup(void)
mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
CRYPTO_set_id_callback(solaris_thread_id);
CRYPTO_set_locking_callback(solaris_locking_callback);
}
void thread_cleanup(void)
@ -778,34 +777,34 @@ void thread_cleanup(void)
CRYPTO_set_locking_callback(NULL);
fprintf(stderr, "cleanup\n");
BIO_printf(bio_err, "cleanup\n");
for (i = 0; i < CRYPTO_num_locks(); i++) {
/* rwlock_destroy(&(lock_cs[i])); */
mutex_destroy(&(lock_cs[i]));
fprintf(stderr, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
fprintf(stderr, "done cleanup\n");
BIO_printf(bio_err, "done cleanup\n");
}
void solaris_locking_callback(int mode, int type, char *file, int line)
void solaris_locking_callback(int mode, int type, const char *file, int line)
{
# ifdef undef
fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode & CRYPTO_LOCK) ? "l" : "u",
(type & CRYPTO_READ) ? "r" : "w", file, line);
BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode & CRYPTO_LOCK) ? "l" : "u",
(type & CRYPTO_READ) ? "r" : "w", file, line);
# endif
/*-
if (CRYPTO_LOCK_SSL_CERT == type)
fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
CRYPTO_thread_id(),
mode,file,line);
BIO_printf(bio_err,"(t,m,f,l) %ld %d %s %d\n",
CRYPTO_thread_id(),
mode,file,line);
*/
if (mode & CRYPTO_LOCK) {
/*-
@ -837,21 +836,22 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
(void *(*)())ndoit, (void *)ssl_ctx, 0L, &(thread_ctx[i]));
}
printf("reaping\n");
BIO_printf(bio_stdout, "reaping\n");
for (i = 0; i < thread_number; i++) {
thr_join(thread_ctx[i], NULL, NULL);
}
printf("solaris threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#if 0 /* We can't currently find out the reference amount */
BIO_printf(bio_stdout, "solaris threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#else
BIO_printf(bio_stdout, "solaris threads done\n");
#endif
}
unsigned long solaris_thread_id(void)
void solaris_thread_id(CRYPTO_THREADID *tid)
{
unsigned long ret;
ret = (unsigned long)thr_self();
return (ret);
CRYPTO_THREADID_set_numeric((unsigned long)thr_self());
}
#endif /* SOLARIS */
@ -880,8 +880,8 @@ void thread_setup(void)
lock_cs[i] = usnewsema(arena, 1);
}
CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
CRYPTO_set_id_callback(irix_thread_id);
CRYPTO_set_locking_callback(irix_locking_callback);
}
void thread_cleanup(void)
@ -899,13 +899,13 @@ void thread_cleanup(void)
OPENSSL_free(lock_cs);
}
void irix_locking_callback(int mode, int type, char *file, int line)
void irix_locking_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
printf("lock %d\n", type);
BIO_printf(bio_stdout, "lock %d\n", type);
uspsema(lock_cs[type]);
} else {
printf("unlock %d\n", type);
BIO_printf(bio_stdout, "unlock %d\n", type);
usvsema(lock_cs[type]);
}
}
@ -924,21 +924,22 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
PR_SADDR | PR_SFDS, (void *)ssl_ctx);
}
printf("reaping\n");
BIO_printf(bio_stdout, "reaping\n");
for (i = 0; i < thread_number; i++) {
wait(NULL);
}
printf("irix threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#if 0 /* We can't currently find out the reference amount */
BIO_printf(bio_stdout, "irix threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#else
BIO_printf(bio_stdout, "irix threads done\n");
#endif
}
unsigned long irix_thread_id(void)
{
unsigned long ret;
ret = (unsigned long)getpid();
return (ret);
CRYPTO_THREADID_set_numeric((unsigned long)getpid());
}
#endif /* IRIX */
@ -958,8 +959,8 @@ void thread_setup(void)
pthread_mutex_init(&(lock_cs[i]), NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
CRYPTO_THREADID_set_callback(pthreads_thread_id);
CRYPTO_set_locking_callback(pthreads_locking_callback);
}
void thread_cleanup(void)
@ -967,30 +968,30 @@ void thread_cleanup(void)
int i;
CRYPTO_set_locking_callback(NULL);
fprintf(stderr, "cleanup\n");
BIO_printf(bio_err, "cleanup\n");
for (i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
fprintf(stderr, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
fprintf(stderr, "done cleanup\n");
BIO_printf(bio_err, "done cleanup\n");
}
void pthreads_locking_callback(int mode, int type, char *file, int line)
void pthreads_locking_callback(int mode, int type, const char *file, int line)
{
# ifdef undef
fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode & CRYPTO_LOCK) ? "l" : "u",
(type & CRYPTO_READ) ? "r" : "w", file, line);
BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode & CRYPTO_LOCK) ? "l" : "u",
(type & CRYPTO_READ) ? "r" : "w", file, line);
# endif
/*-
if (CRYPTO_LOCK_SSL_CERT == type)
fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
CRYPTO_thread_id(),
mode,file,line);
BIO_printf(bio_err,"(t,m,f,l) %ld %d %s %d\n",
CRYPTO_thread_id(),
mode,file,line);
*/
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
@ -1017,21 +1018,22 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
(void *(*)())ndoit, (void *)ssl_ctx);
}
printf("reaping\n");
BIO_printf(bio_stdout, "reaping\n");
for (i = 0; i < thread_number; i++) {
pthread_join(thread_ctx[i], NULL);
}
printf("pthreads threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#if 0 /* We can't currently find out the reference amount */
BIO_printf(bio_stdout, "pthreads threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#else
BIO_printf(bio_stdout, "pthreads threads done\n");
#endif
}
unsigned long pthreads_thread_id(void)
void pthreads_thread_id(CRYPTO_THREADID *tid)
{
unsigned long ret;
ret = (unsigned long)pthread_self();
return (ret);
CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self());
}
#endif /* PTHREADS */
@ -1051,8 +1053,8 @@ void thread_setup(void)
ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0);
CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id);
CRYPTO_set_locking_callback((void (*)())netware_locking_callback);
CRYPTO_set_id_callback(netware_thread_id);
CRYPTO_set_locking_callback(netware_locking_callback);
}
void thread_cleanup(void)
@ -1061,21 +1063,21 @@ void thread_cleanup(void)
CRYPTO_set_locking_callback(NULL);
fprintf(stdout, "thread_cleanup\n");
BIO_printf(bio_stdout, "thread_cleanup\n");
for (i = 0; i < CRYPTO_num_locks(); i++) {
MPKMutexFree(lock_cs[i]);
fprintf(stdout, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
BIO_printf(bio_stdout, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
MPKSemaphoreFree(ThreadSem);
fprintf(stdout, "done cleanup\n");
BIO_printf(bio_stdout, "done cleanup\n");
}
void netware_locking_callback(int mode, int type, char *file, int line)
void netware_locking_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
MPKMutexLock(lock_cs[type]);
@ -1097,22 +1099,23 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
ThreadSwitchWithDelay();
}
printf("reaping\n");
BIO_printf(bio_stdout, "reaping\n");
/* loop until all threads have signaled the semaphore */
for (i = 0; i < thread_number; i++) {
MPKSemaphoreWait(ThreadSem);
}
printf("netware threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#if 0 /* We can't currently find out the reference amount */
BIO_printf(bio_stdout, "netware threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
#else
BIO_printf(bio_stdout, "netware threads done\n");
#endif
}
unsigned long netware_thread_id(void)
{
unsigned long ret;
ret = (unsigned long)GetThreadID();
return (ret);
CRYPTO_THREADID_set_numeric((unsigned long)GetThreadID());
}
#endif /* NETWARE */
@ -1144,24 +1147,24 @@ void thread_cleanup(void)
int i;
CRYPTO_set_locking_callback(NULL);
fprintf(stderr, "cleanup\n");
BIO_printf(bio_err, "cleanup\n");
for (i = 0; i < CRYPTO_num_locks(); i++) {
delete lock_cs[i];
fprintf(stderr, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
fprintf(stderr, "done cleanup\n");
BIO_printf(bio_err, "done cleanup\n");
}
void beos_locking_callback(int mode, int type, const char *file, int line)
{
# if 0
fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode & CRYPTO_LOCK) ? "l" : "u",
(type & CRYPTO_READ) ? "r" : "w", file, line);
BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode & CRYPTO_LOCK) ? "l" : "u",
(type & CRYPTO_READ) ? "r" : "w", file, line);
# endif
if (mode & CRYPTO_LOCK) {
lock_cs[type]->Lock();
@ -1187,14 +1190,14 @@ void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
resume_thread(thread_ctx[i]);
}
printf("waiting...\n");
BIO_printf(bio_stdout, "waiting...\n");
for (i = 0; i < thread_number; i++) {
status_t result;
wait_for_thread(thread_ctx[i], &result);
}
printf("beos threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
BIO_printf(bio_stdout, "beos threads done (%d,%d)\n",
s_ctx->references, c_ctx->references);
}
unsigned long beos_thread_id(void)

View File

@ -3,5 +3,4 @@
# build using pthreads where it's already built into the system
#
/bin/rm -f mttest
gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -lpthread
gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -lpthread -ldl

View File

@ -13,7 +13,7 @@ AR= ar r
CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile README
TEST=
TEST=verify_extra_test.c
APPS=
LIB=$(TOP)/libcrypto.a

View File

@ -0,0 +1,209 @@
/*
* Written by Matt Caswell for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/err.h>
static STACK_OF(X509) *load_certs_from_file(const char *filename)
{
STACK_OF(X509) *certs;
BIO *bio;
X509 *x;
bio = BIO_new_file(filename, "r");
if (bio == NULL) {
return NULL;
}
certs = sk_X509_new_null();
if (certs == NULL) {
BIO_free(bio);
return NULL;
}
ERR_set_mark();
do {
x = PEM_read_bio_X509(bio, NULL, 0, NULL);
if (x != NULL && !sk_X509_push(certs, x)) {
sk_X509_pop_free(certs, X509_free);
BIO_free(bio);
return NULL;
} else if (x == NULL) {
/*
* We probably just ran out of certs, so ignore any errors
* generated
*/
ERR_pop_to_mark();
}
} while (x != NULL);
BIO_free(bio);
return certs;
}
/*
* Test for CVE-2015-1793 (Alternate Chains Certificate Forgery)
*
* Chain is as follows:
*
* rootCA (self-signed)
* |
* interCA
* |
* subinterCA subinterCA (self-signed)
* | |
* leaf ------------------
* |
* bad
*
* rootCA, interCA, subinterCA, subinterCA (ss) all have CA=TRUE
* leaf and bad have CA=FALSE
*
* subinterCA and subinterCA (ss) have the same subject name and keys
*
* interCA (but not rootCA) and subinterCA (ss) are in the trusted store
* (roots.pem)
* leaf and subinterCA are in the untrusted list (untrusted.pem)
* bad is the certificate being verified (bad.pem)
*
* Versions vulnerable to CVE-2015-1793 will fail to detect that leaf has
* CA=FALSE, and will therefore incorrectly verify bad
*
*/
static int test_alt_chains_cert_forgery(void)
{
int ret = 0;
int i;
X509 *x = NULL;
STACK_OF(X509) *untrusted = NULL;
BIO *bio = NULL;
X509_STORE_CTX *sctx = NULL;
X509_STORE *store = NULL;
X509_LOOKUP *lookup = NULL;
store = X509_STORE_new();
if (store == NULL)
goto err;
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
if (lookup == NULL)
goto err;
if(!X509_LOOKUP_load_file(lookup, "certs/roots.pem", X509_FILETYPE_PEM))
goto err;
untrusted = load_certs_from_file("certs/untrusted.pem");
if ((bio = BIO_new_file("certs/bad.pem", "r")) == NULL)
goto err;
if((x = PEM_read_bio_X509(bio, NULL, 0, NULL)) == NULL)
goto err;
sctx = X509_STORE_CTX_new();
if (sctx == NULL)
goto err;
if (!X509_STORE_CTX_init(sctx, store, x, untrusted))
goto err;
i = X509_verify_cert(sctx);
if(i == 0 && X509_STORE_CTX_get_error(sctx)
== X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) {
/* This is the result we were expecting: Test passed */
ret = 1;
}
err:
X509_STORE_CTX_free(sctx);
X509_free(x);
BIO_free(bio);
sk_X509_pop_free(untrusted, X509_free);
X509_STORE_free(store);
if (ret != 1)
ERR_print_errors_fp(stderr);
return ret;
}
int main(void)
{
CRYPTO_malloc_debug_init();
CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
ERR_load_crypto_strings();
OpenSSL_add_all_digests();
if (!test_alt_chains_cert_forgery()) {
fprintf(stderr, "Test alt chains cert forgery failed\n");
return 1;
}
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_thread_state(NULL);
ERR_free_strings();
CRYPTO_mem_leaks_fp(stderr);
printf("PASS\n");
return 0;
}

View File

@ -162,6 +162,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
return -1;
}
if (ctx->chain != NULL) {
/*
* This X509_STORE_CTX has already been used to verify a cert. We
* cannot do another one.
*/
X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
cb = ctx->verify_cb;
@ -169,15 +177,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
* first we make sure the chain we are going to build is present and that
* the first entry is in place
*/
if (ctx->chain == NULL) {
if (((ctx->chain = sk_X509_new_null()) == NULL) ||
(!sk_X509_push(ctx->chain, ctx->cert))) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
goto end;
}
CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
ctx->last_untrusted = 1;
if (((ctx->chain = sk_X509_new_null()) == NULL) ||
(!sk_X509_push(ctx->chain, ctx->cert))) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
goto end;
}
CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
ctx->last_untrusted = 1;
/* We use a temporary STACK so we can chop and hack at it */
if (ctx->untrusted != NULL
@ -306,7 +312,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
* if the user hasn't switched off alternate chain checking
*/
retry = 0;
if (j == ctx->last_untrusted &&
if (num == ctx->last_untrusted &&
!(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
while (j-- > 1) {
xtmp2 = sk_X509_value(ctx->chain, j - 1);
@ -328,8 +334,8 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
xtmp = sk_X509_pop(ctx->chain);
X509_free(xtmp);
num--;
ctx->last_untrusted--;
}
ctx->last_untrusted = sk_X509_num(ctx->chain);
retry = 1;
break;
}

View File

@ -29,6 +29,7 @@ and issuer names.
X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ() retrieve
the next index matching B<nid> or B<obj> after B<lastpos>. B<lastpos>
should initially be set to -1. If there are no more entries -1 is returned.
If B<nid> is invalid (doesn't correspond to a valid OID) then -2 is returned.
X509_NAME_entry_count() returns the total number of entries in B<name>.
@ -63,6 +64,10 @@ The list of all relevant B<NID_*> and B<OBJ_* codes> can be found in
the source code header files E<lt>openssl/obj_mac.hE<gt> and/or
E<lt>openssl/objects.hE<gt>.
Applications which could pass invalid NIDs to X509_NAME_get_index_by_NID()
should check for the return value of -2. Alternatively the NID validity
can be determined first by checking OBJ_nid2obj(nid) is not NULL.
=head1 EXAMPLES
Process all entries:
@ -95,6 +100,8 @@ Process all commonName entries:
X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ()
return the index of the next matching entry or -1 if not found.
X509_NAME_get_index_by_NID() can also return -2 if the supplied
NID is invalid.
X509_NAME_entry_count() returns the total number of entries.

View File

@ -39,10 +39,15 @@ X509_STORE_CTX_free() completely frees up B<ctx>. After this call B<ctx>
is no longer valid.
X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation.
The trusted certificate store is set to B<store>, the end entity certificate
to be verified is set to B<x509> and a set of additional certificates (which
will be untrusted but may be used to build the chain) in B<chain>. Any or
all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>.
It must be called before each call to X509_verify_cert(), i.e. a B<ctx> is only
good for one call to X509_verify_cert(); if you want to verify a second
certificate with the same B<ctx> then you must call X509_XTORE_CTX_cleanup()
and then X509_STORE_CTX_init() again before the second call to
X509_verify_cert(). The trusted certificate store is set to B<store>, the end
entity certificate to be verified is set to B<x509> and a set of additional
certificates (which will be untrusted but may be used to build the chain) in
B<chain>. Any or all of the B<store>, B<x509> and B<chain> parameters can be
B<NULL>.
X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx>
to B<sk>. This is an alternative way of specifying trusted certificates

View File

@ -32,7 +32,8 @@ OpenSSL internally for certificate validation, in both the S/MIME and
SSL/TLS code.
The negative return value from X509_verify_cert() can only occur if no
certificate is set in B<ctx> (due to a programming error) or if a retry
certificate is set in B<ctx> (due to a programming error); if X509_verify_cert()
twice without reinitialising B<ctx> in between; or if a retry
operation is requested during internal lookups (which never happens with
standard lookup methods). It is however recommended that application check
for <= 0 return value on error.

View File

@ -1381,8 +1381,6 @@ int ssl3_get_key_exchange(SSL *s)
#ifndef OPENSSL_NO_PSK
if (alg_k & SSL_kPSK) {
char tmp_id_hint[PSK_MAX_IDENTITY_LEN + 1];
param_len = 2;
if (param_len > n) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
@ -1408,17 +1406,8 @@ int ssl3_get_key_exchange(SSL *s)
}
param_len += i;
/*
* If received PSK identity hint contains NULL characters, the hint
* is truncated from the first NULL. p may not be ending with NULL,
* so create a NULL-terminated string.
*/
memcpy(tmp_id_hint, p, i);
memset(tmp_id_hint + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i);
if (s->ctx->psk_identity_hint != NULL)
OPENSSL_free(s->ctx->psk_identity_hint);
s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
if (s->ctx->psk_identity_hint == NULL) {
s->session->psk_identity_hint = BUF_strndup((char *)p, i);
if (s->session->psk_identity_hint == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
@ -2951,7 +2940,7 @@ int ssl3_send_client_key_exchange(SSL *s)
}
memset(identity, 0, sizeof(identity));
psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
identity, sizeof(identity) - 1,
psk_or_pre_ms,
sizeof(psk_or_pre_ms));

View File

@ -2792,7 +2792,7 @@ int ssl3_get_client_key_exchange(SSL *s)
if (s->session->psk_identity != NULL)
OPENSSL_free(s->session->psk_identity);
s->session->psk_identity = BUF_strdup((char *)p);
s->session->psk_identity = BUF_strndup((char *)p, i);
if (s->session->psk_identity == NULL) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto psk_err;