mirror of https://github.com/wolfSSL/wolfssl
check basic contsraint CA flag before adding as signer even if explicit add
This commit is contained in:
parent
8ddd2185c2
commit
11d15f32b9
|
@ -1017,6 +1017,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
|
|||
cert->extensions = 0;
|
||||
cert->extensionsSz = 0;
|
||||
cert->extensionsIdx = 0;
|
||||
cert->isCA = 0;
|
||||
#ifdef CYASSL_CERT_GEN
|
||||
cert->subjectSN = 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 */
|
||||
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->extensionsIdx = cert->srcIdx; /* for potential later use */
|
||||
}
|
||||
IsCa(cert); /* turn on ca flag if there */
|
||||
/* advance past extensions */
|
||||
cert->srcIdx = cert->sigIndex;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ enum {
|
|||
|
||||
/* ASN Tags */
|
||||
enum ASN_Tags {
|
||||
ASN_BOOLEAN = 0x01,
|
||||
ASN_INTEGER = 0x02,
|
||||
ASN_BIT_STRING = 0x03,
|
||||
ASN_OCTET_STRING = 0x04,
|
||||
|
@ -167,6 +168,7 @@ enum KDF_Sum {
|
|||
|
||||
|
||||
enum Extensions_Sum {
|
||||
BASIC_CA_OID = 133,
|
||||
ALT_NAMES_OID = 131
|
||||
};
|
||||
|
||||
|
@ -207,6 +209,7 @@ struct DecodedCert {
|
|||
byte* extensions; /* not owned, points into raw cert */
|
||||
int extensionsSz; /* length of cert extensions */
|
||||
word32 extensionsIdx; /* if want to go back and parse later */
|
||||
byte isCA; /* CA basic constraint true */
|
||||
#ifdef CYASSL_CERT_GEN
|
||||
/* easy access to subject info for other sign */
|
||||
char* subjectSN;
|
||||
|
|
|
@ -617,7 +617,7 @@ int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
|||
CYASSL_LOCAL
|
||||
int AddCA(CYASSL_CTX* ctx, buffer der);
|
||||
CYASSL_LOCAL
|
||||
int IsCA(CYASSL_CTX* ctx, byte* hash);
|
||||
int AlreadySigner(CYASSL_CTX* ctx, byte* hash);
|
||||
|
||||
/* All cipher suite related info */
|
||||
typedef struct CipherSpecs {
|
||||
|
|
|
@ -1511,7 +1511,11 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
||||
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
||||
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;
|
||||
add.length = myCert.length;
|
||||
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 */
|
||||
|
||||
/* does CA already exist on list */
|
||||
int IsCA(CYASSL_CTX* ctx, byte* hash)
|
||||
/* does CA already exist on signer list */
|
||||
int AlreadySigner(CYASSL_CTX* ctx, byte* hash)
|
||||
{
|
||||
Signer* signers;
|
||||
int ret = 0;
|
||||
|
@ -421,7 +421,11 @@ int AddCA(CYASSL_CTX* ctx, buffer der)
|
|||
ret = ParseCert(&cert, CA_TYPE, ctx->verifyPeer, 0);
|
||||
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");
|
||||
(void)ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue