summaryrefslogtreecommitdiff
path: root/extra/yassl
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-02-11 23:50:40 +0100
committerSergei Golubchik <serg@mariadb.org>2015-02-11 23:50:40 +0100
commit8e80f91fa3e584d6b681bfbb4664e80a255af866 (patch)
treeaf4f13f6f0290ee72b33a0642aa7c03e4e5fcd1c /extra/yassl
parent63108dc9d2cc9f31ae9927817652be465a17f767 (diff)
parent3ee8aa216d55b858ba9e53874359dcac9a82933a (diff)
downloadmariadb-git-8e80f91fa3e584d6b681bfbb4664e80a255af866.tar.gz
Merge remote-tracking branch 'mysql/5.5' into bb-5.5-merge @ mysql-5.5.42
Diffstat (limited to 'extra/yassl')
-rw-r--r--extra/yassl/README10
-rw-r--r--extra/yassl/examples/client/client.cpp11
-rw-r--r--extra/yassl/examples/server/server.cpp23
-rw-r--r--extra/yassl/include/openssl/ssl.h2
-rw-r--r--extra/yassl/include/yassl_int.hpp21
-rw-r--r--extra/yassl/src/yassl_imp.cpp29
-rw-r--r--extra/yassl/src/yassl_int.cpp76
-rw-r--r--extra/yassl/taocrypt/src/asn.cpp8
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp10
-rw-r--r--extra/yassl/testsuite/cipher-test.sh130
-rw-r--r--extra/yassl/testsuite/test.hpp42
11 files changed, 342 insertions, 20 deletions
diff --git a/extra/yassl/README b/extra/yassl/README
index 30c7af4a702..da399c3d141 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -12,6 +12,16 @@ before calling SSL_new();
*** end Note ***
+yaSSL Release notes, version 2.3.7 (12/10/2014)
+ This release of yaSSL fixes the potential to process duplicate handshake
+ messages by explicitly marking/checking received handshake messages.
+
+yaSSL Release notes, version 2.3.6 (11/25/2014)
+
+ This release of yaSSL fixes some valgrind warnings/errors including
+ uninitialized reads and off by one index errors induced from fuzzing
+ the handshake. These were reported by Oracle.
+
yaSSL Release notes, version 2.3.5 (9/29/2014)
This release of yaSSL fixes an RSA Padding check vulnerability reported by
diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp
index fc05b66aaf7..102ed61734c 100644
--- a/extra/yassl/examples/client/client.cpp
+++ b/extra/yassl/examples/client/client.cpp
@@ -18,6 +18,10 @@
/* client.cpp */
+// takes an optional command line argument of cipher list to make scripting
+// easier
+
+
#include "../../testsuite/test.hpp"
//#define TEST_RESUME
@@ -73,11 +77,16 @@ void client_test(void* args)
#ifdef NON_BLOCKING
tcp_set_nonblocking(sockfd);
#endif
-
SSL_METHOD* method = TLSv1_client_method();
SSL_CTX* ctx = SSL_CTX_new(method);
set_certs(ctx);
+ if (argc >= 2) {
+ printf("setting cipher list to %s\n", argv[1]);
+ if (SSL_CTX_set_cipher_list(ctx, argv[1]) != SSL_SUCCESS) {
+ ClientError(ctx, NULL, sockfd, "set_cipher_list error\n");
+ }
+ }
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp
index 173ce8fb548..1540f6d3689 100644
--- a/extra/yassl/examples/server/server.cpp
+++ b/extra/yassl/examples/server/server.cpp
@@ -18,6 +18,9 @@
/* server.cpp */
+// takes 2 optional command line argument to make scripting
+// if the first command line argument is 'n' client auth is disabled
+// if the second command line argument is 'd' DSA certs are used instead of RSA
#include "../../testsuite/test.hpp"
@@ -69,6 +72,9 @@ THREAD_RETURN YASSL_API server_test(void* args)
char** argv = 0;
set_args(argc, argv, *static_cast<func_args*>(args));
+#ifdef SERVER_READY_FILE
+ set_file_ready("server_ready", *static_cast<func_args*>(args));
+#endif
tcp_accept(sockfd, clientfd, *static_cast<func_args*>(args));
tcp_close(sockfd);
@@ -77,8 +83,21 @@ THREAD_RETURN YASSL_API server_test(void* args)
SSL_CTX* ctx = SSL_CTX_new(method);
//SSL_CTX_set_cipher_list(ctx, "RC4-SHA:RC4-MD5");
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
- set_serverCerts(ctx);
+
+ // should we disable client auth
+ if (argc >= 2 && argv[1][0] == 'n')
+ printf("disabling client auth\n");
+ else
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
+
+ // are we using DSA certs
+ if (argc >= 3 && argv[2][0] == 'd') {
+ printf("using DSA certs\n");
+ set_dsaServerCerts(ctx);
+ }
+ else {
+ set_serverCerts(ctx);
+ }
DH* dh = set_tmpDH(ctx);
SSL* ssl = SSL_new(ctx);
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index e678c600fed..24acc7e86b9 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -35,7 +35,7 @@
#include "rsa.h"
-#define YASSL_VERSION "2.3.5"
+#define YASSL_VERSION "2.3.7"
#if defined(__cplusplus)
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index f93727aa9f3..9f28cbe7726 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -107,6 +107,25 @@ enum AcceptState {
};
+// track received messages to explicitly disallow duplicate messages
+struct RecvdMessages {
+ uint8 gotClientHello_;
+ uint8 gotServerHello_;
+ uint8 gotCert_;
+ uint8 gotServerKeyExchange_;
+ uint8 gotCertRequest_;
+ uint8 gotServerHelloDone_;
+ uint8 gotCertVerify_;
+ uint8 gotClientKeyExchange_;
+ uint8 gotFinished_;
+ RecvdMessages() : gotClientHello_(0), gotServerHello_(0), gotCert_(0),
+ gotServerKeyExchange_(0), gotCertRequest_(0),
+ gotServerHelloDone_(0), gotCertVerify_(0),
+ gotClientKeyExchange_(0), gotFinished_(0)
+ {}
+};
+
+
// combines all states
class States {
RecordLayerState recordLayer_;
@@ -115,6 +134,7 @@ class States {
ServerState serverState_;
ConnectState connectState_;
AcceptState acceptState_;
+ RecvdMessages recvdMessages_;
char errorString_[MAX_ERROR_SZ];
YasslError what_;
public:
@@ -137,6 +157,7 @@ public:
AcceptState& UseAccept();
char* useString();
void SetError(YasslError);
+ int SetMessageRecvd(HandShakeType);
private:
States(const States&); // hide copy
States& operator=(const States&); // and assign
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index e2da042457f..742d07956da 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -242,6 +242,7 @@ void EncryptedPreMasterSecret::read(SSL& ssl, input_buffer& input)
}
opaque preMasterSecret[SECRET_LEN];
+ memset(preMasterSecret, 0, sizeof(preMasterSecret));
rsa.decrypt(preMasterSecret, secret_, length_,
ssl.getCrypto().get_random());
@@ -300,6 +301,11 @@ void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input)
tmp[1] = input[AUTO];
ato16(tmp, keyLength);
+ if (keyLength < dh.get_agreedKeyLength()/2) {
+ ssl.SetError(bad_input);
+ return;
+ }
+
alloc(keyLength);
input.read(Yc_, keyLength);
if (input.get_error()) {
@@ -408,6 +414,10 @@ void DH_Server::read(SSL& ssl, input_buffer& input)
tmp[1] = input[AUTO];
ato16(tmp, length);
+ if (length == 0) {
+ ssl.SetError(bad_input);
+ return;
+ }
signature_ = NEW_YS byte[length];
input.read(signature_, length);
if (input.get_error()) {
@@ -864,6 +874,12 @@ void ChangeCipherSpec::Process(input_buffer& input, SSL& ssl)
return;
}
+ // detect duplicate change_cipher
+ if (ssl.getSecurity().get_parms().pending_ == false) {
+ ssl.order_error();
+ return;
+ }
+
ssl.useSecurity().use_parms().pending_ = false;
if (ssl.getSecurity().get_resuming()) {
if (ssl.getSecurity().get_parms().entity_ == client_end)
@@ -2047,12 +2063,8 @@ input_buffer& operator>>(input_buffer& input, CertificateRequest& request)
tmp[0] = input[AUTO];
tmp[1] = input[AUTO];
ato16(tmp, dnSz);
-
- DistinguishedName dn;
- request.certificate_authorities_.push_back(dn = NEW_YS
- byte[REQUEST_HEADER + dnSz]);
- memcpy(dn, tmp, REQUEST_HEADER);
- input.read(&dn[REQUEST_HEADER], dnSz);
+
+ input.set_current(input.get_current() + dnSz);
sz -= dnSz + REQUEST_HEADER;
@@ -2191,6 +2203,11 @@ input_buffer& operator>>(input_buffer& input, CertificateVerify& request)
ato16(tmp, sz);
request.set_length(sz);
+ if (sz == 0) {
+ input.set_error();
+ return input;
+ }
+
request.signature_ = NEW_YS byte[sz];
input.read(request.signature_, sz);
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 75e4dc54523..a98b4f3c9bd 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -255,6 +255,77 @@ void States::SetError(YasslError ye)
}
+// mark message recvd, check for duplicates, return 0 on success
+int States::SetMessageRecvd(HandShakeType hst)
+{
+ switch (hst) {
+ case hello_request:
+ break; // could send more than one
+
+ case client_hello:
+ if (recvdMessages_.gotClientHello_)
+ return -1;
+ recvdMessages_.gotClientHello_ = 1;
+ break;
+
+ case server_hello:
+ if (recvdMessages_.gotServerHello_)
+ return -1;
+ recvdMessages_.gotServerHello_ = 1;
+ break;
+
+ case certificate:
+ if (recvdMessages_.gotCert_)
+ return -1;
+ recvdMessages_.gotCert_ = 1;
+ break;
+
+ case server_key_exchange:
+ if (recvdMessages_.gotServerKeyExchange_)
+ return -1;
+ recvdMessages_.gotServerKeyExchange_ = 1;
+ break;
+
+ case certificate_request:
+ if (recvdMessages_.gotCertRequest_)
+ return -1;
+ recvdMessages_.gotCertRequest_ = 1;
+ break;
+
+ case server_hello_done:
+ if (recvdMessages_.gotServerHelloDone_)
+ return -1;
+ recvdMessages_.gotServerHelloDone_ = 1;
+ break;
+
+ case certificate_verify:
+ if (recvdMessages_.gotCertVerify_)
+ return -1;
+ recvdMessages_.gotCertVerify_ = 1;
+ break;
+
+ case client_key_exchange:
+ if (recvdMessages_.gotClientKeyExchange_)
+ return -1;
+ recvdMessages_.gotClientKeyExchange_ = 1;
+ break;
+
+ case finished:
+ if (recvdMessages_.gotFinished_)
+ return -1;
+ recvdMessages_.gotFinished_ = 1;
+ break;
+
+
+ default:
+ return -1;
+
+ }
+
+ return 0;
+}
+
+
sslFactory::sslFactory() :
messageFactory_(InitMessageFactory),
handShakeFactory_(InitHandShakeFactory),
@@ -1199,6 +1270,11 @@ void SSL::verifyState(const HandShakeHeader& hsHeader)
return;
}
+ if (states_.SetMessageRecvd(hsHeader.get_handshakeType()) != 0) {
+ order_error();
+ return;
+ }
+
if (secure_.get_parms().entity_ == client_end)
verifyClientState(hsHeader.get_handshakeType());
else
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index 544e9518da8..d521088d74a 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -672,7 +672,7 @@ word32 CertDecoder::GetSignature()
}
sigLength_ = GetLength(source_);
- if (sigLength_ == 0 || source_.IsLeft(sigLength_) == false) {
+ if (sigLength_ <= 1 || source_.IsLeft(sigLength_) == false) {
source_.SetError(CONTENT_E);
return 0;
}
@@ -1001,11 +1001,17 @@ bool CertDecoder::ConfirmSignature(Source& pub)
RSA_PublicKey pubKey(pub);
RSAES_Encryptor enc(pubKey);
+ if (pubKey.FixedCiphertextLength() != sigLength_) {
+ source_.SetError(SIG_LEN_E);
+ return false;
+ }
+
return enc.SSL_Verify(build.get_buffer(), build.size(), signature_);
}
else { // DSA
// extract r and s from sequence
byte seqDecoded[DSA_SIG_SZ];
+ memset(seqDecoded, 0, sizeof(seqDecoded));
DecodeDSA_Signature(seqDecoded, signature_, sigLength_);
DSA_PublicKey pubKey(pub);
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index b5262e543a4..d8510066d04 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -2605,18 +2605,20 @@ void Integer::Decode(Source& source)
void Integer::Decode(const byte* input, unsigned int inputLen, Signedness s)
{
unsigned int idx(0);
- byte b = input[idx++];
+ byte b = 0;
+ if (inputLen>0)
+ b = input[idx]; // peek
sign_ = ((s==SIGNED) && (b & 0x80)) ? NEGATIVE : POSITIVE;
while (inputLen>0 && (sign_==POSITIVE ? b==0 : b==0xff))
{
- inputLen--;
- b = input[idx++];
+ idx++; // skip
+ if (--inputLen>0)
+ b = input[idx]; // peek
}
reg_.CleanNew(RoundupSize(BytesToWords(inputLen)));
- --idx;
for (unsigned int i=inputLen; i > 0; i--)
{
b = input[idx++];
diff --git a/extra/yassl/testsuite/cipher-test.sh b/extra/yassl/testsuite/cipher-test.sh
new file mode 100644
index 00000000000..5ce29459d07
--- /dev/null
+++ b/extra/yassl/testsuite/cipher-test.sh
@@ -0,0 +1,130 @@
+#!/bin/bash
+
+# test all yassl cipher suties
+#
+
+
+server_pid=$no_pid
+
+
+do_cleanup() {
+ echo "in cleanup"
+
+ if [[ $server_pid != $no_pid ]]
+ then
+ echo "killing server"
+ kill -9 $server_pid
+ fi
+}
+
+do_trap() {
+ echo "got trap"
+ do_cleanup
+ exit -1
+}
+
+trap do_trap INT TERM
+
+
+# make sure example server and client are built
+if test ! -s ../examples/server/server; then
+ echo "Please build yaSSL first, example server missing"
+ exit -1
+fi
+
+if test ! -s ../examples/client/client; then
+ echo "Please build yaSSL first, example client missing"
+ exit -1
+fi
+
+
+# non DSA suites
+for suite in {"DHE-RSA-AES256-SHA","AES256-SHA","DHE-RSA-AES128-SHA","AES128-SHA","AES256-RMD","AES128-RMD","DES-CBC3-RMD","DHE-RSA-AES256-RMD","DHE-RSA-AES128-RMD","DHE-RSA-DES-CBC3-RMD","RC4-SHA","RC4-MD5","DES-CBC3-SHA","DES-CBC-SHA","EDH-RSA-DES-CBC3-SHA","EDH-RSA-DES-CBC-SHA"}
+do
+ for client_auth in {y,n}
+ do
+ echo "Trying $suite client auth = $client_auth ..."
+
+ if test -e server_ready; then
+ echo -e "removing exisitng server_ready file"
+ rm server_ready
+ fi
+ ../examples/server/server $client_auth &
+ server_pid=$!
+
+ while [ ! -s server_ready ]; do
+ echo -e "waiting for server_ready file..."
+ sleep 0.1
+ done
+
+ ../examples/client/client $suite
+ client_result=$?
+
+ wait $server_pid
+ server_result=$?
+
+ server_pid=$no_pid
+
+ if [[ $client_result != 0 ]]
+ then
+ echo "Client Error"
+ exit $client_result
+ fi
+
+ if [[ $server_result != 0 ]]
+ then
+ echo "Server Error"
+ exit $server_result
+ fi
+
+ done # end client auth loop
+done # end non dsa suite list
+echo -e "Non DSA Loop SUCCESS"
+
+
+
+# DSA suites
+for suite in {"DHE-DSS-AES256-SHA","DHE-DSS-AES128-SHA","DHE-DSS-AES256-RMD","DHE-DSS-AES128-RMD","DHE-DSS-DES-CBC3-RMD","EDH-DSS-DES-CBC3-SHA","EDH-DSS-DES-CBC-SHA"}
+do
+ for client_auth in {y,n}
+ do
+ echo "Trying $suite client auth = $client_auth ..."
+
+ if test -e server_ready; then
+ echo -e "removing exisitng server_ready file"
+ rm server_ready
+ fi
+ # d signifies DSA
+ ../examples/server/server $client_auth d &
+ server_pid=$!
+
+ while [ ! -s server_ready ]; do
+ echo -e "waiting for server_ready file..."
+ sleep 0.1
+ done
+
+ ../examples/client/client $suite
+ client_result=$?
+
+ wait $server_pid
+ server_result=$?
+
+ server_pid=$no_pid
+
+ if [[ $client_result != 0 ]]
+ then
+ echo "Client Error"
+ exit $client_result
+ fi
+
+ if [[ $server_result != 0 ]]
+ then
+ echo "Server Error"
+ exit $server_result
+ fi
+
+ done # end client auth loop
+done # end dsa suite list
+echo -e "DSA Loop SUCCESS"
+
+exit 0
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index 33f398ae269..52f6ed79526 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -131,9 +131,10 @@ struct func_args {
int argc;
char** argv;
int return_code;
+ const char* file_ready;
tcp_ready* signal_;
- func_args(int c = 0, char** v = 0) : argc(c), argv(v) {}
+ func_args(int c = 0, char** v = 0) : argc(c), argv(v), file_ready(0) {}
void SetSignal(tcp_ready* p) { signal_ = p; }
};
@@ -146,6 +147,7 @@ void join_thread(THREAD_TYPE);
// yaSSL
const char* const yasslIP = "127.0.0.1";
const unsigned short yasslPort = 11111;
+const unsigned short proxyPort = 12345;
// client
@@ -172,13 +174,13 @@ const char* const svrKey3 = "../../../certs/server-key.pem";
// server dsa
const char* const dsaCert = "../certs/dsa-cert.pem";
-const char* const dsaKey = "../certs/dsa512.der";
+const char* const dsaKey = "../certs/dsa1024.der";
const char* const dsaCert2 = "../../certs/dsa-cert.pem";
-const char* const dsaKey2 = "../../certs/dsa512.der";
+const char* const dsaKey2 = "../../certs/dsa1024.der";
const char* const dsaCert3 = "../../../certs/dsa-cert.pem";
-const char* const dsaKey3 = "../../../certs/dsa512.der";
+const char* const dsaKey3 = "../../../certs/dsa1024.der";
// CA
@@ -222,6 +224,13 @@ inline void store_ca(SSL_CTX* ctx)
if (SSL_CTX_load_verify_locations(ctx, certSuite, 0) != SSL_SUCCESS)
if (SSL_CTX_load_verify_locations(ctx, certDebug,0) != SSL_SUCCESS)
err_sys("failed to use certificate: certs/client-cert.pem");
+
+ // DSA cert
+ if (SSL_CTX_load_verify_locations(ctx, dsaCert, 0) != SSL_SUCCESS)
+ if (SSL_CTX_load_verify_locations(ctx, dsaCert2, 0) != SSL_SUCCESS)
+ if (SSL_CTX_load_verify_locations(ctx, dsaCert3, 0) != SSL_SUCCESS)
+ err_sys("failed to use certificate: certs/dsa-cert.pem");
+
}
@@ -298,7 +307,7 @@ inline void set_dsaServerCerts(SSL_CTX* ctx)
!= SSL_SUCCESS)
if (SSL_CTX_use_PrivateKey_file(ctx, dsaKey3,SSL_FILETYPE_ASN1)
!= SSL_SUCCESS)
- err_sys("failed to use key file: certs/dsa512.der");
+ err_sys("failed to use key file: certs/dsa1024.der");
}
@@ -310,6 +319,12 @@ inline void set_args(int& argc, char**& argv, func_args& args)
}
+inline void set_file_ready(const char* name, func_args& args)
+{
+ args.file_ready = name;
+}
+
+
inline void tcp_set_nonblocking(SOCKET_T& sockfd)
{
#ifdef NON_BLOCKING
@@ -349,7 +364,11 @@ inline void tcp_socket(SOCKET_T& sockfd, SOCKADDR_IN_T& addr)
*/ // end external testing later
#else
addr.sin_family = AF_INET_V;
+#ifdef YASSL_PROXY_PORT
+ addr.sin_port = htons(proxyPort);
+#else
addr.sin_port = htons(yasslPort);
+#endif
addr.sin_addr.s_addr = inet_addr(yasslIP);
#endif
@@ -401,6 +420,16 @@ inline void tcp_listen(SOCKET_T& sockfd)
}
+inline void create_ready_file(func_args& args)
+{
+ FILE* f = fopen(args.file_ready, "w+");
+
+ if (f) {
+ fputs("ready", f);
+ fclose(f);
+ }
+}
+
inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args)
{
@@ -418,6 +447,9 @@ inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args)
pthread_mutex_unlock(&ready.mutex_);
#endif
+ if (args.file_ready)
+ create_ready_file(args);
+
clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len);
if (clientfd == (SOCKET_T) -1) {