Import yaSSL version 1.4.0

parent d8e27606
yaSSL FLOSS License Exception
****************************************
Version 0.1, 26 June 2006
Version 0.2, 31 August 2006
The Sawtooth Consulting Ltd. Exception for Free/Libre and Open Source
Software-only Applications Using yaSSL Libraries (the "FLOSS Exception").
......@@ -81,6 +81,7 @@ the GPL:
Python license (CNRI Python License) -
Python Software Foundation License 2.1.1
Sleepycat License "1999"
University of Illinois/NCSA Open Source License -
W3C License "2001"
X11 License "2001"
Zlib/libpng License -
......
SUBDIRS = taocrypt src testsuite
EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp) CMakeLists.txt
EXTRA_DIST = yassl.dsp yassl.dsw CMakeLists.txt
yaSSL Release notes, version 1.3.7 (06/26/06)
yaSSL Release notes, version 1.4.0 (08/13/06)
This release of yaSSL contains bug fixes, portability enhancements,
nonblocking connect and accept, better OpenSSL error mapping, and
certificate caching for session resumption.
See normal build instructions below under 1.0.6.
See libcurl build instructions below under 1.3.0.
********************yaSSL Release notes, version 1.3.7 (06/26/06)
This release of yaSSL contains bug fixes, portability enhancements,
......
......@@ -27,7 +27,13 @@ void client_test(void* args)
SSL_set_fd(ssl, sockfd);
if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");
if (SSL_connect(ssl) != SSL_SUCCESS)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
err_sys("SSL_connect failed");
}
showPeer(ssl);
const char* cipher = 0;
......@@ -39,11 +45,16 @@ void client_test(void* args)
strncat(list, cipher, strlen(cipher) + 1);
}
printf("%s\n", list);
printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl));
printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl));
char msg[] = "hello yassl!";
if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
err_sys("SSL_write failed");
}
char reply[1024];
reply[SSL_read(ssl, reply, sizeof(reply))] = 0;
......@@ -56,22 +67,36 @@ void client_test(void* args)
SSL_shutdown(ssl);
SSL_free(ssl);
tcp_close(sockfd);
#ifdef TEST_RESUME
tcp_connect(sockfd);
SSL_set_fd(sslResume, sockfd);
SSL_set_session(sslResume, session);
if (SSL_connect(sslResume) != SSL_SUCCESS) err_sys("SSL resume failed");
if (SSL_connect(sslResume) != SSL_SUCCESS)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
err_sys("SSL resume failed");
}
showPeer(sslResume);
if (SSL_write(sslResume, msg, sizeof(msg)) != sizeof(msg))
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
err_sys("SSL_write failed");
}
reply[SSL_read(sslResume, reply, sizeof(reply))] = 0;
printf("Server response: %s\n", reply);
SSL_shutdown(sslResume);
SSL_free(sslResume);
tcp_close(sockfd);
#endif // TEST_RESUME
SSL_CTX_free(ctx);
......
......@@ -41,7 +41,14 @@ void echoclient_test(void* args)
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");
if (SSL_connect(ssl) != SSL_SUCCESS)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
err_sys("SSL_connect failed");
}
char send[1024];
char reply[1024];
......@@ -50,7 +57,12 @@ void echoclient_test(void* args)
int sendSz = strlen(send) + 1;
if (SSL_write(ssl, send, sendSz) != sendSz)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
err_sys("SSL_write failed");
}
if (strncmp(send, "quit", 4) == 0) {
fputs("sending server shutdown command: quit!\n", fout);
......@@ -63,6 +75,7 @@ void echoclient_test(void* args)
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
fflush(fout);
if (inCreated) fclose(fin);
......
......@@ -67,11 +67,23 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
socklen_t client_len = sizeof(client);
int clientfd = accept(sockfd, (sockaddr*)&client,
(ACCEPT_THIRD_T)&client_len);
if (clientfd == -1) err_sys("tcp accept failed");
if (clientfd == -1)
{
SSL_CTX_free(ctx);
tcp_close(sockfd);
err_sys("tcp accept failed");
}
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, clientfd);
if (SSL_accept(ssl) != SSL_SUCCESS) err_sys("SSL_accept failed");
if (SSL_accept(ssl) != SSL_SUCCESS)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
tcp_close(clientfd);
err_sys("SSL_accept failed");
}
char command[1024];
int echoSz(0);
......@@ -100,7 +112,14 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
echoSz += sizeof(footer);
if (SSL_write(ssl, command, echoSz) != echoSz)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
tcp_close(clientfd);
err_sys("SSL_write failed");
}
break;
}
command[echoSz] = 0;
......@@ -110,16 +129,19 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
#endif
if (SSL_write(ssl, command, echoSz) != echoSz)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
tcp_close(clientfd);
err_sys("SSL_write failed");
}
}
SSL_free(ssl);
tcp_close(clientfd);
}
#ifdef _WIN32
closesocket(sockfd);
#else
close(sockfd);
#endif
tcp_close(sockfd);
DH_free(dh);
SSL_CTX_free(ctx);
......
......@@ -19,11 +19,7 @@ THREAD_RETURN YASSL_API server_test(void* args)
set_args(argc, argv, *static_cast<func_args*>(args));
tcp_accept(sockfd, clientfd, *static_cast<func_args*>(args));
#ifdef _WIN32
closesocket(sockfd);
#else
close(sockfd);
#endif
tcp_close(sockfd);
SSL_METHOD* method = TLSv1_server_method();
SSL_CTX* ctx = SSL_CTX_new(method);
......@@ -36,9 +32,17 @@ THREAD_RETURN YASSL_API server_test(void* args)
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, clientfd);
if (SSL_accept(ssl) != SSL_SUCCESS) err_sys("SSL_accept failed");
if (SSL_accept(ssl) != SSL_SUCCESS)
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
tcp_close(clientfd);
err_sys("SSL_accept failed");
}
showPeer(ssl);
printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl));
printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl));
char command[1024];
command[SSL_read(ssl, command, sizeof(command))] = 0;
......@@ -46,12 +50,20 @@ THREAD_RETURN YASSL_API server_test(void* args)
char msg[] = "I hear you, fa shizzle!";
if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
{
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(sockfd);
tcp_close(clientfd);
err_sys("SSL_write failed");
}
DH_free(dh);
SSL_CTX_free(ctx);
SSL_free(ssl);
tcp_close(clientfd);
((func_args*)args)->return_code = 0;
return 0;
}
......
......@@ -34,7 +34,10 @@
#include <assert.h> // assert
#include "yassl_types.hpp" // ysDelete
#include "memory.hpp" // mySTL::auto_ptr
#include "algorithm.hpp" // mySTL::swap
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
#ifdef _MSC_VER
......@@ -199,7 +202,7 @@ struct del_ptr_zero
void operator()(T*& p) const
{
T* tmp = 0;
mySTL::swap(tmp, p);
STL::swap(tmp, p);
checked_delete(tmp);
}
};
......
......@@ -41,8 +41,12 @@
#include "yassl_types.hpp" // SignatureAlgorithm
#include "buffer.hpp" // input_buffer
#include "asn.hpp" // SignerList
#include "list.hpp" // mySTL::list
#include "algorithm.hpp" // mySTL::for_each
#include STL_LIST_FILE
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
namespace yaSSL {
......@@ -72,7 +76,7 @@ private:
// Certificate Manager keeps a list of the cert chain and public key
class CertManager {
typedef mySTL::list<x509*> CertList;
typedef STL::list<x509*> CertList;
CertList list_; // self
input_buffer privateKey_;
......@@ -120,6 +124,7 @@ public:
void setVerifyNone();
void setFailNoCert();
void setSendVerify();
void setPeerX509(X509*);
private:
CertManager(const CertManager&); // hide copy
CertManager& operator=(const CertManager&); // and assign
......
......@@ -416,7 +416,17 @@ private:
class x509;
x509* PemToDer(FILE*, CertType);
struct EncryptedInfo {
enum { IV_SZ = 32, NAME_SZ = 80 };
char name[NAME_SZ]; // max one line
byte iv[IV_SZ]; // in base16 rep
uint ivSz;
bool set;
EncryptedInfo() : ivSz(0), set(false) {}
};
x509* PemToDer(FILE*, CertType, EncryptedInfo* info = 0);
} // naemspace
......
......@@ -35,10 +35,12 @@
#ifndef yaSSL_FACTORY_HPP
#define yaSSL_FACTORY_HPP
#include "vector.hpp"
#include "pair.hpp"
#include STL_VECTOR_FILE
#include STL_PAIR_FILE
namespace STL = STL_NAMESPACE;
// VC60 workaround: it doesn't allow typename in some places
#if defined(_MSC_VER) && (_MSC_VER < 1300)
......@@ -58,8 +60,8 @@ template<class AbstractProduct,
typename ProductCreator = AbstractProduct* (*)()
>
class Factory {
typedef mySTL::pair<IdentifierType, ProductCreator> CallBack;
typedef mySTL::vector<CallBack> CallBackVector;
typedef STL::pair<IdentifierType, ProductCreator> CallBack;
typedef STL::vector<CallBack> CallBackVector;
CallBackVector callbacks_;
public:
......@@ -79,14 +81,16 @@ public:
// register callback
void Register(const IdentifierType& id, ProductCreator pc)
{
callbacks_.push_back(mySTL::make_pair(id, pc));
callbacks_.push_back(STL::make_pair(id, pc));
}
// THE Creator, returns a new object of the proper type or 0
AbstractProduct* CreateObject(const IdentifierType& id) const
{
const CallBack* first = callbacks_.begin();
const CallBack* last = callbacks_.end();
typedef typename STL::vector<CallBack>::const_iterator cIter;
cIter first = callbacks_.begin();
cIter last = callbacks_.end();
while (first != last) {
if (first->first == id)
......
......@@ -41,7 +41,7 @@
#include "rsa.h"
#define YASSL_VERSION "1.3.7"
#define YASSL_VERSION "1.4.2"
#if defined(__cplusplus)
......@@ -505,6 +505,8 @@ ASN1_TIME* X509_get_notAfter(X509* x);
#define V_ASN1_UTF8STRING 12
#define GEN_DNS 2
#define CERTFICATE_ERROR 0x14090086 /* SSLv3 error */
typedef struct MD4_CTX {
int buffer[32]; /* big enough to hold, check size in Init */
......
......@@ -71,6 +71,7 @@ typedef unsigned char byte;
class Socket {
socket_t socket_; // underlying socket descriptor
bool wouldBlock_; // for non-blocking data
bool blocking_; // is option set
public:
explicit Socket(socket_t s = INVALID_SOCKET);
~Socket();
......@@ -84,6 +85,7 @@ public:
bool wait();
bool WouldBlock() const;
bool IsBlocking() const;
void closeSocket();
void shutDown(int how = SD_SEND);
......
......@@ -54,7 +54,11 @@ enum YasslError {
verify_error = 112,
send_error = 113,
receive_error = 114,
certificate_error = 115
certificate_error = 115,
privateKey_error = 116,
badVersion_error = 117
// !!!! add error message to .cpp !!!!
// 1000+ from TaoCrypt error.hpp
......
......@@ -39,7 +39,10 @@
#include "yassl_types.hpp"
#include "factory.hpp"
#include "list.hpp" // mySTL::list
#include STL_LIST_FILE
namespace STL = STL_NAMESPACE;
namespace yaSSL {
......@@ -427,7 +430,7 @@ private:
class CertificateRequest : public HandShakeBase {
ClientCertificateType certificate_types_[CERT_TYPES];
int typeTotal_;
mySTL::list<DistinguishedName> certificate_authorities_;
STL::list<DistinguishedName> certificate_authorities_;
public:
CertificateRequest();
~CertificateRequest();
......
......@@ -40,6 +40,13 @@
#include "lock.hpp"
#include "openssl/ssl.h" // ASN1_STRING and DH
#ifdef _POSIX_THREADS
#include <pthread.h>
#endif
namespace STL = STL_NAMESPACE;
namespace yaSSL {
......@@ -80,12 +87,35 @@ enum ServerState {
};
// client connect state for nonblocking restart
enum ConnectState {
CONNECT_BEGIN = 0,
CLIENT_HELLO_SENT,
FIRST_REPLY_DONE,
FINISHED_DONE,
SECOND_REPLY_DONE
};
// server accpet state for nonblocking restart
enum AcceptState {
ACCEPT_BEGIN = 0,
ACCEPT_FIRST_REPLY_DONE,
SERVER_HELLO_DONE,
ACCEPT_SECOND_REPLY_DONE,
ACCEPT_FINISHED_DONE,
ACCEPT_THIRD_REPLY_DONE
};
// combines all states
class States {
RecordLayerState recordLayer_;
HandShakeState handshakeLayer_;
ClientState clientState_;
ServerState serverState_;
ConnectState connectState_;
AcceptState acceptState_;
char errorString_[MAX_ERROR_SZ];
YasslError what_;
public:
......@@ -95,6 +125,8 @@ public:
const HandShakeState& getHandShake() const;
const ClientState& getClient() const;
const ServerState& getServer() const;
const ConnectState& GetConnect() const;
const AcceptState& GetAccept() const;
const char* getString() const;
YasslError What() const;
......@@ -102,6 +134,8 @@ public:
HandShakeState& useHandShake();
ClientState& useClient();
ServerState& useServer();
ConnectState& UseConnect();
AcceptState& UseAccept();
char* useString();
void SetError(YasslError);
private:
......@@ -142,8 +176,9 @@ public:
X509_NAME(const char*, size_t sz);
~X509_NAME();
char* GetName();
const char* GetName() const;
ASN1_STRING* GetEntry(int i);
size_t GetLength() const;
private:
X509_NAME(const X509_NAME&); // hide copy
X509_NAME& operator=(const X509_NAME&); // and assign
......@@ -157,6 +192,9 @@ public:
~StringHolder();
ASN1_STRING* GetString();
private:
StringHolder(const StringHolder&); // hide copy
StringHolder& operator=(const StringHolder&); // and assign
};
......@@ -176,6 +214,7 @@ public:
ASN1_STRING* GetBefore();
ASN1_STRING* GetAfter();
private:
X509(const X509&); // hide copy
X509& operator=(const X509&); // and assign
......@@ -202,6 +241,7 @@ class SSL_SESSION {
uint bornOn_; // create time in seconds
uint timeout_; // timeout in seconds
RandomPool& random_; // will clean master secret
X509* peerX509_;
public:
explicit SSL_SESSION(RandomPool&);
SSL_SESSION(const SSL&, RandomPool&);
......@@ -212,17 +252,20 @@ public:
const Cipher* GetSuite() const;
uint GetBornOn() const;
uint GetTimeOut() const;
X509* GetPeerX509() const;
void SetTimeOut(uint);
SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
private:
SSL_SESSION(const SSL_SESSION&); // hide copy
void CopyX509(X509*);
};
// holds all sessions
class Sessions {
mySTL::list<SSL_SESSION*> list_;
STL::list<SSL_SESSION*> list_;
RandomPool random_; // for session cleaning
Mutex mutex_; // no-op for single threaded
......@@ -241,8 +284,42 @@ private:
};
#ifdef _POSIX_THREADS
typedef pthread_t THREAD_ID_T;
#else
typedef DWORD THREAD_ID_T;
#endif
// thread error data
struct ThreadError {
THREAD_ID_T threadID_;
int errorID_;
};
// holds all errors
class Errors {
STL::list<ThreadError> list_;
Mutex mutex_;
Errors() {} // only GetErrors can create
public:
int Lookup(bool peek); // self lookup
void Add(int);
void Remove(); // remove self
~Errors() {}
friend Errors& GetErrors(); // singleton creator
private:
Errors(const Errors&); // hide copy
Errors& operator=(const Errors); // and assign
};
Sessions& GetSessions(); // forward singletons
sslFactory& GetSSL_Factory();
Errors& GetErrors();
// openSSL method and context types
......@@ -252,8 +329,10 @@ class SSL_METHOD {
bool verifyPeer_; // request or send certificate
bool verifyNone_; // whether to verify certificate
bool failNoCert_;
bool multipleProtocol_; // for SSLv23 compatibility
public:
explicit SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv);
SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv,
bool multipleProtocol = false);
ProtocolVersion getVersion() const;
ConnectionEnd getSide() const;
......@@ -265,6 +344,7 @@ public:
bool verifyPeer() const;
bool verifyNone() const;
bool failNoCert() const;
bool multipleProtocol() const;
private:
SSL_METHOD(const SSL_METHOD&); // hide copy
SSL_METHOD& operator=(const SSL_METHOD&); // and assign
......@@ -334,7 +414,7 @@ private:
// the SSL context
class SSL_CTX {
public:
typedef mySTL::list<x509*> CertList;
typedef STL::list<x509*> CertList;
private:
SSL_METHOD* method_;
x509* certificate_;
......@@ -342,6 +422,8 @@ private:
CertList caList_;
Ciphers ciphers_;
DH_Parms dhParms_;
pem_password_cb passwordCb_;
void* userData_;
Stats stats_;
Mutex mutex_; // for Stats
public:
......@@ -354,12 +436,16 @@ public:
const Ciphers& GetCiphers() const;
const DH_Parms& GetDH_Parms() const;
const Stats& GetStats() const;
pem_password_cb GetPasswordCb() const;
void* GetUserData() const;
void setVerifyPeer();
void setVerifyNone();
void setFailNoCert();
bool SetCipherList(const char*);
bool SetDH(const DH&);
void SetPasswordCb(pem_password_cb cb);
void SetUserData(void*);
void IncrementStats(StatsField);
void AddCA(x509* ca);
......@@ -434,13 +520,14 @@ private:
// holds input and output buffers
class Buffers {
public:
typedef mySTL::list<input_buffer*> inputList;
typedef mySTL::list<output_buffer*> outputList;
typedef STL::list<input_buffer*> inputList;
typedef STL::list<output_buffer*> outputList;
private:
inputList dataList_; // list of users app data / handshake
outputList handShakeList_; // buffered handshake msgs
input_buffer* rawInput_; // buffered raw input yet to process
public:
Buffers() {}
Buffers();
~Buffers();
const inputList& getData() const;
......@@ -448,6 +535,9 @@ public:
inputList& useData();
outputList& useHandShake();
void SetRawInput(input_buffer*); // takes ownership
input_buffer* TakeRawInput(); // takes ownership
private:
Buffers(const Buffers&); // hide copy
Buffers& operator=(const Buffers&); // and assign
......@@ -502,6 +592,7 @@ public:
const sslFactory& getFactory() const;
const Socket& getSocket() const;
YasslError GetError() const;
bool GetMultiProtocol() const;
Crypto& useCrypto();
Security& useSecurity();
......@@ -509,6 +600,7 @@ public:
sslHashes& useHashes();
Socket& useSocket();
Log& useLog();
Buffers& useBuffers();
// sets
void set_pending(Cipher suite);
......
......@@ -38,6 +38,8 @@
namespace yaSSL {
#define YASSL_LIB
#ifdef YASSL_PURE_C
......@@ -76,7 +78,7 @@ namespace yaSSL {
::operator delete[](ptr, yaSSL::ys);
}
#define NEW_YS new (ys)
#define NEW_YS new (yaSSL::ys)
// to resolve compiler generated operator delete on base classes with
// virtual destructors (when on stack), make sure doesn't get called
......@@ -122,6 +124,39 @@ typedef opaque byte;
typedef unsigned int uint;
#ifdef USE_SYS_STL
// use system STL
#define STL_VECTOR_FILE <vector>
#define STL_LIST_FILE <list>
#define STL_ALGORITHM_FILE <algorithm>
#define STL_MEMORY_FILE <memory>
#define STL_PAIR_FILE <utility>
#define STL_NAMESPACE std
#else
// use mySTL
#define STL_VECTOR_FILE "vector.hpp"
#define STL_LIST_FILE "list.hpp"
#define STL_ALGORITHM_FILE "algorithm.hpp"
#define STL_MEMORY_FILE "memory.hpp"
#define STL_PAIR_FILE "pair.hpp"
#define STL_NAMESPACE mySTL
#endif
#ifdef min
#undef min
#endif
template <typename T>
T min(T a, T b)
{
return a < b ? a : b;
}
// all length constants in bytes
const int ID_LEN = 32; // session id length
const int SUITE_LEN = 2; // cipher suite length
......@@ -163,6 +198,7 @@ const int DES_BLOCK = 8; // DES is always fixed block size 8
const int DES_IV_SZ = DES_BLOCK; // Init Vector length for DES
const int RC4_KEY_SZ = 16; // RC4 Key length
const int AES_128_KEY_SZ = 16; // AES 128bit Key length
const int AES_192_KEY_SZ = 24; // AES 192bit Key length
const int AES_256_KEY_SZ = 32; // AES 256bit Key length
const int AES_BLOCK_SZ = 16; // AES 128bit block size, rfc 3268
const int AES_IV_SZ = AES_BLOCK_SZ; // AES Init Vector length
......
INCLUDES = -I../include -I../taocrypt/include -I../mySTL
INCLUDES = -I../include -I../taocrypt/include -I../taocrypt/mySTL
noinst_LTLIBRARIES = libyassl.la
libyassl_la_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \
......
......@@ -63,8 +63,8 @@ x509::x509(const x509& that) : length_(that.length_),
void x509::Swap(x509& that)
{
mySTL::swap(length_, that.length_);
mySTL::swap(buffer_, that.buffer_);
STL::swap(length_, that.length_);
STL::swap(buffer_, that.buffer_);
}
......@@ -105,11 +105,11 @@ CertManager::~CertManager()
{
ysDelete(peerX509_);
mySTL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ;
STL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ;
mySTL::for_each(peerList_.begin(), peerList_.end(), del_ptr_zero()) ;
STL::for_each(peerList_.begin(), peerList_.end(), del_ptr_zero()) ;
mySTL::for_each(list_.begin(), list_.end(), del_ptr_zero()) ;
STL::for_each(list_.begin(), list_.end(), del_ptr_zero()) ;
}
......@@ -242,7 +242,7 @@ uint CertManager::get_privateKeyLength() const
// Validate the peer's certificate list, from root to peer (last to first)
int CertManager::Validate()
{
CertList::iterator last = peerList_.rbegin(); // fix this
CertList::reverse_iterator last = peerList_.rbegin();
int count = peerList_.size();
while ( count > 1 ) {
......@@ -255,7 +255,7 @@ int CertManager::Validate()
const TaoCrypt::PublicKey& key = cert.GetPublicKey();
signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
cert.GetCommonName(), cert.GetHash()));
--last;
++last;
--count;
}
......@@ -310,6 +310,23 @@ int CertManager::SetPrivateKey(const x509& key)
}
// Store OpenSSL type peer's cert
void CertManager::setPeerX509(X509* x)
{
assert(peerX509_ == 0);
if (x == 0) return;
X509_NAME* issuer = x->GetIssuer();
X509_NAME* subject = x->GetSubject();
ASN1_STRING* before = x->GetBefore();
ASN1_STRING* after = x->GetAfter();
peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
subject->GetName(), subject->GetLength(), (const char*) before->data,
before->length, (const char*) after->data, after->length);
}
#if defined(USE_CML_LIB)
// Get the peer's certificate, extract and save public key
......
......@@ -908,7 +908,7 @@ void DiffieHellman::get_parms(byte* bp, byte* bg, byte* bpub) const
// convert PEM file to DER x509 type
x509* PemToDer(FILE* file, CertType type)
x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info)
{
using namespace TaoCrypt;
......@@ -935,6 +935,37 @@ x509* PemToDer(FILE* file, CertType type)
break;
}
// remove encrypted header if there
if (fgets(line, sizeof(line), file)) {
char encHeader[] = "Proc-Type";
if (strncmp(encHeader, line, strlen(encHeader)) == 0 &&
fgets(line,sizeof(line), file)) {
char* start = strstr(line, "DES");
char* finish = strstr(line, ",");
if (!start)
start = strstr(line, "AES");
if (!info) return 0;
if ( start && finish && (start < finish)) {
memcpy(info->name, start, finish - start);
info->name[finish - start] = 0;
memcpy(info->iv, finish + 1, sizeof(info->iv));
char* newline = strstr(line, "\r");
if (!newline) newline = strstr(line, "\n");
if (newline && (newline > finish)) {
info->ivSz = newline - (finish + 1);
info->set = true;
}
}
fgets(line,sizeof(line), file); // get blank line
begin = ftell(file);
}
}
while(fgets(line, sizeof(line), file))
if (strncmp(footer, line, strlen(footer)) == 0) {
foundEnd = true;
......@@ -956,7 +987,7 @@ x509* PemToDer(FILE* file, CertType type)
Base64Decoder b64Dec(der);
uint sz = der.size();
mySTL::auto_ptr<x509> x(NEW_YS x509(sz), ysDelete);
mySTL::auto_ptr<x509> x(NEW_YS x509(sz));
memcpy(x->use_buffer(), der.get_buffer(), sz);
return x.release();
......
......@@ -37,7 +37,6 @@
namespace yaSSL {
using mySTL::min;
// Build a client hello message from cipher suites and compression method
......@@ -363,7 +362,7 @@ void p_hash(output_buffer& result, const output_buffer& secret,
uint lastLen = result.get_capacity() % len;
opaque previous[SHA_LEN]; // max size
opaque current[SHA_LEN]; // max size
mySTL::auto_ptr<Digest> hmac(ysDelete);
mySTL::auto_ptr<Digest> hmac;
if (lastLen) times += 1;
......@@ -582,7 +581,7 @@ void hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz,
void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz,
ContentType content, bool verify)
{
mySTL::auto_ptr<Digest> hmac(ysDelete);
mySTL::auto_ptr<Digest> hmac;
opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
opaque length[LENGTH_SZ];
opaque inner[SIZEOF_ENUM + VERSION_SZ + LENGTH_SZ]; // type + version + len
......@@ -660,25 +659,25 @@ void build_certHashes(SSL& ssl, Hashes& hashes)
// do process input requests
mySTL::auto_ptr<input_buffer>
DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
// do process input requests, return 0 is done, 1 is call again to complete
int DoProcessReply(SSL& ssl)
{
// wait for input if blocking
if (!ssl.useSocket().wait()) {
ssl.SetError(receive_error);
buffered.reset(0);
return buffered;
return 0;
}
uint ready = ssl.getSocket().get_ready();
if (!ready) return buffered;
if (!ready) return 1;
// add buffered data if its there
uint buffSz = buffered.get() ? buffered.get()->get_size() : 0;
input_buffer* buffered = ssl.useBuffers().TakeRawInput();
uint buffSz = buffered ? buffered->get_size() : 0;
input_buffer buffer(buffSz + ready);
if (buffSz) {
buffer.assign(buffered.get()->get_buffer(), buffSz);
buffered.reset(0);
buffer.assign(buffered->get_buffer(), buffSz);
ysDelete(buffered);
buffered = 0;
}
// add new data
......@@ -692,10 +691,8 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
ssl.getStates().getServer() == clientNull)
if (buffer.peek() != handshake) {
ProcessOldClientHello(buffer, ssl);
if (ssl.GetError()) {
buffered.reset(0);
return buffered;
}
if (ssl.GetError())
return 0;
}
while(!buffer.eof()) {
......@@ -715,31 +712,28 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
// put header in front for next time processing
uint extra = needHdr ? 0 : RECORD_HEADER;
uint sz = buffer.get_remaining() + extra;
buffered.reset(NEW_YS input_buffer(sz, buffer.get_buffer() +
buffer.get_current() - extra, sz));
break;
ssl.useBuffers().SetRawInput(NEW_YS input_buffer(sz,
buffer.get_buffer() + buffer.get_current() - extra, sz));
return 1;
}
while (buffer.get_current() < hdr.length_ + RECORD_HEADER + offset) {
// each message in record, can be more than 1 if not encrypted
if (ssl.getSecurity().get_parms().pending_ == false) // cipher on
decrypt_message(ssl, buffer, hdr.length_);
mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_), ysDelete);
mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_));
if (!msg.get()) {
ssl.SetError(factory_error);
buffered.reset(0);
return buffered;
return 0;
}
buffer >> *msg;
msg->Process(buffer, ssl);
if (ssl.GetError()) {
buffered.reset(0);
return buffered;
}
if (ssl.GetError())
return 0;
}
offset += hdr.length_ + RECORD_HEADER;
}
return buffered;
return 0;
}
......@@ -747,16 +741,17 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
void processReply(SSL& ssl)
{
if (ssl.GetError()) return;
mySTL::auto_ptr<input_buffer> buffered(ysDelete);
for (;;) {
mySTL::auto_ptr<input_buffer> tmp(DoProcessReply(ssl, buffered));
if (tmp.get()) // had only part of a record's data, call again
buffered = tmp;
else
break;
if (ssl.GetError()) return;
if (DoProcessReply(ssl))
// didn't complete process
if (!ssl.getSocket().IsBlocking()) {
// keep trying now
while (!ssl.GetError())
if (DoProcessReply(ssl) == 0) break;
}
else
// user will have try again later
ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
}
......@@ -793,7 +788,7 @@ void sendClientKeyExchange(SSL& ssl, BufferOutput buffer)
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, ck);
buildOutput(*out.get(), rlHeader, hsHeader, ck);
hashHandShake(ssl, *out.get());
......@@ -814,7 +809,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer)
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, sk);
buildOutput(*out.get(), rlHeader, hsHeader, sk);
hashHandShake(ssl, *out.get());
......@@ -839,7 +834,7 @@ void sendChangeCipher(SSL& ssl, BufferOutput buffer)
ChangeCipherSpec ccs;
RecordLayerHeader rlHeader;
buildHeader(ssl, rlHeader, ccs);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildOutput(*out.get(), rlHeader, ccs);
if (buffer == buffered)
......@@ -856,7 +851,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
Finished fin;
buildFinished(ssl, fin, side == client_end ? client : server);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
cipherFinished(ssl, fin, *out.get()); // hashes handshake
if (ssl.getSecurity().get_resuming()) {
......@@ -955,7 +950,7 @@ void sendServerHello(SSL& ssl, BufferOutput buffer)
ServerHello sh(ssl.getSecurity().get_connection().version_);
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildServerHello(ssl, sh);
ssl.set_random(sh.get_random(), server_end);
......@@ -978,7 +973,7 @@ void sendServerHelloDone(SSL& ssl, BufferOutput buffer)
ServerHelloDone shd;
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, shd);
buildOutput(*out.get(), rlHeader, hsHeader, shd);
......@@ -999,7 +994,7 @@ void sendCertificate(SSL& ssl, BufferOutput buffer)
Certificate cert(ssl.getCrypto().get_certManager().get_cert());
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, cert);
buildOutput(*out.get(), rlHeader, hsHeader, cert);
......@@ -1021,7 +1016,7 @@ void sendCertificateRequest(SSL& ssl, BufferOutput buffer)
request.Build();
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, request);
buildOutput(*out.get(), rlHeader, hsHeader, request);
......@@ -1043,7 +1038,7 @@ void sendCertificateVerify(SSL& ssl, BufferOutput buffer)
verify.Build(ssl);
RecordLayerHeader rlHeader;
HandShakeHeader hsHeader;
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer, ysDelete);
mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer);
buildHeaders(ssl, hsHeader, rlHeader, verify);
buildOutput(*out.get(), rlHeader, hsHeader, verify);
......
......@@ -41,9 +41,10 @@
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <string.h>
#include <fcntl.h>
#endif // _WIN32
#if defined(__sun) || defined(__SCO_VERSION__)
#if defined(__sun) || defined(__SCO_VERSION__) || defined(__NETWARE__)
#include <sys/filio.h>
#endif
......@@ -62,7 +63,7 @@ namespace yaSSL {
Socket::Socket(socket_t s)
: socket_(s), wouldBlock_(false)
: socket_(s), wouldBlock_(false), blocking_(false)
{}
......@@ -148,6 +149,7 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags)
if (get_lastError() == SOCKET_EWOULDBLOCK ||
get_lastError() == SOCKET_EAGAIN) {
wouldBlock_ = true;
blocking_ = true; // socket can block, only way to tell for win32
return 0;
}
}
......@@ -189,6 +191,12 @@ bool Socket::WouldBlock() const
}
bool Socket::IsBlocking() const
{
return blocking_;
}
void Socket::set_lastError(int errorCode)
{
#ifdef _WIN32
......
......@@ -42,6 +42,9 @@
#include "yassl_int.hpp"
#include "md5.hpp" // for TaoCrypt MD5 size assert
#include "md4.hpp" // for TaoCrypt MD4 size assert
#include "file.hpp" // for TaoCrypt Source
#include "coding.hpp" // HexDecoder
#include "helpers.hpp" // for placement new hack
#include <stdio.h>
#ifdef _WIN32
......@@ -55,7 +58,6 @@
namespace yaSSL {
using mySTL::min;
int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
......@@ -93,11 +95,55 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
}
}
else {
x = PemToDer(input, type);
EncryptedInfo info;
x = PemToDer(input, type, &info);
if (!x) {
fclose(input);
return SSL_BAD_FILE;
}
if (info.set) {
// decrypt
char password[80];
pem_password_cb cb = ctx->GetPasswordCb();
if (!cb) {
fclose(input);
return SSL_BAD_FILE;
}
int passwordSz = cb(password, sizeof(password), 0,
ctx->GetUserData());
byte key[AES_256_KEY_SZ]; // max sizes
byte iv[AES_IV_SZ];
// use file's salt for key derivation, but not real iv
TaoCrypt::Source source(info.iv, info.ivSz);
TaoCrypt::HexDecoder dec(source);
memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
source.size()));
EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
passwordSz, 1, key, iv);
STL::auto_ptr<BulkCipher> cipher;
if (strncmp(info.name, "DES-CBC", 7) == 0)
cipher.reset(NEW_YS DES);
else if (strncmp(info.name, "DES-EDE3-CBC", 13) == 0)
cipher.reset(NEW_YS DES_EDE);
else if (strncmp(info.name, "AES-128-CBC", 13) == 0)
cipher.reset(NEW_YS AES(AES_128_KEY_SZ));
else if (strncmp(info.name, "AES-192-CBC", 13) == 0)
cipher.reset(NEW_YS AES(AES_192_KEY_SZ));
else if (strncmp(info.name, "AES-256-CBC", 13) == 0)
cipher.reset(NEW_YS AES(AES_256_KEY_SZ));
else {
fclose(input);
return SSL_BAD_FILE;
}
cipher->set_decryptKey(key, info.iv);
STL::auto_ptr<x509> newx(NEW_YS x509(x->get_length()));
cipher->decrypt(newx->use_buffer(), x->get_buffer(),
x->get_length());
ysDelete(x);
x = newx.release();
}
}
}
fclose(input);
......@@ -140,8 +186,17 @@ SSL_METHOD* TLSv1_client_method()
SSL_METHOD* SSLv23_server_method()
{
// compatibility only, no version 2 support
return SSLv3_server_method();
// compatibility only, no version 2 support, but does SSL 3 and TLS 1
return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,1), true);
}
SSL_METHOD* SSLv23_client_method()
{
// compatibility only, no version 2 support, but does SSL 3 and TLS 1
// though it sends TLS1 hello not SSLv2 so SSLv3 only servers will decline
// TODO: maybe add support to send SSLv2 hello ???
return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,1), true);
}
......@@ -178,14 +233,29 @@ int SSL_set_fd(SSL* ssl, int fd)
int SSL_connect(SSL* ssl)
{
if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
ssl->SetError(no_error);
ClientState neededState;
switch (ssl->getStates().GetConnect()) {
case CONNECT_BEGIN :
sendClientHello(*ssl);
ClientState neededState = ssl->getSecurity().get_resuming() ?
if (!ssl->GetError())
ssl->useStates().UseConnect() = CLIENT_HELLO_SENT;
case CLIENT_HELLO_SENT :
neededState = ssl->getSecurity().get_resuming() ?
serverFinishedComplete : serverHelloDoneComplete;
while (ssl->getStates().getClient() < neededState) {
if (ssl->GetError()) break;
processReply(*ssl);
}
if (!ssl->GetError())
ssl->useStates().UseConnect() = FIRST_REPLY_DONE;
case FIRST_REPLY_DONE :
if(ssl->getCrypto().get_certManager().sendVerify())
sendCertificate(*ssl);
......@@ -198,18 +268,32 @@ int SSL_connect(SSL* ssl)
sendChangeCipher(*ssl);
sendFinished(*ssl, client_end);
ssl->flushBuffer();
if (!ssl->GetError())
ssl->useStates().UseConnect() = FINISHED_DONE;
case FINISHED_DONE :
if (!ssl->getSecurity().get_resuming())
while (ssl->getStates().getClient() < serverFinishedComplete) {
if (ssl->GetError()) break;
processReply(*ssl);
}
if (!ssl->GetError())
ssl->useStates().UseConnect() = SECOND_REPLY_DONE;
case SECOND_REPLY_DONE :
ssl->verifyState(serverFinishedComplete);
ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
if (ssl->GetError())
if (ssl->GetError()) {
GetErrors().Add(ssl->GetError());
return SSL_FATAL_ERROR;
}
return SSL_SUCCESS;
default :
return SSL_FATAL_ERROR; // unkown state
}
}
......@@ -228,7 +312,17 @@ int SSL_read(SSL* ssl, void* buffer, int sz)
int SSL_accept(SSL* ssl)
{
if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
ssl->SetError(no_error);
switch (ssl->getStates().GetAccept()) {
case ACCEPT_BEGIN :
processReply(*ssl);
if (!ssl->GetError())
ssl->useStates().UseAccept() = ACCEPT_FIRST_REPLY_DONE;
case ACCEPT_FIRST_REPLY_DONE :
sendServerHello(*ssl);
if (!ssl->getSecurity().get_resuming()) {
......@@ -242,27 +336,51 @@ int SSL_accept(SSL* ssl)
sendServerHelloDone(*ssl);
ssl->flushBuffer();
}
if (!ssl->GetError())
ssl->useStates().UseAccept() = SERVER_HELLO_DONE;
case SERVER_HELLO_DONE :
if (!ssl->getSecurity().get_resuming()) {
while (ssl->getStates().getServer() < clientFinishedComplete) {
if (ssl->GetError()) break;
processReply(*ssl);
}
}
if (!ssl->GetError())
ssl->useStates().UseAccept() = ACCEPT_SECOND_REPLY_DONE;
case ACCEPT_SECOND_REPLY_DONE :
sendChangeCipher(*ssl);
sendFinished(*ssl, server_end);
ssl->flushBuffer();
if (!ssl->GetError())
ssl->useStates().UseAccept() = ACCEPT_FINISHED_DONE;
case ACCEPT_FINISHED_DONE :
if (ssl->getSecurity().get_resuming()) {
while (ssl->getStates().getServer() < clientFinishedComplete) {
if (ssl->GetError()) break;
processReply(*ssl);
}
}
if (!ssl->GetError())
ssl->useStates().UseAccept() = ACCEPT_THIRD_REPLY_DONE;
case ACCEPT_THIRD_REPLY_DONE :
ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
if (ssl->GetError())
if (ssl->GetError()) {
GetErrors().Add(ssl->GetError());
return SSL_FATAL_ERROR;
}
return SSL_SUCCESS;
default:
return SSL_FATAL_ERROR; // unknown state
}
}
......@@ -278,6 +396,8 @@ int SSL_do_handshake(SSL* ssl)
int SSL_clear(SSL* ssl)
{
ssl->useSocket().closeSocket();
GetErrors().Remove();
return SSL_SUCCESS;
}
......@@ -289,6 +409,8 @@ int SSL_shutdown(SSL* ssl)
ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true);
ssl->useSocket().closeSocket();
GetErrors().Remove();
return SSL_SUCCESS;
}
......@@ -762,9 +884,8 @@ void DH_free(DH* dh)
// be created
BIGNUM* BN_bin2bn(const unsigned char* num, int sz, BIGNUM* retVal)
{
using mySTL::auto_ptr;
bool created = false;
auto_ptr<BIGNUM> bn(ysDelete);
mySTL::auto_ptr<BIGNUM> bn;
if (!retVal) {
created = true;
......@@ -825,7 +946,7 @@ const EVP_MD* EVP_md5(void)
const EVP_CIPHER* EVP_des_ede3_cbc(void)
{
static const char* type = "DES_EDE3_CBC";
static const char* type = "DES-EDE3-CBC";
return type;
}
......@@ -836,16 +957,37 @@ int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt,
// only support MD5 for now
if (strncmp(md, "MD5", 3)) return 0;
// only support DES_EDE3_CBC for now
if (strncmp(type, "DES_EDE3_CBC", 12)) return 0;
int keyLen = 0;
int ivLen = 0;
// only support CBC DES and AES for now
if (strncmp(type, "DES-CBC", 7) == 0) {
keyLen = DES_KEY_SZ;
ivLen = DES_IV_SZ;
}
else if (strncmp(type, "DES-EDE3-CBC", 12) == 0) {
keyLen = DES_EDE_KEY_SZ;
ivLen = DES_IV_SZ;
}
else if (strncmp(type, "AES-128-CBC", 11) == 0) {
keyLen = AES_128_KEY_SZ;
ivLen = AES_IV_SZ;
}
else if (strncmp(type, "AES-192-CBC", 11) == 0) {
keyLen = AES_192_KEY_SZ;
ivLen = AES_IV_SZ;
}
else if (strncmp(type, "AES-256-CBC", 11) == 0) {
keyLen = AES_256_KEY_SZ;
ivLen = AES_IV_SZ;
}
else
return 0;
yaSSL::MD5 myMD;
uint digestSz = myMD.get_digestSize();
byte digest[SHA_LEN]; // max size
yaSSL::DES_EDE cipher;
int keyLen = cipher.get_keySize();
int ivLen = cipher.get_ivSize();
int keyLeft = keyLen;
int ivLeft = ivLen;
int keyOutput = 0;
......@@ -878,7 +1020,7 @@ int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt,
if (ivLeft && digestLeft) {
int store = min(ivLeft, digestLeft);
memcpy(&iv[ivLen - ivLeft], digest, store);
memcpy(&iv[ivLen - ivLeft], &digest[digestSz - digestLeft], store);
keyOutput += store;
ivLeft -= store;
......@@ -954,10 +1096,9 @@ void DES_ecb_encrypt(DES_cblock* input, DES_cblock* output,
}
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX*, void* userdata)
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX* ctx, void* userdata)
{
// yaSSL doesn't support yet, unencrypt your PEM file with userdata
// before handing off to yaSSL
ctx->SetUserData(userdata);
}
......@@ -1034,12 +1175,6 @@ ASN1_TIME* X509_get_notAfter(X509* x)
}
SSL_METHOD* SSLv23_client_method(void) /* doesn't actually roll back */
{
return SSLv3_client_method();
}
SSL_METHOD* SSLv2_client_method(void) /* will never work, no v 2 */
{
return 0;
......@@ -1363,9 +1498,9 @@ int SSL_pending(SSL* ssl)
}
void SSL_CTX_set_default_passwd_cb(SSL_CTX*, pem_password_cb)
void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb)
{
// TDOD:
ctx->SetPasswordCb(cb);
}
......@@ -1428,7 +1563,7 @@ int SSL_pending(SSL* ssl)
void ERR_remove_state(unsigned long)
{
// TODO:
GetErrors().Remove();
}
......@@ -1437,16 +1572,30 @@ int SSL_pending(SSL* ssl)
return l & 0xfff;
}
unsigned long err_helper(bool peek = false)
{
int ysError = GetErrors().Lookup(peek);
// translate cert error for libcurl, it uses OpenSSL hex code
switch (ysError) {
case TaoCrypt::SIG_OTHER_E:
return CERTFICATE_ERROR;
break;
default :
return 0;
}
}
unsigned long ERR_peek_error()
{
return 0; // TODO:
return err_helper(true);
}
unsigned long ERR_get_error()
{
return ERR_peek_error();
return err_helper();
}
......
......@@ -65,6 +65,19 @@ template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::output_buffer*>::iterat
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::x509*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::x509*>::iterator, mySTL::list<yaSSL::x509*>::iterator, yaSSL::del_ptr_zero);
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::Digest*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::Digest*>::iterator, mySTL::list<yaSSL::Digest*>::iterator, yaSSL::del_ptr_zero);
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::BulkCipher*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::BulkCipher*>::iterator, mySTL::list<yaSSL::BulkCipher*>::iterator, yaSSL::del_ptr_zero);
template bool list<yaSSL::ThreadError>::erase(list<yaSSL::ThreadError>::iterator);
template void list<yaSSL::ThreadError>::push_back(yaSSL::ThreadError);
template void list<yaSSL::ThreadError>::pop_front();
template void list<yaSSL::ThreadError>::pop_back();
template list<yaSSL::ThreadError>::~list();
template pair<int, yaSSL::Message* (*)()>* GetArrayMemory<pair<int, yaSSL::Message* (*)()> >(size_t);
template void FreeArrayMemory<pair<int, yaSSL::Message* (*)()> >(pair<int, yaSSL::Message* (*)()>*);
template pair<int, yaSSL::HandShakeBase* (*)()>* GetArrayMemory<pair<int, yaSSL::HandShakeBase* (*)()> >(size_t);
template void FreeArrayMemory<pair<int, yaSSL::HandShakeBase* (*)()> >(pair<int, yaSSL::HandShakeBase* (*)()>*);
template pair<int, yaSSL::ServerKeyBase* (*)()>* GetArrayMemory<pair<int, yaSSL::ServerKeyBase* (*)()> >(size_t);
template void FreeArrayMemory<pair<int, yaSSL::ServerKeyBase* (*)()> >(pair<int, yaSSL::ServerKeyBase* (*)()>*);
template pair<int, yaSSL::ClientKeyBase* (*)()>* GetArrayMemory<pair<int, yaSSL::ClientKeyBase* (*)()> >(size_t);
template void FreeArrayMemory<pair<int, yaSSL::ClientKeyBase* (*)()> >(pair<int, yaSSL::ClientKeyBase* (*)()>*);
}
namespace yaSSL {
......@@ -90,8 +103,12 @@ template void ysDelete<X509>(X509*);
template void ysDelete<Message>(Message*);
template void ysDelete<sslFactory>(sslFactory*);
template void ysDelete<Sessions>(Sessions*);
template void ysDelete<Errors>(Errors*);
template void ysArrayDelete<unsigned char>(unsigned char*);
template void ysArrayDelete<char>(char*);
template int min<int>(int, int);
template unsigned int min<unsigned int>(unsigned int, unsigned int);
}
#endif // HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
......
......@@ -36,21 +36,9 @@
#include "openssl/ssl.h" // get rid of this
// yaSSL overloads hide these
void* operator new[](size_t sz)
{
return ::operator new(sz);
}
void operator delete[](void* ptr)
{
::operator delete(ptr);
}
namespace yaSSL {
using mySTL::min;
struct Base {
......
......@@ -125,13 +125,21 @@ void SetErrorString(YasslError error, char* buffer)
strncpy(buffer, "unable to proccess cerificate", max);
break;
case privateKey_error :
strncpy(buffer, "unable to proccess private key, bad format", max);
break;
case badVersion_error :
strncpy(buffer, "protocl version mismatch", max);
break;
// openssl errors
case SSL_ERROR_WANT_READ :
strncpy(buffer, "the read operation would block", max);
break;
// TaoCrypt errors
case NO_ERROR :
case NO_ERROR_E :
strncpy(buffer, "not in error state", max);
break;
......@@ -235,6 +243,10 @@ void SetErrorString(YasslError error, char* buffer)
strncpy(buffer, "ASN: bad other signature confirmation", max);
break;
case CERTFICATE_ERROR :
strncpy(buffer, "Unable to verify certificate", max);
break;
default :
strncpy(buffer, "unknown error number", max);
}
......
......@@ -139,7 +139,7 @@ void DH_Server::build(SSL& ssl)
parms_.alloc_pub(pubSz));
short sigSz = 0;
mySTL::auto_ptr<Auth> auth(ysDelete);
mySTL::auto_ptr<Auth> auth;
const CertManager& cert = ssl.getCrypto().get_certManager();
if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
......@@ -151,9 +151,11 @@ void DH_Server::build(SSL& ssl)
sigSz += DSS_ENCODED_EXTRA;
}
sigSz += auth->get_signatureLength();
if (!sigSz) {
ssl.SetError(privateKey_error);
return;
}
length_ = 8; // pLen + gLen + YsLen + SigLen
length_ += pSz + gSz + pubSz + sigSz;
......@@ -612,7 +614,7 @@ void HandShakeHeader::Process(input_buffer& input, SSL& ssl)
{
ssl.verifyState(*this);
const HandShakeFactory& hsf = ssl.getFactory().getHandShake();
mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_), ysDelete);
mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_));
if (!hs.get()) {
ssl.SetError(factory_error);
return;
......@@ -1214,6 +1216,20 @@ output_buffer& operator<<(output_buffer& output, const ServerHello& hello)
// Server Hello processing handler
void ServerHello::Process(input_buffer&, SSL& ssl)
{
if (ssl.GetMultiProtocol()) { // SSLv23 support
if (ssl.isTLS() && server_version_.minor_ < 1)
// downgrade to SSLv3
ssl.useSecurity().use_connection().TurnOffTLS();
}
else if (ssl.isTLS() && server_version_.minor_ < 1) {
ssl.SetError(badVersion_error);
return;
}
else if (!ssl.isTLS() && (server_version_.major_ == 3 &&
server_version_.minor_ >= 1)) {
ssl.SetError(badVersion_error);
return;
}
ssl.set_pending(cipher_suite_[1]);
ssl.set_random(random_, server_end);
if (id_len_)
......@@ -1384,11 +1400,23 @@ output_buffer& operator<<(output_buffer& output, const ClientHello& hello)
// Client Hello processing handler
void ClientHello::Process(input_buffer&, SSL& ssl)
{
if (ssl.isTLS() && client_version_.minor_ == 0) {
if (ssl.GetMultiProtocol()) { // SSLv23 support
if (ssl.isTLS() && client_version_.minor_ < 1) {
// downgrade to SSLv3
ssl.useSecurity().use_connection().TurnOffTLS();
ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
ssl.useSecurity().use_parms().SetSuites(pv); // reset w/ SSL suites
}
}
else if (ssl.isTLS() && client_version_.minor_ < 1) {
ssl.SetError(badVersion_error);
return;
}
else if (!ssl.isTLS() && (client_version_.major_ == 3 &&
client_version_.minor_ >= 1)) {
ssl.SetError(badVersion_error);
return;
}
ssl.set_random(random_, client_end);
while (id_len_) { // trying to resume
......@@ -1541,7 +1569,7 @@ CertificateRequest::CertificateRequest()
CertificateRequest::~CertificateRequest()
{
mySTL::for_each(certificate_authorities_.begin(),
STL::for_each(certificate_authorities_.begin(),
certificate_authorities_.end(),
del_ptr_zero()) ;
}
......@@ -1634,9 +1662,9 @@ output_buffer& operator<<(output_buffer& output,
request.typeTotal_ - REQUEST_HEADER, tmp);
output.write(tmp, sizeof(tmp));
mySTL::list<DistinguishedName>::const_iterator first =
STL::list<DistinguishedName>::const_iterator first =
request.certificate_authorities_.begin();
mySTL::list<DistinguishedName>::const_iterator last =
STL::list<DistinguishedName>::const_iterator last =
request.certificate_authorities_.end();
while (first != last) {
uint16 sz;
......@@ -1684,7 +1712,7 @@ void CertificateVerify::Build(SSL& ssl)
uint16 sz = 0;
byte len[VERIFY_HEADER];
mySTL::auto_ptr<byte> sig(ysArrayDelete);
mySTL::auto_array<byte> sig;
// sign
const CertManager& cert = ssl.getCrypto().get_certManager();
......
......@@ -33,6 +33,10 @@
#include "handshake.hpp"
#include "timer.hpp"
#ifdef _POSIX_THREADS
#include "pthread.h"
#endif
#ifdef YASSL_PURE_C
......@@ -74,7 +78,6 @@
namespace yaSSL {
using mySTL::min;
......@@ -155,6 +158,7 @@ void c32toa(uint32 u32, opaque* c)
States::States() : recordLayer_(recordReady), handshakeLayer_(preHandshake),
clientState_(serverNull), serverState_(clientNull),
connectState_(CONNECT_BEGIN), acceptState_(ACCEPT_BEGIN),
what_(no_error) {}
const RecordLayerState& States::getRecord() const
......@@ -181,6 +185,18 @@ const ServerState& States::getServer() const
}
const ConnectState& States::GetConnect() const
{
return connectState_;
}
const AcceptState& States::GetAccept() const
{
return acceptState_;
}
const char* States::getString() const
{
return errorString_;
......@@ -217,6 +233,18 @@ ServerState& States::useServer()
}
ConnectState& States::UseConnect()
{
return connectState_;
}
AcceptState& States::UseAccept()
{
return acceptState_;
}
char* States::useString()
{
return errorString_;
......@@ -722,6 +750,12 @@ void SSL::SetError(YasslError ye)
}
Buffers& SSL::useBuffers()
{
return buffers_;
}
// locals
namespace {
......@@ -959,7 +993,7 @@ using namespace yassl_int_cpp_local1;
uint SSL::bufferedData()
{
return mySTL::for_each(buffers_.getData().begin(),buffers_.getData().end(),
return STL::for_each(buffers_.getData().begin(),buffers_.getData().end(),
SumData()).total_;
}
......@@ -1002,7 +1036,7 @@ void SSL::PeekData(Data& data)
data.set_length(0); // output, actual data filled
dataSz = min(dataSz, bufferedData());
Buffers::inputList::iterator front = buffers_.getData().begin();
Buffers::inputList::iterator front = buffers_.useData().begin();
while (elements) {
uint frontSz = (*front)->get_remaining();
......@@ -1027,7 +1061,7 @@ void SSL::flushBuffer()
{
if (GetError()) return;
uint sz = mySTL::for_each(buffers_.getHandShake().begin(),
uint sz = STL::for_each(buffers_.getHandShake().begin(),
buffers_.getHandShake().end(),
SumBuffer()).total_;
output_buffer out(sz);
......@@ -1213,8 +1247,10 @@ void SSL::matchSuite(const opaque* peer, uint length)
void SSL::set_session(SSL_SESSION* s)
{
if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume()))
if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume())) {
secure_.set_resuming(true);
crypto_.use_certManager().setPeerX509(s->GetPeerX509());
}
}
......@@ -1260,6 +1296,12 @@ YasslError SSL::GetError() const
}
bool SSL::GetMultiProtocol() const
{
return secure_.GetContext()->getMethod()->multipleProtocol();
}
Crypto& SSL::useCrypto()
{
return crypto_;
......@@ -1314,9 +1356,25 @@ void SSL::addBuffer(output_buffer* b)
}
void SSL_SESSION::CopyX509(X509* x)
{
assert(peerX509_ == 0);
if (x == 0) return;
X509_NAME* issuer = x->GetIssuer();
X509_NAME* subject = x->GetSubject();
ASN1_STRING* before = x->GetBefore();
ASN1_STRING* after = x->GetAfter();
peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
subject->GetName(), subject->GetLength(), (const char*) before->data,
before->length, (const char*) after->data, after->length);
}
// store connection parameters
SSL_SESSION::SSL_SESSION(const SSL& ssl, RandomPool& ran)
: timeout_(DEFAULT_TIMEOUT), random_(ran)
: timeout_(DEFAULT_TIMEOUT), random_(ran), peerX509_(0)
{
const Connection& conn = ssl.getSecurity().get_connection();
......@@ -1325,12 +1383,14 @@ SSL_SESSION::SSL_SESSION(const SSL& ssl, RandomPool& ran)
memcpy(suite_, ssl.getSecurity().get_parms().suite_, SUITE_LEN);
bornOn_ = lowResTimer();
CopyX509(ssl.getCrypto().get_certManager().get_peerX509());
}
// for resumption copy in ssl::parameters
SSL_SESSION::SSL_SESSION(RandomPool& ran)
: bornOn_(0), timeout_(0), random_(ran)
: bornOn_(0), timeout_(0), random_(ran), peerX509_(0)
{
memset(sessionID_, 0, ID_LEN);
memset(master_secret_, 0, SECRET_LEN);
......@@ -1347,6 +1407,12 @@ SSL_SESSION& SSL_SESSION::operator=(const SSL_SESSION& that)
bornOn_ = that.bornOn_;
timeout_ = that.timeout_;
if (peerX509_) {
ysDelete(peerX509_);
peerX509_ = 0;
}
CopyX509(that.peerX509_);
return *this;
}
......@@ -1369,6 +1435,12 @@ const Cipher* SSL_SESSION::GetSuite() const
}
X509* SSL_SESSION::GetPeerX509() const
{
return peerX509_;
}
uint SSL_SESSION::GetBornOn() const
{
return bornOn_;
......@@ -1395,6 +1467,8 @@ SSL_SESSION::~SSL_SESSION()
{
volatile opaque* p = master_secret_;
clean(p, SECRET_LEN, random_);
ysDelete(peerX509_);
}
......@@ -1418,6 +1492,15 @@ sslFactory& GetSSL_Factory()
}
static Errors* errorsInstance = 0;
Errors& GetErrors()
{
if (!errorsInstance)
errorsInstance = NEW_YS Errors;
return *errorsInstance;
}
typedef Mutex::Lock Lock;
......@@ -1433,14 +1516,15 @@ void Sessions::add(const SSL& ssl)
Sessions::~Sessions()
{
mySTL::for_each(list_.begin(), list_.end(), del_ptr_zero());
STL::for_each(list_.begin(), list_.end(), del_ptr_zero());
}
// locals
namespace yassl_int_cpp_local2 { // for explicit templates
typedef mySTL::list<SSL_SESSION*>::iterator iterator;
typedef STL::list<SSL_SESSION*>::iterator sess_iterator;
typedef STL::list<ThreadError>::iterator thr_iterator;
struct sess_match {
const opaque* id_;
......@@ -1455,6 +1539,28 @@ struct sess_match {
};
THREAD_ID_T GetSelf()
{
#ifndef _POSIX_THREADS
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
struct thr_match {
THREAD_ID_T id_;
explicit thr_match() : id_(GetSelf()) {}
bool operator()(ThreadError thr)
{
if (thr.threadID_ == id_)
return true;
return false;
}
};
} // local namespace
using namespace yassl_int_cpp_local2;
......@@ -1463,8 +1569,8 @@ using namespace yassl_int_cpp_local2;
SSL_SESSION* Sessions::lookup(const opaque* id, SSL_SESSION* copy)
{
Lock guard(mutex_);
iterator find = mySTL::find_if(list_.begin(), list_.end(), sess_match(id));
sess_iterator find = STL::find_if(list_.begin(), list_.end(),
sess_match(id));
if (find != list_.end()) {
uint current = lowResTimer();
if ( ((*find)->GetBornOn() + (*find)->GetTimeOut()) < current) {
......@@ -1484,8 +1590,8 @@ SSL_SESSION* Sessions::lookup(const opaque* id, SSL_SESSION* copy)
void Sessions::remove(const opaque* id)
{
Lock guard(mutex_);
iterator find = mySTL::find_if(list_.begin(), list_.end(), sess_match(id));
sess_iterator find = STL::find_if(list_.begin(), list_.end(),
sess_match(id));
if (find != list_.end()) {
del_ptr_zero()(*find);
list_.erase(find);
......@@ -1493,9 +1599,51 @@ void Sessions::remove(const opaque* id)
}
SSL_METHOD::SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv)
// remove a self thread error
void Errors::Remove()
{
Lock guard(mutex_);
thr_iterator find = STL::find_if(list_.begin(), list_.end(),
thr_match());
if (find != list_.end())
list_.erase(find);
}
// lookup self error code
int Errors::Lookup(bool peek)
{
Lock guard(mutex_);
thr_iterator find = STL::find_if(list_.begin(), list_.end(),
thr_match());
if (find != list_.end()) {
int ret = find->errorID_;
if (!peek)
list_.erase(find);
return ret;
}
else
return 0;
}
// add a new error code for self
void Errors::Add(int error)
{
ThreadError add;
add.errorID_ = error;
add.threadID_ = GetSelf();
Remove(); // may have old error
Lock guard(mutex_);
list_.push_back(add);
}
SSL_METHOD::SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv, bool multiProto)
: version_(pv), side_(ce), verifyPeer_(false), verifyNone_(false),
failNoCert_(false)
failNoCert_(false), multipleProtocol_(multiProto)
{}
......@@ -1547,8 +1695,15 @@ bool SSL_METHOD::failNoCert() const
}
bool SSL_METHOD::multipleProtocol() const
{
return multipleProtocol_;
}
SSL_CTX::SSL_CTX(SSL_METHOD* meth)
: method_(meth), certificate_(0), privateKey_(0)
: method_(meth), certificate_(0), privateKey_(0), passwordCb_(0),
userData_(0)
{}
......@@ -1558,7 +1713,7 @@ SSL_CTX::~SSL_CTX()
ysDelete(certificate_);
ysDelete(privateKey_);
mySTL::for_each(caList_.begin(), caList_.end(), del_ptr_zero());
STL::for_each(caList_.begin(), caList_.end(), del_ptr_zero());
}
......@@ -1611,6 +1766,30 @@ const Stats& SSL_CTX::GetStats() const
}
pem_password_cb SSL_CTX::GetPasswordCb() const
{
return passwordCb_;
}
void SSL_CTX::SetPasswordCb(pem_password_cb cb)
{
passwordCb_ = cb;
}
void* SSL_CTX::GetUserData() const
{
return userData_;
}
void SSL_CTX::SetUserData(void* data)
{
userData_ = data;
}
void SSL_CTX::setVerifyPeer()
{
method_->setVerifyPeer();
......@@ -1914,12 +2093,33 @@ Hashes& sslHashes::use_certVerify()
}
Buffers::Buffers() : rawInput_(0)
{}
Buffers::~Buffers()
{
mySTL::for_each(handShakeList_.begin(), handShakeList_.end(),
STL::for_each(handShakeList_.begin(), handShakeList_.end(),
del_ptr_zero()) ;
mySTL::for_each(dataList_.begin(), dataList_.end(),
STL::for_each(dataList_.begin(), dataList_.end(),
del_ptr_zero()) ;
ysDelete(rawInput_);
}
void Buffers::SetRawInput(input_buffer* ib)
{
assert(rawInput_ == 0);
rawInput_ = ib;
}
input_buffer* Buffers::TakeRawInput()
{
input_buffer* ret = rawInput_;
rawInput_ = 0;
return ret;
}
......@@ -2026,12 +2226,18 @@ X509_NAME::~X509_NAME()
}
char* X509_NAME::GetName()
const char* X509_NAME::GetName() const
{
return name_;
}
size_t X509_NAME::GetLength() const
{
return sz_;
}
X509::X509(const char* i, size_t iSz, const char* s, size_t sSz,
const char* b, int bSz, const char* a, int aSz)
: issuer_(i, iSz), subject_(s, sSz),
......@@ -2114,10 +2320,12 @@ extern "C" void yaSSL_CleanUp()
TaoCrypt::CleanUp();
yaSSL::ysDelete(yaSSL::sslFactoryInstance);
yaSSL::ysDelete(yaSSL::sessionsInstance);
yaSSL::ysDelete(yaSSL::errorsInstance);
// In case user calls more than once, prevent seg fault
yaSSL::sslFactoryInstance = 0;
yaSSL::sessionsInstance = 0;
yaSSL::errorsInstance = 0;
}
......@@ -2126,6 +2334,7 @@ namespace mySTL {
template yaSSL::yassl_int_cpp_local1::SumData for_each<mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData>(mySTL::list<yaSSL::input_buffer*>::iterator, mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData);
template yaSSL::yassl_int_cpp_local1::SumBuffer for_each<mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer>(mySTL::list<yaSSL::output_buffer*>::iterator, mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer);
template mySTL::list<yaSSL::SSL_SESSION*>::iterator find_if<mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::yassl_int_cpp_local2::sess_match>(mySTL::list<yaSSL::SSL_SESSION*>::iterator, mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::yassl_int_cpp_local2::sess_match);
template mySTL::list<yaSSL::ThreadError>::iterator find_if<mySTL::list<yaSSL::ThreadError>::iterator, yaSSL::yassl_int_cpp_local2::thr_match>(mySTL::list<yaSSL::ThreadError>::iterator, mySTL::list<yaSSL::ThreadError>::iterator, yaSSL::yassl_int_cpp_local2::thr_match);
}
#endif
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
SUBDIRS = src test benchmark
EXTRA_DIST = taocrypt.dsw taocrypt.dsp CMakeLists.txt
EXTRA_DIST = taocrypt.dsw taocrypt.dsp CMakeLists.txt $(wildcard mySTL/*.hpp)
TaoCrypt release 0.9.0 09/18/2006
This is the first release of TaoCrypt, it was previously only included with
yaSSL. TaoCrypt is highly portable and fast, its features include:
One way hash functions: SHA-1, MD2, MD4, MD5, RIPEMD-160
Message authentication codes: HMAC
Block Ciphers: DES, Triple-DES, AES, Blowfish, Twofish
Stream Ciphers: ARC4
Public Key Crypto: RSA, DSA, Diffie-Hellman
Password based key derivation: PBKDF2 from PKCS #5
Pseudo Random Number Generators
Lare Integer Support
Base 16/64 encoding/decoding
DER encoding/decoding
X.509 processing
SSE2 and ia32 asm for the right processors and compilers
To build on Unix
./configure
make
To test the build, from the ./test directory run ./test
On Windows
Open the taocrypt project workspace
Choose (Re)Build All
To test the build, run the test executable
Please send any questions or comments to todd@yassl.com.
INCLUDES = -I../include -I../../mySTL
INCLUDES = -I../include -I../mySTL
bin_PROGRAMS = benchmark
benchmark_SOURCES = benchmark.cpp
benchmark_LDFLAGS = -L../src
......
......@@ -33,10 +33,12 @@
#include "misc.hpp"
#include "block.hpp"
#include "list.hpp"
#include "error.hpp"
#include STL_LIST_FILE
namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
......@@ -232,7 +234,7 @@ private:
};
typedef mySTL::list<Signer*> SignerList;
typedef STL::list<Signer*> SignerList;
enum SigType { SHAwDSA = 517, MD2wRSA = 646, MD5wRSA = 648, SHAwRSA =649};
......
......@@ -31,12 +31,14 @@
#ifndef TAO_CRYPT_BLOCK_HPP
#define TAO_CRYPT_BLOCK_HPP
#include "algorithm.hpp" // mySTL::swap
#include "misc.hpp"
#include <string.h> // memcpy
#include <stddef.h> // ptrdiff_t
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
......@@ -80,7 +82,7 @@ typename A::pointer StdReallocate(A& a, T* p, typename A::size_type oldSize,
typename A::pointer newPointer = b.allocate(newSize, 0);
memcpy(newPointer, p, sizeof(T) * min(oldSize, newSize));
a.deallocate(p, oldSize);
mySTL::swap(a, b);
STL::swap(a, b);
return newPointer;
}
else {
......@@ -183,9 +185,9 @@ public:
}
void Swap(Block& other) {
mySTL::swap(sz_, other.sz_);
mySTL::swap(buffer_, other.buffer_);
mySTL::swap(allocator_, other.allocator_);
STL::swap(sz_, other.sz_);
STL::swap(buffer_, other.buffer_);
STL::swap(allocator_, other.allocator_);
}
~Block() { allocator_.deallocate(buffer_, sz_); }
......
......@@ -32,7 +32,11 @@
#include "misc.hpp"
#include "modes.hpp"
#include "algorithm.hpp"
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
......
......@@ -37,7 +37,7 @@ namespace TaoCrypt {
enum ErrorNumber {
NO_ERROR = 0, // "not in error state"
NO_ERROR_E = 0, // "not in error state"
// RandomNumberGenerator
WINCRYPT_E = 1001, // "bad wincrypt acquire"
......@@ -78,7 +78,7 @@ SIG_OTHER_E = 1039 // "bad other signature confirmation"
struct Error {
ErrorNumber what_; // description number, 0 for no error
explicit Error(ErrorNumber w = NO_ERROR) : what_(w) {}
explicit Error(ErrorNumber w = NO_ERROR_E) : what_(w) {}
ErrorNumber What() const { return what_; }
void SetError(ErrorNumber w) { what_ = w; }
......
......@@ -83,7 +83,7 @@ private:
void Swap(Source& other)
{
buffer_.Swap(other.buffer_);
mySTL::swap(current_, other.current_);
STL::swap(current_, other.current_);
}
};
......
......@@ -44,8 +44,8 @@
#include "block.hpp"
#include "random.hpp"
#include "file.hpp"
#include "algorithm.hpp" // mySTL::swap
#include <string.h>
#include STL_ALGORITHM_FILE
#ifdef TAOCRYPT_X86ASM_AVAILABLE
......
......@@ -198,6 +198,23 @@ void CleanUp();
#endif
#ifdef USE_SYS_STL
// use system STL
#define STL_VECTOR_FILE <vector>
#define STL_LIST_FILE <list>
#define STL_ALGORITHM_FILE <algorithm>
#define STL_MEMORY_FILE <memory>
#define STL_NAMESPACE std
#else
// use mySTL
#define STL_VECTOR_FILE "vector.hpp"
#define STL_LIST_FILE "list.hpp"
#define STL_ALGORITHM_FILE "algorithm.hpp"
#define STL_MEMORY_FILE "memory.hpp"
#define STL_NAMESPACE mySTL
#endif
// ***************** DLL related ********************
#ifdef TAOCRYPT_WIN32_AVAILABLE
......
......@@ -74,7 +74,7 @@ word32 PBKDF2_HMAC<T>::DeriveKey(byte* derived, word32 dLen, const byte* pwd,
}
hmac.Final(buffer.get_buffer());
word32 segmentLen = mySTL::min(dLen, buffer.size());
word32 segmentLen = min(dLen, buffer.size());
memcpy(derived, buffer.get_buffer(), segmentLen);
for (j = 1; j < iterations; j++) {
......
......@@ -32,7 +32,11 @@
#include "misc.hpp"
#include "modes.hpp"
#include "algorithm.hpp"
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
......
......@@ -8,7 +8,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to yaSSL. View the full text of the exception in the file
* FLOSS-EXCEPTIONS in the directory of this software distribution.
......
......@@ -113,6 +113,47 @@ PlaceIter uninit_fill_n(PlaceIter place, Size n, const T& value)
}
template <typename T>
T* GetArrayMemory(size_t items)
{
unsigned char* ret;
#ifdef YASSL_LIB
ret = NEW_YS unsigned char[sizeof(T) * items];
#else
ret = NEW_TC unsigned char[sizeof(T) * items];
#endif
return reinterpret_cast<T*>(ret);
}
template <typename T>
void FreeArrayMemory(T* ptr)
{
unsigned char* p = reinterpret_cast<unsigned char*>(ptr);
#ifdef YASSL_LIB
yaSSL::ysArrayDelete(p);
#else
TaoCrypt::tcArrayDelete(p);
#endif
}
static void* GetMemory(size_t bytes)
{
return GetArrayMemory<unsigned char>(bytes);
}
static void FreeMemory(void* ptr)
{
FreeArrayMemory(ptr);
}
} // namespace mySTL
......
......@@ -33,7 +33,6 @@
#include "helpers.hpp"
#include <stdlib.h>
namespace mySTL {
......@@ -75,8 +74,7 @@ public:
class iterator {
node* current_;
public:
iterator() : current_(0) {}
explicit iterator(node* p) : current_(p) {}
explicit iterator(node* p = 0) : current_(p) {}
T& operator*() const
{
......@@ -127,11 +125,67 @@ public:
friend class list<T>;
};
class reverse_iterator {
node* current_;
public:
explicit reverse_iterator(node* p = 0) : current_(p) {}
T& operator*() const
{
return current_->value_;
}
T* operator->() const
{
return &(operator*());
}
reverse_iterator& operator++()
{
current_ = current_->prev_;
return *this;
}
reverse_iterator& operator--()
{
current_ = current_->next_;
return *this;
}
reverse_iterator operator++(int)
{
reverse_iterator tmp = *this;
current_ = current_->prev_;
return tmp;
}
reverse_iterator operator--(int)
{
reverse_iterator tmp = *this;
current_ = current_->next_;
return tmp;
}
bool operator==(const reverse_iterator& other) const
{
return current_ == other.current_;
}
bool operator!=(const reverse_iterator& other) const
{
return current_ != other.current_;
}
friend class list<T>;
};
bool erase(iterator);
iterator begin() const { return iterator(head_); }
iterator rbegin() const { return iterator(tail_); }
iterator end() const { return iterator(); }
iterator begin() const { return iterator(head_); }
reverse_iterator rbegin() const { return reverse_iterator(tail_); }
iterator end() const { return iterator(); }
reverse_iterator rend() const { return reverse_iterator(); }
typedef iterator const_iterator; // for now
......@@ -158,7 +212,7 @@ list<T>::~list()
for (; start; start = next_) {
next_ = start->next_;
destroy(start);
free(start);
FreeMemory(start);
}
}
......@@ -166,8 +220,7 @@ list<T>::~list()
template<typename T>
void list<T>::push_front(T t)
{
void* mem = malloc(sizeof(node));
if (!mem) abort();
void* mem = GetMemory(sizeof(node));
node* add = new (reinterpret_cast<yassl_pointer>(mem)) node(t);
if (head_) {
......@@ -196,7 +249,7 @@ void list<T>::pop_front()
head_->prev_ = 0;
}
destroy(front);
free(front);
FreeMemory(front);
--sz_;
}
......@@ -204,7 +257,7 @@ void list<T>::pop_front()
template<typename T>
T list<T>::front() const
{
if (head_ == 0) return 0;
if (head_ == 0) return T();
return head_->value_;
}
......@@ -212,8 +265,7 @@ T list<T>::front() const
template<typename T>
void list<T>::push_back(T t)
{
void* mem = malloc(sizeof(node));
if (!mem) abort();
void* mem = GetMemory(sizeof(node));
node* add = new (reinterpret_cast<yassl_pointer>(mem)) node(t);
if (tail_) {
......@@ -242,7 +294,7 @@ void list<T>::pop_back()
tail_->next_ = 0;
}
destroy(rear);
free(rear);
FreeMemory(rear);
--sz_;
}
......@@ -250,7 +302,7 @@ void list<T>::pop_back()
template<typename T>
T list<T>::back() const
{
if (tail_ == 0) return 0;
if (tail_ == 0) return T();
return tail_->value_;
}
......@@ -286,7 +338,7 @@ bool list<T>::remove(T t)
del->next_->prev_ = del->prev_;
destroy(del);
free(del);
FreeMemory(del);
--sz_;
}
return true;
......@@ -309,78 +361,13 @@ bool list<T>::erase(iterator iter)
del->next_->prev_ = del->prev_;
destroy(del);
free(del);
FreeMemory(del);
--sz_;
}
return true;
}
/* MSVC can't handle ??
template<typename T>
T& list<T>::iterator::operator*() const
{
return current_->value_;
}
template<typename T>
T* list<T>::iterator::operator->() const
{
return &(operator*());
}
template<typename T>
typename list<T>::iterator& list<T>::iterator::operator++()
{
current_ = current_->next_;
return *this;
}
template<typename T>
typename list<T>::iterator& list<T>::iterator::operator--()
{
current_ = current_->prev_;
return *this;
}
template<typename T>
typename list<T>::iterator& list<T>::iterator::operator++(int)
{
iterator tmp = *this;
current_ = current_->next_;
return tmp;
}
template<typename T>
typename list<T>::iterator& list<T>::iterator::operator--(int)
{
iterator tmp = *this;
current_ = current_->prev_;
return tmp;
}
template<typename T>
bool list<T>::iterator::operator==(const iterator& other) const
{
return current_ == other.current_;
}
template<typename T>
bool list<T>::iterator::operator!=(const iterator& other) const
{
return current_ != other.current_;
}
*/ // end MSVC 6 can't handle
} // namespace mySTL
......
......@@ -31,6 +31,7 @@
#ifndef mySTL_MEMORY_HPP
#define mySTL_MEMORY_HPP
#include "memory_array.hpp" // for auto_array
#ifdef _MSC_VER
// disable operator-> warning for builtins
......@@ -43,27 +44,25 @@ namespace mySTL {
template<typename T>
struct auto_ptr_ref {
typedef void (*Deletor)(T*);
T* ptr_;
Deletor del_;
auto_ptr_ref(T* p, Deletor d) : ptr_(p), del_(d) {}
T* ptr_;
explicit auto_ptr_ref(T* p) : ptr_(p) {}
};
template<typename T>
class auto_ptr {
typedef void (*Deletor)(T*);
T* ptr_;
Deletor del_;
void Destroy()
{
del_(ptr_);
#ifdef YASSL_LIB
yaSSL::ysDelete(ptr_);
#else
TaoCrypt::tcDelete(ptr_);
#endif
}
public:
auto_ptr(T* p, Deletor d) : ptr_(p), del_(d) {}
explicit auto_ptr(Deletor d) : ptr_(0), del_(d) {}
explicit auto_ptr(T* p = 0) : ptr_(p) {}
~auto_ptr()
{
......@@ -71,14 +70,13 @@ public:
}
auto_ptr(auto_ptr& other) : ptr_(other.release()), del_(other.del_) {}
auto_ptr(auto_ptr& other) : ptr_(other.release()) {}
auto_ptr& operator=(auto_ptr& that)
{
if (this != &that) {
Destroy();
ptr_ = that.release();
del_ = that.del_;
}
return *this;
}
......@@ -115,14 +113,13 @@ public:
}
// auto_ptr_ref conversions
auto_ptr(auto_ptr_ref<T> ref) : ptr_(ref.ptr_), del_(ref.del_) {}
auto_ptr(auto_ptr_ref<T> ref) : ptr_(ref.ptr_) {}
auto_ptr& operator=(auto_ptr_ref<T> ref)
{
if (this->ptr_ != ref.ptr_) {
Destroy();
ptr_ = ref.ptr_;
del_ = ref.del_;
}
return *this;
}
......@@ -130,13 +127,13 @@ public:
template<typename T2>
operator auto_ptr<T2>()
{
return auto_ptr<T2>(this->release(), this->del_);
return auto_ptr<T2>(this->release());
}
template<typename T2>
operator auto_ptr_ref<T2>()
{
return auto_ptr_ref<T2>(this->release(), this->del_);
return auto_ptr_ref<T2>(this->release());
}
};
......
/* mySTL memory_array.hpp
*
* Copyright (C) 2003 Sawtooth Consulting Ltd.
*
* This file is part of yaSSL.
*
* yaSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to yaSSL. View the full text of the exception in the file
* FLOSS-EXCEPTIONS in the directory of this software distribution.
*
* yaSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/* mySTL memory_arry implements auto_array
*
*/
#ifndef mySTL_MEMORY_ARRAY_HPP
#define mySTL_MEMORY_ARRAY_HPP
#ifdef _MSC_VER
// disable operator-> warning for builtins
#pragma warning(disable:4284)
#endif
namespace mySTL {
template<typename T>
struct auto_array_ref {
T* ptr_;
explicit auto_array_ref(T* p) : ptr_(p) {}
};
template<typename T>
class auto_array {
T* ptr_;
void Destroy()
{
#ifdef YASSL_LIB
yaSSL::ysArrayDelete(ptr_);
#else
TaoCrypt::tcArrayDelete(ptr_);
#endif
}
public:
explicit auto_array(T* p = 0) : ptr_(p) {}
~auto_array()
{
Destroy();
}
auto_array(auto_array& other) : ptr_(other.release()) {}
auto_array& operator=(auto_array& that)
{
if (this != &that) {
Destroy();
ptr_ = that.release();
}
return *this;
}
T* operator->() const
{
return ptr_;
}
T& operator*() const
{
return *ptr_;
}
T* get() const
{
return ptr_;
}
T* release()
{
T* tmp = ptr_;
ptr_ = 0;
return tmp;
}
void reset(T* p = 0)
{
if (ptr_ != p) {
Destroy();
ptr_ = p;
}
}
// auto_array_ref conversions
auto_array(auto_array_ref<T> ref) : ptr_(ref.ptr_) {}
auto_array& operator=(auto_array_ref<T> ref)
{
if (this->ptr_ != ref.ptr_) {
Destroy();
ptr_ = ref.ptr_;
}
return *this;
}
template<typename T2>
operator auto_array<T2>()
{
return auto_array<T2>(this->release());
}
template<typename T2>
operator auto_array_ref<T2>()
{
return auto_array_ref<T2>(this->release());
}
};
} // namespace mySTL
#endif // mySTL_MEMORY_ARRAY_HPP
......@@ -34,7 +34,6 @@
#include "helpers.hpp" // construct, destory, fill, etc.
#include "algorithm.hpp" // swap
#include <assert.h> // assert
#include <stdlib.h> // malloc
namespace mySTL {
......@@ -49,14 +48,15 @@ struct vector_base {
vector_base() : start_(0), finish_(0), end_of_storage_(0) {}
vector_base(size_t n)
{
// Don't allow malloc(0), if n is 0 use 1
start_ = static_cast<T*>(malloc((n ? n : 1) * sizeof(T)));
if (!start_) abort();
start_ = GetArrayMemory<T>(n);
finish_ = start_;
end_of_storage_ = start_ + n;
}
~vector_base() { if (start_) free(start_); }
~vector_base()
{
FreeArrayMemory(start_);
}
void Swap(vector_base& that)
{
......@@ -71,6 +71,9 @@ struct vector_base {
template <typename T>
class vector {
public:
typedef T* iterator;
typedef const T* const_iterator;
vector() {}
explicit vector(size_t n) : vec_(n)
{
......
INCLUDES = -I../include -I../../mySTL
INCLUDES = -I../include -I../mySTL
noinst_LTLIBRARIES = libtaocrypt.la
......
......@@ -29,7 +29,10 @@
#include "runtime.hpp"
#include "algebra.hpp"
#include "vector.hpp" // mySTL::vector (simple)
#include STL_VECTOR_FILE
namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
......@@ -82,7 +85,7 @@ const Integer& AbstractEuclideanDomain::Mod(const Element &a,
const Integer& AbstractEuclideanDomain::Gcd(const Element &a,
const Element &b) const
{
mySTL::vector<Element> g(3);
STL::vector<Element> g(3);
g[0]= b;
g[1]= a;
unsigned int i0=0, i1=1, i2=2;
......@@ -115,7 +118,7 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x,
const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3));
const unsigned tableSize = 1<<w;
mySTL::vector<Element> powerTable(tableSize << w);
STL::vector<Element> powerTable(tableSize << w);
powerTable[1] = x;
powerTable[tableSize] = y;
......@@ -240,8 +243,8 @@ struct WindowSlider
void AbstractGroup::SimultaneousMultiply(Integer *results, const Integer &base,
const Integer *expBegin, unsigned int expCount) const
{
mySTL::vector<mySTL::vector<Element> > buckets(expCount);
mySTL::vector<WindowSlider> exponents;
STL::vector<STL::vector<Element> > buckets(expCount);
STL::vector<WindowSlider> exponents;
exponents.reserve(expCount);
unsigned int i;
......@@ -332,6 +335,8 @@ void AbstractRing::SimultaneousExponentiate(Integer *results,
namespace mySTL {
template TaoCrypt::WindowSlider* uninit_copy<TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*>(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*);
template void destroy<TaoCrypt::WindowSlider*>(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*);
template TaoCrypt::WindowSlider* GetArrayMemory<TaoCrypt::WindowSlider>(size_t);
template void FreeArrayMemory<TaoCrypt::WindowSlider>(TaoCrypt::WindowSlider*);
}
#endif
......@@ -38,7 +38,8 @@
#include "sha.hpp"
#include "coding.hpp"
#include <time.h> // gmtime();
#include "memory.hpp" // mySTL::auto_ptr
#include "memory.hpp" // some auto_ptr don't have reset, also need auto_array
namespace TaoCrypt {
......@@ -202,13 +203,13 @@ void PublicKey::SetKey(const byte* k)
void PublicKey::AddToEnd(const byte* data, word32 len)
{
mySTL::auto_ptr<byte> tmp(NEW_TC byte[sz_ + len], tcArrayDelete);
mySTL::auto_array<byte> tmp(NEW_TC byte[sz_ + len]);
memcpy(tmp.get(), key_, sz_);
memcpy(tmp.get() + sz_, data, len);
byte* del = 0;
mySTL::swap(del, key_);
STL::swap(del, key_);
tcArrayDelete(del);
key_ = tmp.release();
......@@ -856,7 +857,7 @@ bool CertDecoder::ValidateSignature(SignerList* signers)
bool CertDecoder::ConfirmSignature(Source& pub)
{
HashType ht;
mySTL::auto_ptr<HASH> hasher(tcDelete);
mySTL::auto_ptr<HASH> hasher;
if (signatureOID_ == MD5wRSA) {
hasher.reset(NEW_TC MD5);
......
......@@ -133,7 +133,7 @@ void Blowfish::SetKey(const byte* key_string, word32 keylength, CipherDir dir)
if (dir==DECRYPTION)
for (i=0; i<(ROUNDS+2)/2; i++)
mySTL::swap(pbox_[i], pbox_[ROUNDS+1-i]);
STL::swap(pbox_[i], pbox_[ROUNDS+1-i]);
}
......
......@@ -34,7 +34,10 @@
#include "runtime.hpp"
#include "des.hpp"
#include "algorithm.hpp" // mySTL::swap
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
......@@ -265,8 +268,8 @@ void BasicDES::SetKey(const byte* key, word32 /*length*/, CipherDir dir)
// reverse key schedule order
if (dir == DECRYPTION)
for (i = 0; i < 16; i += 2) {
mySTL::swap(k_[i], k_[32 - 2 - i]);
mySTL::swap(k_[i+1], k_[32 - 1 - i]);
STL::swap(k_[i], k_[32 - 2 - i]);
STL::swap(k_[i+1], k_[32 - 1 - i]);
}
}
......
......@@ -61,7 +61,7 @@ void DH::GenerateKeyPair(RandomNumberGenerator& rng, byte* priv, byte* pub)
// Generate private value
void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
{
Integer x(rng, Integer::One(), mySTL::min(p_ - 1,
Integer x(rng, Integer::One(), min(p_ - 1,
Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
x.Encode(priv, p_.ByteCount());
}
......
......@@ -1094,7 +1094,7 @@ static bool IsP4()
word32 cpuid[4];
CpuId(0, cpuid);
mySTL::swap(cpuid[2], cpuid[3]);
STL::swap(cpuid[2], cpuid[3]);
if (memcmp(cpuid+1, "GenuineIntel", 12) != 0)
return false;
......@@ -2384,8 +2384,8 @@ void AsymmetricMultiply(word *R, word *T, const word *A, unsigned int NA,
if (NA > NB)
{
mySTL::swap(A, B);
mySTL::swap(NA, NB);
STL::swap(A, B);
STL::swap(NA, NB);
}
assert(NB % NA == 0);
......@@ -2521,8 +2521,8 @@ unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA,
if (Compare(f, g, fgLen)==-1)
{
mySTL::swap(f, g);
mySTL::swap(b, c);
STL::swap(f, g);
STL::swap(b, c);
s++;
}
......@@ -3162,7 +3162,7 @@ signed long Integer::ConvertToLong() const
void Integer::Swap(Integer& a)
{
reg_.Swap(a.reg_);
mySTL::swap(sign_, a.sign_);
STL::swap(sign_, a.sign_);
}
......
......@@ -28,9 +28,11 @@
#include "runtime.hpp"
#include "md4.hpp"
#include "algorithm.hpp" // mySTL::swap
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
namespace TaoCrypt {
......@@ -69,9 +71,9 @@ MD4& MD4::operator= (const MD4& that)
void MD4::Swap(MD4& other)
{
mySTL::swap(loLen_, other.loLen_);
mySTL::swap(hiLen_, other.hiLen_);
mySTL::swap(buffLen_, other.buffLen_);
STL::swap(loLen_, other.loLen_);
STL::swap(hiLen_, other.hiLen_);
STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
......
......@@ -28,7 +28,10 @@
#include "runtime.hpp"
#include "md5.hpp"
#include "algorithm.hpp" // mySTL::swap
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
......@@ -72,9 +75,9 @@ MD5& MD5::operator= (const MD5& that)
void MD5::Swap(MD5& other)
{
mySTL::swap(loLen_, other.loLen_);
mySTL::swap(hiLen_, other.hiLen_);
mySTL::swap(buffLen_, other.buffLen_);
STL::swap(loLen_, other.loLen_);
STL::swap(hiLen_, other.hiLen_);
STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
......
......@@ -29,16 +29,6 @@
#include "runtime.hpp"
#include "misc.hpp"
#if !defined(YASSL_MYSQL_COMPATIBLE)
extern "C" {
// for libcurl configure test, these are the signatures they use
// locking handled internally by library
char CRYPTO_lock() { return 0;}
char CRYPTO_add_lock() { return 0;}
} // extern "C"
#endif
#ifdef YASSL_PURE_C
void* operator new(size_t sz, TaoCrypt::new_t)
......
......@@ -31,7 +31,7 @@
#include "runtime.hpp"
#include "random.hpp"
#include <string.h>
#include <time.h>
#if defined(_WIN32)
#define _WIN32_WINNT 0x0400
......@@ -74,6 +74,8 @@ byte RandomNumberGenerator::GenerateByte()
#if defined(_WIN32)
/* The OS_Seed implementation for windows */
OS_Seed::OS_Seed()
{
if(!CryptAcquireContext(&handle_, 0, 0, PROV_RSA_FULL,
......@@ -95,8 +97,70 @@ void OS_Seed::GenerateSeed(byte* output, word32 sz)
}
#else // _WIN32
#elif defined(__NETWARE__)
/* The OS_Seed implementation for Netware */
#include <nks/thread.h>
#include <nks/plat.h>
// Loop on high resulution Read Time Stamp Counter
static void NetwareSeed(byte* output, word32 sz)
{
word32 tscResult;
for (word32 i = 0; i < sz; i += sizeof(tscResult)) {
#if defined(__GNUC__)
asm volatile("rdtsc" : "=A" (tscResult));
#else
#ifdef __MWERKS__
asm {
#else
__asm {
#endif
rdtsc
mov tscResult, eax
}
#endif
memcpy(output, &tscResult, sizeof(tscResult));
output += sizeof(tscResult);
NXThreadYield(); // induce more variance
}
}
OS_Seed::OS_Seed()
{
}
OS_Seed::~OS_Seed()
{
}
void OS_Seed::GenerateSeed(byte* output, word32 sz)
{
/*
Try to use NXSeedRandom as it will generate a strong
seed using the onboard 82802 chip
As it's not always supported, fallback to default
implementation if an error is returned
*/
if (NXSeedRandom(sz, output) != 0)
{
NetwareSeed(output, sz);
}
}
#else
/* The default OS_Seed implementation */
OS_Seed::OS_Seed()
{
......
......@@ -28,9 +28,11 @@
#include "runtime.hpp"
#include "ripemd.hpp"
#include "algorithm.hpp" // mySTL::swap
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
#define DO_RIPEMD_ASM
......@@ -75,9 +77,9 @@ RIPEMD160& RIPEMD160::operator= (const RIPEMD160& that)
void RIPEMD160::Swap(RIPEMD160& other)
{
mySTL::swap(loLen_, other.loLen_);
mySTL::swap(hiLen_, other.hiLen_);
mySTL::swap(buffLen_, other.buffLen_);
STL::swap(loLen_, other.loLen_);
STL::swap(hiLen_, other.hiLen_);
STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
......
......@@ -27,8 +27,11 @@
#include "runtime.hpp"
#include <string.h>
#include "algorithm.hpp" // mySTL::swap
#include "sha.hpp"
#include STL_ALGORITHM_FILE
namespace STL = STL_NAMESPACE;
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
......@@ -96,9 +99,9 @@ SHA& SHA::operator= (const SHA& that)
void SHA::Swap(SHA& other)
{
mySTL::swap(loLen_, other.loLen_);
mySTL::swap(hiLen_, other.hiLen_);
mySTL::swap(buffLen_, other.buffLen_);
STL::swap(loLen_, other.loLen_);
STL::swap(hiLen_, other.hiLen_);
STL::swap(buffLen_, other.buffLen_);
memcpy(digest_, other.digest_, DIGEST_SIZE);
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
......
......@@ -77,6 +77,13 @@ template void destroy<vector<TaoCrypt::Integer>*>(vector<TaoCrypt::Integer>*, ve
template TaoCrypt::Integer* uninit_copy<TaoCrypt::Integer*, TaoCrypt::Integer*>(TaoCrypt::Integer*, TaoCrypt::Integer*, TaoCrypt::Integer*);
template TaoCrypt::Integer* uninit_fill_n<TaoCrypt::Integer*, size_t, TaoCrypt::Integer>(TaoCrypt::Integer*, size_t, TaoCrypt::Integer const&);
template void destroy<TaoCrypt::Integer*>(TaoCrypt::Integer*, TaoCrypt::Integer*);
template TaoCrypt::byte* GetArrayMemory<TaoCrypt::byte>(size_t);
template void FreeArrayMemory<TaoCrypt::byte>(TaoCrypt::byte*);
template TaoCrypt::Integer* GetArrayMemory<TaoCrypt::Integer>(size_t);
template void FreeArrayMemory<TaoCrypt::Integer>(TaoCrypt::Integer*);
template vector<TaoCrypt::Integer>* GetArrayMemory<vector<TaoCrypt::Integer> >(size_t);
template void FreeArrayMemory<vector<TaoCrypt::Integer> >(vector<TaoCrypt::Integer>*);
template void FreeArrayMemory<void>(void*);
}
#endif
INCLUDES = -I../include -I../../mySTL
INCLUDES = -I../include -I../mySTL
bin_PROGRAMS = test
test_SOURCES = test.cpp
test_LDFLAGS = -L../src
......
INCLUDES = -I../include -I../taocrypt/include -I../mySTL
INCLUDES = -I../include -I../taocrypt/include -I../taocrypt/mySTL
bin_PROGRAMS = testsuite
testsuite_SOURCES = testsuite.cpp ../taocrypt/test/test.cpp \
../examples/client/client.cpp ../examples/server/server.cpp \
......
......@@ -27,24 +27,27 @@
#endif /* _WIN32 */
#if !defined(_SOCKLEN_T) && defined(_WIN32)
#if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__NETWARE__))
typedef int socklen_t;
#endif
// Check type of third arg to accept
#if defined(__hpux)
// HPUX doesn't use socklent_t for third parameter to accept
#if !defined(__hpux)
typedef socklen_t* ACCEPT_THIRD_T;
#else
typedef int* ACCEPT_THIRD_T;
#else
typedef socklen_t* ACCEPT_THIRD_T;
#endif
// Check if _POSIX_THREADS should be forced
#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux))
// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
#ifndef _POSIX_THREADS
// Netware supports pthreads but does not announce it
#define _POSIX_THREADS
#endif
#endif
#ifndef _POSIX_THREADS
typedef unsigned int THREAD_RETURN;
......@@ -148,6 +151,13 @@ inline void err_sys(const char* msg)
}
static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
{
strncpy(passwd, "12345678", sz);
return 8;
}
inline void store_ca(SSL_CTX* ctx)
{
// To allow testing from serveral dirs
......@@ -168,6 +178,7 @@ inline void store_ca(SSL_CTX* ctx)
inline void set_certs(SSL_CTX* ctx)
{
store_ca(ctx);
SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
// To allow testing from serveral dirs
if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)
......@@ -193,6 +204,7 @@ inline void set_certs(SSL_CTX* ctx)
inline void set_serverCerts(SSL_CTX* ctx)
{
store_ca(ctx);
SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
// To allow testing from serveral dirs
if (SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
......@@ -258,13 +270,27 @@ inline void tcp_socket(SOCKET_T& sockfd, sockaddr_in& addr)
}
inline void tcp_close(SOCKET_T& sockfd)
{
#ifdef _WIN32
closesocket(sockfd);
#else
close(sockfd);
#endif
sockfd = -1;
}
inline void tcp_connect(SOCKET_T& sockfd)
{
sockaddr_in addr;
tcp_socket(sockfd, addr);
if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0)
{
tcp_close(sockfd);
err_sys("tcp connect failed");
}
}
......@@ -274,9 +300,15 @@ inline void tcp_listen(SOCKET_T& sockfd)
tcp_socket(sockfd, addr);
if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0)
{
tcp_close(sockfd);
err_sys("tcp bind failed");
}
if (listen(sockfd, 3) != 0)
{
tcp_close(sockfd);
err_sys("tcp listen failed");
}
}
......@@ -299,7 +331,10 @@ inline void tcp_accept(SOCKET_T& sockfd, int& clientfd, func_args& args)
clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len);
if (clientfd == -1)
{
tcp_close(sockfd);
err_sys("tcp accept failed");
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment