forked from wolfSSL/wolfssl
basic extneral cert manager added
This commit is contained in:
@ -2017,13 +2017,12 @@ static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ParseCert(DecodedCert* cert, int type, int verify,
|
int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
Signer* signers)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char* ptr;
|
char* ptr;
|
||||||
|
|
||||||
ret = ParseCertRelative(cert, type, verify, signers);
|
ret = ParseCertRelative(cert, type, verify, cm);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -2144,8 +2143,7 @@ static void IsCa(DecodedCert* cert)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int ParseCertRelative(DecodedCert* cert, int type, int verify,
|
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
Signer* signers)
|
|
||||||
{
|
{
|
||||||
word32 confirmOID;
|
word32 confirmOID;
|
||||||
int ret;
|
int ret;
|
||||||
@ -2181,7 +2179,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify,
|
|||||||
return ASN_SIG_OID_E;
|
return ASN_SIG_OID_E;
|
||||||
|
|
||||||
if (verify && type != CA_TYPE) {
|
if (verify && type != CA_TYPE) {
|
||||||
Signer* ca = GetCA(signers, cert->issuerHash);
|
Signer* ca = GetCA(cm, cert->issuerHash);
|
||||||
CYASSL_MSG("About to verify certificate signature");
|
CYASSL_MSG("About to verify certificate signature");
|
||||||
|
|
||||||
if (ca) {
|
if (ca) {
|
||||||
|
@ -262,11 +262,9 @@ struct Signer {
|
|||||||
|
|
||||||
CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
|
CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
|
||||||
CYASSL_TEST_API void FreeDecodedCert(DecodedCert*);
|
CYASSL_TEST_API void FreeDecodedCert(DecodedCert*);
|
||||||
CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify,
|
CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
|
||||||
Signer* signer);
|
|
||||||
|
|
||||||
CYASSL_LOCAL int ParseCertRelative(DecodedCert*, int type, int verify,
|
CYASSL_LOCAL int ParseCertRelative(DecodedCert*, int type, int verify,void* cm);
|
||||||
Signer* signer);
|
|
||||||
CYASSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
|
CYASSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
|
||||||
|
|
||||||
CYASSL_LOCAL word32 EncodeSignature(byte* out, const byte* digest, word32 digSz,
|
CYASSL_LOCAL word32 EncodeSignature(byte* out, const byte* digest, word32 digSz,
|
||||||
|
@ -200,7 +200,8 @@ enum {
|
|||||||
DYNAMIC_TYPE_SSL = 17,
|
DYNAMIC_TYPE_SSL = 17,
|
||||||
DYNAMIC_TYPE_CTX = 18,
|
DYNAMIC_TYPE_CTX = 18,
|
||||||
DYNAMIC_TYPE_WRITEV = 19,
|
DYNAMIC_TYPE_WRITEV = 19,
|
||||||
DYNAMIC_TYPE_OPENSSL = 20
|
DYNAMIC_TYPE_OPENSSL = 20,
|
||||||
|
DYNAMIC_TYPE_CERT_MANAGER = 21
|
||||||
};
|
};
|
||||||
|
|
||||||
/* stack protection */
|
/* stack protection */
|
||||||
|
@ -91,11 +91,12 @@ enum CyaSSL_ErrorCodes {
|
|||||||
BAD_MUTEX_ERROR = -256, /* Bad mutex */
|
BAD_MUTEX_ERROR = -256, /* Bad mutex */
|
||||||
NOT_CA_ERROR = -257, /* Not a CA cert error */
|
NOT_CA_ERROR = -257, /* Not a CA cert error */
|
||||||
BAD_PATH_ERROR = -258, /* Bad path for opendir */
|
BAD_PATH_ERROR = -258, /* Bad path for opendir */
|
||||||
|
BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
|
||||||
/* add strings to SetErrorString !!!!! */
|
/* add strings to SetErrorString !!!!! */
|
||||||
|
|
||||||
/* begin negotiation parameter errors */
|
/* begin negotiation parameter errors */
|
||||||
UNSUPPORTED_SUITE = -260, /* unsupported cipher suite */
|
UNSUPPORTED_SUITE = -270, /* unsupported cipher suite */
|
||||||
MATCH_SUITE_ERROR = -261 /* can't match cipher suite */
|
MATCH_SUITE_ERROR = -271 /* can't match cipher suite */
|
||||||
/* end negotiation parameter errors only 10 for now */
|
/* end negotiation parameter errors only 10 for now */
|
||||||
/* add strings to SetErrorString !!!!! */
|
/* add strings to SetErrorString !!!!! */
|
||||||
};
|
};
|
||||||
|
@ -619,6 +619,15 @@ CYASSL_LOCAL int LockMutex(CyaSSL_Mutex*);
|
|||||||
CYASSL_LOCAL int UnLockMutex(CyaSSL_Mutex*);
|
CYASSL_LOCAL int UnLockMutex(CyaSSL_Mutex*);
|
||||||
|
|
||||||
|
|
||||||
|
/* CyaSSL Certificate Manager */
|
||||||
|
struct CYASSL_CERT_MANAGER {
|
||||||
|
Signer* caList; /* the CA signer list */
|
||||||
|
CyaSSL_Mutex caLock; /* CA list lock */
|
||||||
|
CallbackCACache caCacheCallback; /* CA cache addition callback */
|
||||||
|
void* heap; /* heap helper */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* CyaSSL context type */
|
/* CyaSSL context type */
|
||||||
struct CYASSL_CTX {
|
struct CYASSL_CTX {
|
||||||
CYASSL_METHOD* method;
|
CYASSL_METHOD* method;
|
||||||
@ -630,7 +639,7 @@ struct CYASSL_CTX {
|
|||||||
buffer privateKey;
|
buffer privateKey;
|
||||||
buffer serverDH_P;
|
buffer serverDH_P;
|
||||||
buffer serverDH_G;
|
buffer serverDH_G;
|
||||||
Signer* caList; /* CYASSL_CTX owns this, SSL will reference */
|
CYASSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */
|
||||||
Suites suites;
|
Suites suites;
|
||||||
void* heap; /* for user memory overrides */
|
void* heap; /* for user memory overrides */
|
||||||
byte verifyPeer;
|
byte verifyPeer;
|
||||||
@ -648,7 +657,6 @@ struct CYASSL_CTX {
|
|||||||
byte groupMessages; /* group handshake messages before sending */
|
byte groupMessages; /* group handshake messages before sending */
|
||||||
CallbackIORecv CBIORecv;
|
CallbackIORecv CBIORecv;
|
||||||
CallbackIOSend CBIOSend;
|
CallbackIOSend CBIOSend;
|
||||||
CallbackCACache caCacheCallback; /* CA cache addition callback */
|
|
||||||
VerifyCallback verifyCallback; /* cert verification callback */
|
VerifyCallback verifyCallback; /* cert verification callback */
|
||||||
word32 timeout; /* session timeout */
|
word32 timeout; /* session timeout */
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
@ -680,9 +688,9 @@ CYASSL_LOCAL
|
|||||||
int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
word32 inSz, word16 sz);
|
word32 inSz, word16 sz);
|
||||||
CYASSL_LOCAL
|
CYASSL_LOCAL
|
||||||
int AddCA(CYASSL_CTX* ctx, buffer der, int force);
|
int AddCA(CYASSL_CERT_MANAGER* ctx, buffer der, int type, int verify);
|
||||||
CYASSL_LOCAL
|
CYASSL_LOCAL
|
||||||
int AlreadySigner(CYASSL_CTX* ctx, byte* hash);
|
int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash);
|
||||||
|
|
||||||
/* All cipher suite related info */
|
/* All cipher suite related info */
|
||||||
typedef struct CipherSpecs {
|
typedef struct CipherSpecs {
|
||||||
@ -1257,7 +1265,7 @@ CYASSL_LOCAL int IsAtLeastTLSv1_2(const CYASSL* ssl);
|
|||||||
CYASSL_LOCAL void ShrinkInputBuffer(CYASSL* ssl, int forcedFree);
|
CYASSL_LOCAL void ShrinkInputBuffer(CYASSL* ssl, int forcedFree);
|
||||||
CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl);
|
CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl);
|
||||||
CYASSL_LOCAL int SendHelloVerifyRequest(CYASSL* ssl);
|
CYASSL_LOCAL int SendHelloVerifyRequest(CYASSL* ssl);
|
||||||
CYASSL_LOCAL Signer* GetCA(Signer* signers, byte* hash);
|
CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash);
|
||||||
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
|
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
|
||||||
const byte* sender);
|
const byte* sender);
|
||||||
#ifndef NO_TLS
|
#ifndef NO_TLS
|
||||||
|
@ -65,6 +65,7 @@ typedef struct CYASSL_X509 CYASSL_X509;
|
|||||||
typedef struct CYASSL_X509_NAME CYASSL_X509_NAME;
|
typedef struct CYASSL_X509_NAME CYASSL_X509_NAME;
|
||||||
typedef struct CYASSL_X509_CHAIN CYASSL_X509_CHAIN;
|
typedef struct CYASSL_X509_CHAIN CYASSL_X509_CHAIN;
|
||||||
|
|
||||||
|
typedef struct CYASSL_CERT_MANAGER CYASSL_CERT_MANAGER;
|
||||||
|
|
||||||
/* redeclare guard */
|
/* redeclare guard */
|
||||||
#define CYASSL_TYPES_DEFINED
|
#define CYASSL_TYPES_DEFINED
|
||||||
@ -776,6 +777,14 @@ typedef void (*CallbackCACache)(unsigned char* der, int sz, int type);
|
|||||||
CYASSL_API void CyaSSL_CTX_SetCACb(CYASSL_CTX*, CallbackCACache);
|
CYASSL_API void CyaSSL_CTX_SetCACb(CYASSL_CTX*, CallbackCACache);
|
||||||
|
|
||||||
|
|
||||||
|
CYASSL_API CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void);
|
||||||
|
CYASSL_API void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER*);
|
||||||
|
|
||||||
|
CYASSL_API int CyaSSL_CertManagerLoadCA(CYASSL_CERT_MANAGER*, const char* f,
|
||||||
|
const char* d);
|
||||||
|
CYASSL_API int CyaSSL_CertManagerVerify(CYASSL_CERT_MANAGER*, const char* f,
|
||||||
|
int format);
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
|
|
||||||
/* used internally by CyaSSL while OpenSSL types aren't */
|
/* used internally by CyaSSL while OpenSSL types aren't */
|
||||||
|
@ -364,9 +364,8 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
|
|||||||
#endif
|
#endif
|
||||||
ctx->partialWrite = 0;
|
ctx->partialWrite = 0;
|
||||||
ctx->verifyCallback = 0;
|
ctx->verifyCallback = 0;
|
||||||
ctx->caCacheCallback = 0;
|
|
||||||
|
|
||||||
ctx->caList = 0;
|
ctx->cm = CyaSSL_CertManagerNew();
|
||||||
#ifdef HAVE_NTRU
|
#ifdef HAVE_NTRU
|
||||||
if (method->side == CLIENT_END)
|
if (method->side == CLIENT_END)
|
||||||
ctx->haveNTRU = 1; /* always on cliet side */
|
ctx->haveNTRU = 1; /* always on cliet side */
|
||||||
@ -395,6 +394,10 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
|
|||||||
CYASSL_MSG("Mutex error on CTX init");
|
CYASSL_MSG("Mutex error on CTX init");
|
||||||
return BAD_MUTEX_ERROR;
|
return BAD_MUTEX_ERROR;
|
||||||
}
|
}
|
||||||
|
if (ctx->cm == NULL) {
|
||||||
|
CYASSL_MSG("Bad Cert Manager New");
|
||||||
|
return BAD_CERT_MANAGER_ERROR;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +412,7 @@ void SSL_CtxResourceFree(CYASSL_CTX* ctx)
|
|||||||
XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
|
XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
|
||||||
XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
|
XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
|
||||||
|
|
||||||
FreeSigners(ctx->caList, ctx->heap);
|
CyaSSL_CertManagerFree(ctx->cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -858,7 +861,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->options.certOnly = 0;
|
ssl->options.certOnly = 0;
|
||||||
ssl->options.groupMessages = ctx->groupMessages;
|
ssl->options.groupMessages = ctx->groupMessages;
|
||||||
|
|
||||||
/* ctx still owns certificate, certChain, key, dh, and caList buffers */
|
/* ctx still owns certificate, certChain, key, dh, and cm */
|
||||||
ssl->buffers.certificate = ctx->certificate;
|
ssl->buffers.certificate = ctx->certificate;
|
||||||
ssl->buffers.certChain = ctx->certChain;
|
ssl->buffers.certChain = ctx->certChain;
|
||||||
ssl->buffers.key = ctx->privateKey;
|
ssl->buffers.key = ctx->privateKey;
|
||||||
@ -1613,7 +1616,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
|
|
||||||
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
||||||
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
||||||
ssl->ctx->caList);
|
ssl->ctx->cm);
|
||||||
if (ret == 0 && dCert.isCA == 0) {
|
if (ret == 0 && dCert.isCA == 0) {
|
||||||
CYASSL_MSG("Chain cert is not a CA, not adding as one");
|
CYASSL_MSG("Chain cert is not a CA, not adding as one");
|
||||||
(void)ret;
|
(void)ret;
|
||||||
@ -1622,7 +1625,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
CYASSL_MSG("Chain cert not verified by option, not adding as CA");
|
CYASSL_MSG("Chain cert not verified by option, not adding as CA");
|
||||||
(void)ret;
|
(void)ret;
|
||||||
}
|
}
|
||||||
else if (ret == 0 && !AlreadySigner(ssl->ctx, dCert.subjectHash)) {
|
else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, dCert.subjectHash)) {
|
||||||
buffer add;
|
buffer add;
|
||||||
add.length = myCert.length;
|
add.length = myCert.length;
|
||||||
add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
||||||
@ -1633,7 +1636,8 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
XMEMCPY(add.buffer, myCert.buffer, myCert.length);
|
XMEMCPY(add.buffer, myCert.buffer, myCert.length);
|
||||||
|
|
||||||
ret = AddCA(ssl->ctx, add, CYASSL_CHAIN_CA);
|
ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
|
||||||
|
ssl->ctx->verifyPeer);
|
||||||
if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
|
if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
|
||||||
}
|
}
|
||||||
else if (ret != 0) {
|
else if (ret != 0) {
|
||||||
@ -1662,7 +1666,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
|
|
||||||
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
||||||
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
||||||
ssl->ctx->caList);
|
ssl->ctx->cm);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
CYASSL_MSG("Verified Peer's cert");
|
CYASSL_MSG("Verified Peer's cert");
|
||||||
fatal = 0;
|
fatal = 0;
|
||||||
@ -3482,6 +3486,10 @@ void SetErrorString(int error, char* str)
|
|||||||
XSTRNCPY(str, "Bad path for opendir error", max);
|
XSTRNCPY(str, "Bad path for opendir error", max);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BAD_CERT_MANAGER_ERROR:
|
||||||
|
XSTRNCPY(str, "Bad Cert Manager error", max);
|
||||||
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
XSTRNCPY(str, "unknown error number", max);
|
XSTRNCPY(str, "unknown error number", max);
|
||||||
}
|
}
|
||||||
|
207
src/ssl.c
207
src/ssl.c
@ -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
|
#ifndef NO_FILESYSTEM
|
||||||
|
|
||||||
void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
|
void CyaSSL_ERR_print_errors_fp(FILE* fp, int err)
|
||||||
@ -423,17 +462,15 @@ int CyaSSL_set_group_messages(CYASSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CyaSSL_Mutex ca_mutex; /* CA signers mutex */
|
|
||||||
|
|
||||||
/* does CA already exist on signer list */
|
/* does CA already exist on signer list */
|
||||||
int AlreadySigner(CYASSL_CTX* ctx, byte* hash)
|
int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
|
||||||
{
|
{
|
||||||
Signer* signers;
|
Signer* signers;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (LockMutex(&ca_mutex) != 0)
|
if (LockMutex(&cm->caLock) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
signers = ctx->caList;
|
signers = cm->caList;
|
||||||
while (signers) {
|
while (signers) {
|
||||||
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -441,18 +478,25 @@ int AlreadySigner(CYASSL_CTX* ctx, byte* hash)
|
|||||||
}
|
}
|
||||||
signers = signers->next;
|
signers = signers->next;
|
||||||
}
|
}
|
||||||
UnLockMutex(&ca_mutex);
|
UnLockMutex(&cm->caLock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return CA if found, otherwise NULL */
|
/* 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;
|
return ret;
|
||||||
while (signers) {
|
while (signers) {
|
||||||
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
||||||
@ -461,7 +505,7 @@ Signer* GetCA(Signer* signers, byte* hash)
|
|||||||
}
|
}
|
||||||
signers = signers->next;
|
signers = signers->next;
|
||||||
}
|
}
|
||||||
UnLockMutex(&ca_mutex);
|
UnLockMutex(&cm->caLock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -470,28 +514,28 @@ Signer* GetCA(Signer* signers, byte* hash)
|
|||||||
/* owns der, internal now uses too */
|
/* owns der, internal now uses too */
|
||||||
/* type flag ids from user or from chain received during verify
|
/* type flag ids from user or from chain received during verify
|
||||||
don't allow chain ones to be added w/o isCA extension */
|
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;
|
int ret;
|
||||||
DecodedCert cert;
|
DecodedCert cert;
|
||||||
Signer* signer = 0;
|
Signer* signer = 0;
|
||||||
|
|
||||||
CYASSL_MSG("Adding a CA");
|
CYASSL_MSG("Adding a CA");
|
||||||
InitDecodedCert(&cert, der.buffer, der.length, ctx->heap);
|
InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
|
||||||
ret = ParseCert(&cert, CA_TYPE, ctx->verifyPeer, 0);
|
ret = ParseCert(&cert, CA_TYPE, verify, cm);
|
||||||
CYASSL_MSG(" Parsed new CA");
|
CYASSL_MSG(" Parsed new CA");
|
||||||
|
|
||||||
if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
|
if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
|
||||||
CYASSL_MSG(" Can't add as CA if not actually one");
|
CYASSL_MSG(" Can't add as CA if not actually one");
|
||||||
ret = NOT_CA_ERROR;
|
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");
|
CYASSL_MSG(" Already have this CA, not adding again");
|
||||||
(void)ret;
|
(void)ret;
|
||||||
}
|
}
|
||||||
else if (ret == 0) {
|
else if (ret == 0) {
|
||||||
/* take over signer parts */
|
/* take over signer parts */
|
||||||
signer = MakeSigner(ctx->heap);
|
signer = MakeSigner(cm->heap);
|
||||||
if (!signer)
|
if (!signer)
|
||||||
ret = MEMORY_ERROR;
|
ret = MEMORY_ERROR;
|
||||||
else {
|
else {
|
||||||
@ -505,17 +549,17 @@ int AddCA(CYASSL_CTX* ctx, buffer der, int type)
|
|||||||
cert.publicKey = 0; /* don't free here */
|
cert.publicKey = 0; /* don't free here */
|
||||||
cert.subjectCN = 0;
|
cert.subjectCN = 0;
|
||||||
|
|
||||||
if (LockMutex(&ca_mutex) == 0) {
|
if (LockMutex(&cm->caLock) == 0) {
|
||||||
signer->next = ctx->caList;
|
signer->next = cm->caList;
|
||||||
ctx->caList = signer; /* takes ownership */
|
cm->caList = signer; /* takes ownership */
|
||||||
UnLockMutex(&ca_mutex);
|
UnLockMutex(&cm->caLock);
|
||||||
if (ctx->caCacheCallback)
|
if (cm->caCacheCallback)
|
||||||
ctx->caCacheCallback(der.buffer, (int)der.length, type);
|
cm->caCacheCallback(der.buffer, (int)der.length, type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CYASSL_MSG(" CA Mutex Lock failed");
|
CYASSL_MSG(" CA Mutex Lock failed");
|
||||||
ret = BAD_MUTEX_ERROR;
|
ret = BAD_MUTEX_ERROR;
|
||||||
FreeSigners(signer, ctx->heap);
|
FreeSigners(signer, cm->heap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -932,7 +976,8 @@ int AddCA(CYASSL_CTX* ctx, buffer der, int type)
|
|||||||
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
|
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
|
||||||
|
|
||||||
if (type == CA_TYPE)
|
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) {
|
else if (type == CERT_TYPE) {
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
|
if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
|
||||||
@ -1201,6 +1246,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
|
#ifdef CYASSL_DER_LOAD
|
||||||
|
|
||||||
/* Add format parameter to allow DER load of CA files */
|
/* Add format parameter to allow DER load of CA files */
|
||||||
@ -1580,8 +1724,8 @@ void CyaSSL_set_verify(CYASSL* ssl, int mode, VerifyCallback vc)
|
|||||||
/* store context CA Cache addition callback */
|
/* store context CA Cache addition callback */
|
||||||
void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
|
void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
|
||||||
{
|
{
|
||||||
if (ctx && cb)
|
if (ctx && ctx->cm)
|
||||||
ctx->caCacheCallback = cb;
|
ctx->cm->caCacheCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2126,6 +2270,7 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
|
|||||||
|
|
||||||
/* prevent multiple mutex initializations */
|
/* prevent multiple mutex initializations */
|
||||||
static volatile int initRefCount = 0;
|
static volatile int initRefCount = 0;
|
||||||
|
static CyaSSL_Mutex count_mutex; /* init ref count mutex */
|
||||||
|
|
||||||
int CyaSSL_Init(void)
|
int CyaSSL_Init(void)
|
||||||
{
|
{
|
||||||
@ -2138,13 +2283,13 @@ int CyaSSL_Init(void)
|
|||||||
if (InitMutex(&session_mutex) != 0)
|
if (InitMutex(&session_mutex) != 0)
|
||||||
ret = BAD_MUTEX_ERROR;
|
ret = BAD_MUTEX_ERROR;
|
||||||
#endif
|
#endif
|
||||||
if (InitMutex(&ca_mutex) != 0)
|
if (InitMutex(&count_mutex) != 0)
|
||||||
ret = BAD_MUTEX_ERROR;
|
ret = BAD_MUTEX_ERROR;
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
LockMutex(&ca_mutex);
|
LockMutex(&count_mutex);
|
||||||
initRefCount++;
|
initRefCount++;
|
||||||
UnLockMutex(&ca_mutex);
|
UnLockMutex(&count_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -2158,13 +2303,13 @@ int CyaSSL_Cleanup(void)
|
|||||||
|
|
||||||
CYASSL_ENTER("CyaSSL_Cleanup");
|
CYASSL_ENTER("CyaSSL_Cleanup");
|
||||||
|
|
||||||
LockMutex(&ca_mutex);
|
LockMutex(&count_mutex);
|
||||||
|
|
||||||
release = initRefCount-- == 1;
|
release = initRefCount-- == 1;
|
||||||
if (initRefCount < 0)
|
if (initRefCount < 0)
|
||||||
initRefCount = 0;
|
initRefCount = 0;
|
||||||
|
|
||||||
UnLockMutex(&ca_mutex);
|
UnLockMutex(&count_mutex);
|
||||||
|
|
||||||
if (!release)
|
if (!release)
|
||||||
return ret;
|
return ret;
|
||||||
@ -2173,7 +2318,7 @@ int CyaSSL_Cleanup(void)
|
|||||||
if (FreeMutex(&session_mutex) != 0)
|
if (FreeMutex(&session_mutex) != 0)
|
||||||
ret = BAD_MUTEX_ERROR;
|
ret = BAD_MUTEX_ERROR;
|
||||||
#endif
|
#endif
|
||||||
if (FreeMutex(&ca_mutex) != 0)
|
if (FreeMutex(&count_mutex) != 0)
|
||||||
ret = BAD_MUTEX_ERROR;
|
ret = BAD_MUTEX_ERROR;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user