forked from wolfSSL/wolfssl
merge fix
This commit is contained in:
267
src/ssl.c
267
src/ssl.c
@@ -227,7 +227,7 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz,
|
||||
#endif
|
||||
InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH,
|
||||
havePSK, ssl->options.haveNTRU, ssl->options.haveECDSA,
|
||||
ssl->ctx->method->side);
|
||||
ssl->options.haveStaticECC, ssl->ctx->method->side);
|
||||
|
||||
CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
|
||||
return 0;
|
||||
@@ -362,6 +362,45 @@ void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
|
||||
}
|
||||
|
||||
|
||||
CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void)
|
||||
{
|
||||
CYASSL_CERT_MANAGER* cm = NULL;
|
||||
|
||||
CYASSL_ENTER("CyaSSL_CertManagerNew");
|
||||
|
||||
cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0,
|
||||
DYNAMIC_TYPE_CERT_MANAGER);
|
||||
if (cm) {
|
||||
cm->caList = NULL;
|
||||
cm->heap = NULL;
|
||||
cm->caCacheCallback = NULL;
|
||||
|
||||
if (InitMutex(&cm->caLock) != 0) {
|
||||
CYASSL_MSG("Bad mutex init");
|
||||
CyaSSL_CertManagerFree(cm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return cm;
|
||||
}
|
||||
|
||||
|
||||
void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
|
||||
{
|
||||
CYASSL_ENTER("CyaSSL_CertManagerFree");
|
||||
|
||||
if (cm) {
|
||||
FreeSigners(cm->caList, NULL);
|
||||
FreeMutex(&cm->caLock);
|
||||
XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
|
||||
void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
|
||||
@@ -395,6 +434,7 @@ int CyaSSL_CTX_set_group_messages(CYASSL_CTX* ctx)
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_CYASSL_CLIENT
|
||||
/* connect enough to get peer cert chain */
|
||||
int CyaSSL_connect_cert(CYASSL* ssl)
|
||||
{
|
||||
@@ -409,6 +449,7 @@ int CyaSSL_connect_cert(CYASSL* ssl)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* trun on handshake group messages for ssl object */
|
||||
@@ -423,17 +464,15 @@ int CyaSSL_set_group_messages(CYASSL* ssl)
|
||||
}
|
||||
|
||||
|
||||
static CyaSSL_Mutex ca_mutex; /* CA signers mutex */
|
||||
|
||||
/* does CA already exist on signer list */
|
||||
int AlreadySigner(CYASSL_CTX* ctx, byte* hash)
|
||||
int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
|
||||
{
|
||||
Signer* signers;
|
||||
int ret = 0;
|
||||
|
||||
if (LockMutex(&ca_mutex) != 0)
|
||||
if (LockMutex(&cm->caLock) != 0)
|
||||
return ret;
|
||||
signers = ctx->caList;
|
||||
signers = cm->caList;
|
||||
while (signers) {
|
||||
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
||||
ret = 1;
|
||||
@@ -441,18 +480,25 @@ int AlreadySigner(CYASSL_CTX* ctx, byte* hash)
|
||||
}
|
||||
signers = signers->next;
|
||||
}
|
||||
UnLockMutex(&ca_mutex);
|
||||
UnLockMutex(&cm->caLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* return CA if found, otherwise NULL */
|
||||
Signer* GetCA(Signer* signers, byte* hash)
|
||||
Signer* GetCA(void* vp, byte* hash)
|
||||
{
|
||||
Signer* ret = 0;
|
||||
CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
|
||||
Signer* ret = NULL;
|
||||
Signer* signers;
|
||||
|
||||
if (LockMutex(&ca_mutex) != 0)
|
||||
if (cm == NULL)
|
||||
return NULL;
|
||||
|
||||
signers = cm->caList;
|
||||
|
||||
if (LockMutex(&cm->caLock) != 0)
|
||||
return ret;
|
||||
while (signers) {
|
||||
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
||||
@@ -461,7 +507,7 @@ Signer* GetCA(Signer* signers, byte* hash)
|
||||
}
|
||||
signers = signers->next;
|
||||
}
|
||||
UnLockMutex(&ca_mutex);
|
||||
UnLockMutex(&cm->caLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -470,28 +516,28 @@ Signer* GetCA(Signer* signers, byte* hash)
|
||||
/* owns der, internal now uses too */
|
||||
/* type flag ids from user or from chain received during verify
|
||||
don't allow chain ones to be added w/o isCA extension */
|
||||
int AddCA(CYASSL_CTX* ctx, buffer der, int type)
|
||||
int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
|
||||
{
|
||||
int ret;
|
||||
DecodedCert cert;
|
||||
Signer* signer = 0;
|
||||
|
||||
CYASSL_MSG("Adding a CA");
|
||||
InitDecodedCert(&cert, der.buffer, der.length, ctx->heap);
|
||||
ret = ParseCert(&cert, CA_TYPE, ctx->verifyPeer, 0);
|
||||
InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
|
||||
ret = ParseCert(&cert, CA_TYPE, verify, cm);
|
||||
CYASSL_MSG(" Parsed new CA");
|
||||
|
||||
if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
|
||||
CYASSL_MSG(" Can't add as CA if not actually one");
|
||||
ret = NOT_CA_ERROR;
|
||||
}
|
||||
else if (ret == 0 && AlreadySigner(ctx, cert.subjectHash)) {
|
||||
else if (ret == 0 && AlreadySigner(cm, cert.subjectHash)) {
|
||||
CYASSL_MSG(" Already have this CA, not adding again");
|
||||
(void)ret;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
/* take over signer parts */
|
||||
signer = MakeSigner(ctx->heap);
|
||||
signer = MakeSigner(cm->heap);
|
||||
if (!signer)
|
||||
ret = MEMORY_ERROR;
|
||||
else {
|
||||
@@ -505,17 +551,17 @@ int AddCA(CYASSL_CTX* ctx, buffer der, int type)
|
||||
cert.publicKey = 0; /* don't free here */
|
||||
cert.subjectCN = 0;
|
||||
|
||||
if (LockMutex(&ca_mutex) == 0) {
|
||||
signer->next = ctx->caList;
|
||||
ctx->caList = signer; /* takes ownership */
|
||||
UnLockMutex(&ca_mutex);
|
||||
if (ctx->caCacheCallback)
|
||||
ctx->caCacheCallback(der.buffer, (int)der.length, type);
|
||||
if (LockMutex(&cm->caLock) == 0) {
|
||||
signer->next = cm->caList;
|
||||
cm->caList = signer; /* takes ownership */
|
||||
UnLockMutex(&cm->caLock);
|
||||
if (cm->caCacheCallback)
|
||||
cm->caCacheCallback(der.buffer, (int)der.length, type);
|
||||
}
|
||||
else {
|
||||
CYASSL_MSG(" CA Mutex Lock failed");
|
||||
ret = BAD_MUTEX_ERROR;
|
||||
FreeSigners(signer, ctx->heap);
|
||||
FreeSigners(signer, cm->heap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,7 +978,8 @@ int AddCA(CYASSL_CTX* ctx, buffer der, int type)
|
||||
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
|
||||
|
||||
if (type == CA_TYPE)
|
||||
return AddCA(ctx, der, CYASSL_USER_CA); /* takes der over */
|
||||
return AddCA(ctx->cm, der, CYASSL_USER_CA, ctx->verifyPeer);
|
||||
/* takes der over */
|
||||
else if (type == CERT_TYPE) {
|
||||
if (ssl) {
|
||||
if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
|
||||
@@ -996,10 +1043,37 @@ int AddCA(CYASSL_CTX* ctx, buffer der, int type)
|
||||
return SSL_BAD_FILE;
|
||||
}
|
||||
ecc_free(&key);
|
||||
ctx->haveECDSA = 1;
|
||||
ctx->haveStaticECC = 1;
|
||||
if (ssl)
|
||||
ssl->options.haveStaticECC = 1;
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
else if (type == CERT_TYPE) {
|
||||
int ret;
|
||||
DecodedCert cert;
|
||||
|
||||
CYASSL_MSG("Checking cert signature type");
|
||||
InitDecodedCert(&cert, der.buffer, der.length, ctx->heap);
|
||||
|
||||
if ((ret = DecodeToKey(&cert, 0)) < 0) {
|
||||
CYASSL_MSG("Decode to key failed");
|
||||
return SSL_BAD_FILE;
|
||||
}
|
||||
switch (cert.signatureOID) {
|
||||
case CTC_SHAwECDSA:
|
||||
case CTC_SHA256wECDSA:
|
||||
case CTC_SHA384wECDSA:
|
||||
case CTC_SHA512wECDSA:
|
||||
CYASSL_MSG("ECDSA cert signature");
|
||||
ctx->haveECDSA = 1;
|
||||
if (ssl)
|
||||
ssl->options.haveECDSA = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
FreeDecodedCert(&cert);
|
||||
}
|
||||
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
@@ -1174,6 +1248,105 @@ int CyaSSL_CTX_load_verify_locations(CYASSL_CTX* ctx, const char* file,
|
||||
}
|
||||
|
||||
|
||||
/* Verify the ceritficate, 1 for success, < 0 for error */
|
||||
int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER* cm, const char* fname,
|
||||
int format)
|
||||
{
|
||||
int ret = SSL_FATAL_ERROR;
|
||||
int eccKey = 0; /* not used */
|
||||
DecodedCert cert;
|
||||
|
||||
byte staticBuffer[FILE_BUFFER_SIZE];
|
||||
byte* myBuffer = staticBuffer;
|
||||
int dynamic = 0;
|
||||
long sz = 0;
|
||||
buffer der;
|
||||
XFILE* file = XFOPEN(fname, "rb");
|
||||
|
||||
if (!file) return SSL_BAD_FILE;
|
||||
XFSEEK(file, 0, XSEEK_END);
|
||||
sz = XFTELL(file);
|
||||
XREWIND(file);
|
||||
|
||||
der.buffer = NULL;
|
||||
|
||||
if (sz > (long)sizeof(staticBuffer)) {
|
||||
CYASSL_MSG("Getting dynamic buffer");
|
||||
myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
|
||||
if (myBuffer == NULL) {
|
||||
XFCLOSE(file);
|
||||
return SSL_BAD_FILE;
|
||||
}
|
||||
dynamic = 1;
|
||||
}
|
||||
|
||||
if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
|
||||
ret = SSL_BAD_FILE;
|
||||
else {
|
||||
ret = 0; /* ok */
|
||||
if (format == SSL_FILETYPE_PEM) {
|
||||
EncryptedInfo info;
|
||||
|
||||
info.set = 0;
|
||||
info.ctx = NULL;
|
||||
info.consumed = 0;
|
||||
ret = PemToDer(myBuffer, sz, CERT_TYPE, &der, cm->heap, &info,
|
||||
&eccKey);
|
||||
InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
|
||||
|
||||
}
|
||||
else
|
||||
InitDecodedCert(&cert, myBuffer, sz, cm->heap);
|
||||
|
||||
if (ret == 0)
|
||||
ret = ParseCertRelative(&cert, CERT_TYPE, 1, cm);
|
||||
}
|
||||
|
||||
FreeDecodedCert(&cert);
|
||||
XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
|
||||
XFCLOSE(file);
|
||||
if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
|
||||
|
||||
if (ret == 0)
|
||||
return SSL_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* like load verify locations, 1 for success, < 0 for error */
|
||||
int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER* cm, const char* file,
|
||||
const char* path)
|
||||
{
|
||||
int ret = SSL_FATAL_ERROR;
|
||||
CYASSL_CTX* tmp;
|
||||
|
||||
CYASSL_ENTER("CyaSSL_CertManagerLoadCA");
|
||||
|
||||
if (cm == NULL) {
|
||||
CYASSL_MSG("No CertManager error");
|
||||
return ret;
|
||||
}
|
||||
tmp = CyaSSL_CTX_new(CyaSSLv3_client_method());
|
||||
|
||||
if (tmp == NULL) {
|
||||
CYASSL_MSG("CTX new failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* for tmp use */
|
||||
CyaSSL_CertManagerFree(tmp->cm);
|
||||
tmp->cm = cm;
|
||||
|
||||
ret = CyaSSL_CTX_load_verify_locations(tmp, file, path);
|
||||
|
||||
/* don't loose our good one */
|
||||
tmp->cm = NULL;
|
||||
CyaSSL_CTX_free(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_DER_LOAD
|
||||
|
||||
/* Add format parameter to allow DER load of CA files */
|
||||
@@ -1553,8 +1726,8 @@ void CyaSSL_set_verify(CYASSL* ssl, int mode, VerifyCallback vc)
|
||||
/* store context CA Cache addition callback */
|
||||
void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
|
||||
{
|
||||
if (ctx && cb)
|
||||
ctx->caCacheCallback = cb;
|
||||
if (ctx && ctx->cm)
|
||||
ctx->cm->caCacheCallback = cb;
|
||||
}
|
||||
|
||||
|
||||
@@ -1633,7 +1806,7 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
|
||||
|
||||
InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
|
||||
ssl->options.haveNTRU, ssl->options.haveECDSA,
|
||||
ssl->ctx->method->side);
|
||||
ssl->options.haveStaticECC, ssl->ctx->method->side);
|
||||
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
@@ -2099,6 +2272,7 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
|
||||
|
||||
/* prevent multiple mutex initializations */
|
||||
static volatile int initRefCount = 0;
|
||||
static CyaSSL_Mutex count_mutex; /* init ref count mutex */
|
||||
|
||||
int CyaSSL_Init(void)
|
||||
{
|
||||
@@ -2111,13 +2285,13 @@ int CyaSSL_Init(void)
|
||||
if (InitMutex(&session_mutex) != 0)
|
||||
ret = BAD_MUTEX_ERROR;
|
||||
#endif
|
||||
if (InitMutex(&ca_mutex) != 0)
|
||||
if (InitMutex(&count_mutex) != 0)
|
||||
ret = BAD_MUTEX_ERROR;
|
||||
}
|
||||
if (ret == 0) {
|
||||
LockMutex(&ca_mutex);
|
||||
LockMutex(&count_mutex);
|
||||
initRefCount++;
|
||||
UnLockMutex(&ca_mutex);
|
||||
UnLockMutex(&count_mutex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -2131,13 +2305,13 @@ int CyaSSL_Cleanup(void)
|
||||
|
||||
CYASSL_ENTER("CyaSSL_Cleanup");
|
||||
|
||||
LockMutex(&ca_mutex);
|
||||
LockMutex(&count_mutex);
|
||||
|
||||
release = initRefCount-- == 1;
|
||||
if (initRefCount < 0)
|
||||
initRefCount = 0;
|
||||
|
||||
UnLockMutex(&ca_mutex);
|
||||
UnLockMutex(&count_mutex);
|
||||
|
||||
if (!release)
|
||||
return ret;
|
||||
@@ -2146,7 +2320,7 @@ int CyaSSL_Cleanup(void)
|
||||
if (FreeMutex(&session_mutex) != 0)
|
||||
ret = BAD_MUTEX_ERROR;
|
||||
#endif
|
||||
if (FreeMutex(&ca_mutex) != 0)
|
||||
if (FreeMutex(&count_mutex) != 0)
|
||||
ret = BAD_MUTEX_ERROR;
|
||||
|
||||
return ret;
|
||||
@@ -2649,7 +2823,8 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||
ssl->options.client_psk_cb = cb;
|
||||
|
||||
InitSuites(&ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU,
|
||||
ssl->options.haveECDSA, ssl->ctx->method->side);
|
||||
ssl->options.haveECDSA, ssl->options.haveStaticECC,
|
||||
ssl->ctx->method->side);
|
||||
}
|
||||
|
||||
|
||||
@@ -2670,7 +2845,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||
|
||||
InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, TRUE,
|
||||
ssl->options.haveNTRU, ssl->options.haveECDSA,
|
||||
ssl->ctx->method->side);
|
||||
ssl->optoins.haveStaticECC, ssl->ctx->method->side);
|
||||
}
|
||||
|
||||
|
||||
@@ -2904,7 +3079,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||
#endif
|
||||
InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
|
||||
ssl->options.haveNTRU, ssl->options.haveECDSA,
|
||||
ssl->ctx->method->side);
|
||||
ssl->options.haveStaticECC, ssl->ctx->method->side);
|
||||
}
|
||||
|
||||
|
||||
@@ -4365,6 +4540,24 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||
return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
|
||||
case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
|
||||
return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
|
||||
|
||||
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
|
||||
return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
|
||||
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
|
||||
return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
|
||||
case TLS_ECDH_RSA_WITH_RC4_128_SHA :
|
||||
return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
|
||||
case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
|
||||
return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
|
||||
case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
|
||||
return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
|
||||
case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
|
||||
return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
|
||||
|
||||
default:
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user