forked from wolfSSL/wolfssl
check basic contsraint CA flag before adding as signer even if explicit add
This commit is contained in:
@ -1017,6 +1017,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
|
|||||||
cert->extensions = 0;
|
cert->extensions = 0;
|
||||||
cert->extensionsSz = 0;
|
cert->extensionsSz = 0;
|
||||||
cert->extensionsIdx = 0;
|
cert->extensionsIdx = 0;
|
||||||
|
cert->isCA = 0;
|
||||||
#ifdef CYASSL_CERT_GEN
|
#ifdef CYASSL_CERT_GEN
|
||||||
cert->subjectSN = 0;
|
cert->subjectSN = 0;
|
||||||
cert->subjectSNLen = 0;
|
cert->subjectSNLen = 0;
|
||||||
@ -1970,6 +1971,78 @@ int ParseCert(DecodedCert* cert, int type, int verify,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If extension CA basic constraint is turned on, flag it, not error if not */
|
||||||
|
static void IsCa(DecodedCert* cert)
|
||||||
|
{
|
||||||
|
if (cert->extensions) {
|
||||||
|
byte b;
|
||||||
|
int length;
|
||||||
|
word32 maxExtensionsIdx;
|
||||||
|
|
||||||
|
cert->srcIdx = cert->extensionsIdx;
|
||||||
|
b = cert->source[cert->srcIdx++];
|
||||||
|
if (b != ASN_EXTENSIONS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GetLength(cert->source, &cert->srcIdx, &length,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GetSequence(cert->source, &cert->srcIdx, &length,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
maxExtensionsIdx = cert->srcIdx + length;
|
||||||
|
|
||||||
|
while (cert->srcIdx < maxExtensionsIdx) {
|
||||||
|
word32 oid;
|
||||||
|
word32 startIdx = cert->srcIdx;
|
||||||
|
word32 tmpIdx;
|
||||||
|
|
||||||
|
if (GetSequence(cert->source, &cert->srcIdx, &length,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tmpIdx = cert->srcIdx;
|
||||||
|
cert->srcIdx = startIdx;
|
||||||
|
|
||||||
|
if (GetAlgoId(cert->source, &cert->srcIdx, &oid,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (oid == BASIC_CA_OID) {
|
||||||
|
b = cert->source[cert->srcIdx++];
|
||||||
|
if (b != ASN_OCTET_STRING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GetLength(cert->source, &cert->srcIdx, &length,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GetSequence(cert->source, &cert->srcIdx, &length,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
b = cert->source[cert->srcIdx++];
|
||||||
|
if (b != ASN_BOOLEAN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GetLength(cert->source, &cert->srcIdx, &length,
|
||||||
|
cert->maxIdx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
b = cert->source[cert->srcIdx++];
|
||||||
|
if (b)
|
||||||
|
cert->isCA = 1;
|
||||||
|
|
||||||
|
return; /* we're done checking */
|
||||||
|
}
|
||||||
|
cert->srcIdx = tmpIdx + length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* from SSL proper, for locking can't do find here anymore */
|
/* from SSL proper, for locking can't do find here anymore */
|
||||||
CYASSL_LOCAL Signer* GetCA(Signer* signers, byte* hash);
|
CYASSL_LOCAL Signer* GetCA(Signer* signers, byte* hash);
|
||||||
|
|
||||||
@ -1995,6 +2068,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify,
|
|||||||
cert->extensionsSz = cert->sigIndex - cert->srcIdx;
|
cert->extensionsSz = cert->sigIndex - cert->srcIdx;
|
||||||
cert->extensionsIdx = cert->srcIdx; /* for potential later use */
|
cert->extensionsIdx = cert->srcIdx; /* for potential later use */
|
||||||
}
|
}
|
||||||
|
IsCa(cert); /* turn on ca flag if there */
|
||||||
/* advance past extensions */
|
/* advance past extensions */
|
||||||
cert->srcIdx = cert->sigIndex;
|
cert->srcIdx = cert->sigIndex;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ enum {
|
|||||||
|
|
||||||
/* ASN Tags */
|
/* ASN Tags */
|
||||||
enum ASN_Tags {
|
enum ASN_Tags {
|
||||||
|
ASN_BOOLEAN = 0x01,
|
||||||
ASN_INTEGER = 0x02,
|
ASN_INTEGER = 0x02,
|
||||||
ASN_BIT_STRING = 0x03,
|
ASN_BIT_STRING = 0x03,
|
||||||
ASN_OCTET_STRING = 0x04,
|
ASN_OCTET_STRING = 0x04,
|
||||||
@ -167,6 +168,7 @@ enum KDF_Sum {
|
|||||||
|
|
||||||
|
|
||||||
enum Extensions_Sum {
|
enum Extensions_Sum {
|
||||||
|
BASIC_CA_OID = 133,
|
||||||
ALT_NAMES_OID = 131
|
ALT_NAMES_OID = 131
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -207,6 +209,7 @@ struct DecodedCert {
|
|||||||
byte* extensions; /* not owned, points into raw cert */
|
byte* extensions; /* not owned, points into raw cert */
|
||||||
int extensionsSz; /* length of cert extensions */
|
int extensionsSz; /* length of cert extensions */
|
||||||
word32 extensionsIdx; /* if want to go back and parse later */
|
word32 extensionsIdx; /* if want to go back and parse later */
|
||||||
|
byte isCA; /* CA basic constraint true */
|
||||||
#ifdef CYASSL_CERT_GEN
|
#ifdef CYASSL_CERT_GEN
|
||||||
/* easy access to subject info for other sign */
|
/* easy access to subject info for other sign */
|
||||||
char* subjectSN;
|
char* subjectSN;
|
||||||
|
@ -617,7 +617,7 @@ int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
CYASSL_LOCAL
|
CYASSL_LOCAL
|
||||||
int AddCA(CYASSL_CTX* ctx, buffer der);
|
int AddCA(CYASSL_CTX* ctx, buffer der);
|
||||||
CYASSL_LOCAL
|
CYASSL_LOCAL
|
||||||
int IsCA(CYASSL_CTX* ctx, byte* hash);
|
int AlreadySigner(CYASSL_CTX* ctx, byte* hash);
|
||||||
|
|
||||||
/* All cipher suite related info */
|
/* All cipher suite related info */
|
||||||
typedef struct CipherSpecs {
|
typedef struct CipherSpecs {
|
||||||
|
@ -1511,7 +1511,11 @@ 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->caList);
|
||||||
if (ret == 0 && !IsCA(ssl->ctx, dCert.subjectHash)) {
|
if (ret == 0 && dCert.isCA == 0) {
|
||||||
|
CYASSL_MSG("Chain cert is not a CA, not adding as one");
|
||||||
|
(void)ret;
|
||||||
|
}
|
||||||
|
else if (ret == 0 && !AlreadySigner(ssl->ctx, 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,
|
||||||
|
10
src/ssl.c
10
src/ssl.c
@ -367,8 +367,8 @@ int CyaSSL_pending(CYASSL* ssl)
|
|||||||
|
|
||||||
static CyaSSL_Mutex ca_mutex; /* CA signers mutex */
|
static CyaSSL_Mutex ca_mutex; /* CA signers mutex */
|
||||||
|
|
||||||
/* does CA already exist on list */
|
/* does CA already exist on signer list */
|
||||||
int IsCA(CYASSL_CTX* ctx, byte* hash)
|
int AlreadySigner(CYASSL_CTX* ctx, byte* hash)
|
||||||
{
|
{
|
||||||
Signer* signers;
|
Signer* signers;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -421,7 +421,11 @@ int AddCA(CYASSL_CTX* ctx, buffer der)
|
|||||||
ret = ParseCert(&cert, CA_TYPE, ctx->verifyPeer, 0);
|
ret = ParseCert(&cert, CA_TYPE, ctx->verifyPeer, 0);
|
||||||
CYASSL_MSG(" Parsed new CA");
|
CYASSL_MSG(" Parsed new CA");
|
||||||
|
|
||||||
if (ret == 0 && IsCA(ctx, cert.subjectHash)) {
|
if (ret == 0 && cert.isCA == 0) {
|
||||||
|
CYASSL_MSG(" Can't add as CA if not actually one");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
else if (ret == 0 && AlreadySigner(ctx, cert.subjectHash)) {
|
||||||
CYASSL_MSG(" Already have this CA, not adding again");
|
CYASSL_MSG(" Already have this CA, not adding again");
|
||||||
(void)ret;
|
(void)ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user