forked from wolfSSL/wolfssl
crl stage 2
This commit is contained in:
@@ -355,6 +355,8 @@ static int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
CYASSL_ENTER("GetMyVersion");
|
||||
|
||||
if (input[idx++] != ASN_INTEGER)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
@@ -398,6 +400,7 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
CYASSL_ENTER("GetExplicitVersion");
|
||||
if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
|
||||
*inOutIdx = ++idx; /* eat header */
|
||||
return GetMyVersion(input, inOutIdx, version);
|
||||
@@ -446,7 +449,9 @@ static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
|
||||
word32 i = *inOutIdx;
|
||||
byte b;
|
||||
*oid = 0;
|
||||
|
||||
|
||||
CYASSL_ENTER("GetAlgoId");
|
||||
|
||||
if (GetSequence(input, &i, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
@@ -1250,8 +1255,6 @@ static int GetName(DecodedCert* cert, int nameType)
|
||||
char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
|
||||
word32 idx = 0;
|
||||
|
||||
InitSha(&sha);
|
||||
|
||||
if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
|
||||
CYASSL_MSG("Trying optional prefix...");
|
||||
|
||||
@@ -1265,6 +1268,13 @@ static int GetName(DecodedCert* cert, int nameType)
|
||||
if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, &cert->source[cert->srcIdx], length);
|
||||
if (nameType == ISSUER)
|
||||
ShaFinal(&sha, cert->issuerHash);
|
||||
else
|
||||
ShaFinal(&sha, cert->subjectHash);
|
||||
|
||||
length += cert->srcIdx;
|
||||
|
||||
while (cert->srcIdx < (word32)length) {
|
||||
@@ -1395,7 +1405,6 @@ static int GetName(DecodedCert* cert, int nameType)
|
||||
idx += strLen;
|
||||
}
|
||||
|
||||
ShaUpdate(&sha, &cert->source[cert->srcIdx], strLen);
|
||||
cert->srcIdx += strLen;
|
||||
}
|
||||
else {
|
||||
@@ -1450,11 +1459,6 @@ static int GetName(DecodedCert* cert, int nameType)
|
||||
}
|
||||
full[idx++] = 0;
|
||||
|
||||
if (nameType == ISSUER)
|
||||
ShaFinal(&sha, cert->issuerHash);
|
||||
else
|
||||
ShaFinal(&sha, cert->subjectHash);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4169,3 +4173,257 @@ int EncodeOcspRequest(DecodedCert* cert, byte* output, word32 outputSz)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CRL
|
||||
|
||||
/* initialize decoded CRL */
|
||||
void InitDecodedCRL(DecodedCRL* dcrl)
|
||||
{
|
||||
CYASSL_MSG("InitDecodedCRL");
|
||||
|
||||
dcrl->certBegin = 0;
|
||||
dcrl->sigIndex = 0;
|
||||
dcrl->sigLength = 0;
|
||||
dcrl->signatureOID = 0;
|
||||
dcrl->certs = NULL;
|
||||
dcrl->totalCerts = 0;
|
||||
}
|
||||
|
||||
|
||||
/* free decoded CRL resources */
|
||||
void FreeDecodedCRL(DecodedCRL* dcrl)
|
||||
{
|
||||
RevokedCert* tmp = dcrl->certs;
|
||||
|
||||
CYASSL_MSG("FreeDecodedCRL");
|
||||
|
||||
while(tmp) {
|
||||
RevokedCert* next = tmp->next;
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
|
||||
tmp = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* store SHA1 hash of NAME */
|
||||
static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
|
||||
{
|
||||
Sha sha;
|
||||
int length; /* length of all distinguished names */
|
||||
|
||||
CYASSL_ENTER("GetNameHash");
|
||||
|
||||
if (source[*idx] == ASN_OBJECT_ID) {
|
||||
CYASSL_MSG("Trying optional prefix...");
|
||||
|
||||
if (GetLength(source, idx, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
*idx += length;
|
||||
CYASSL_MSG("Got optional prefix");
|
||||
}
|
||||
|
||||
if (GetSequence(source, idx, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, &source[*idx], length);
|
||||
ShaFinal(&sha, hash);
|
||||
|
||||
*idx += length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Get raw Date only, no processing, 0 on success */
|
||||
static int GetBasicDate(const byte* source, word32* idx, byte* date, int maxIdx)
|
||||
{
|
||||
int length;
|
||||
byte b = source[*idx];
|
||||
|
||||
CYASSL_ENTER("GetBasicDate");
|
||||
|
||||
*idx += 1;
|
||||
if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
|
||||
return ASN_TIME_E;
|
||||
|
||||
if (GetLength(source, idx, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
|
||||
return ASN_DATE_SZ_E;
|
||||
|
||||
XMEMCPY(date, &source[*idx], length);
|
||||
*idx += length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Get Revoked Cert list, 0 on success */
|
||||
static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
|
||||
int maxIdx)
|
||||
{
|
||||
int len;
|
||||
byte b;
|
||||
RevokedCert* rc;
|
||||
|
||||
CYASSL_ENTER("GetRevoked");
|
||||
|
||||
if (GetSequence(buff, idx, &len, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* get serial number */
|
||||
b = buff[*idx];
|
||||
*idx += 1;
|
||||
|
||||
if (b != ASN_INTEGER) {
|
||||
CYASSL_MSG("Expecting Integer");
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (GetLength(buff, idx, &len, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (len > EXTERNAL_SERIAL_SIZE) {
|
||||
CYASSL_MSG("Serial Size too big");
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
rc = XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
|
||||
if (rc == NULL) {
|
||||
CYASSL_MSG("Alloc Revoked Cert failed");
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
XMEMCPY(rc->serialNumber, &buff[*idx], len);
|
||||
rc->serialSz = len;
|
||||
|
||||
/* add to list */
|
||||
rc->next = dcrl->certs;
|
||||
dcrl->certs = rc;
|
||||
dcrl->totalCerts++;
|
||||
|
||||
*idx += len;
|
||||
|
||||
/* get date */
|
||||
b = buff[*idx];
|
||||
*idx += 1;
|
||||
|
||||
if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
|
||||
CYASSL_MSG("Expecting Date");
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (GetLength(buff, idx, &len, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* skip for now */
|
||||
*idx += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Get CRL Signature, 0 on success */
|
||||
static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
|
||||
int maxIdx)
|
||||
{
|
||||
int length;
|
||||
byte b;
|
||||
|
||||
CYASSL_ENTER("GetCRL_Signature");
|
||||
|
||||
b = source[*idx];
|
||||
*idx += 1;
|
||||
if (b != ASN_BIT_STRING)
|
||||
return ASN_BITSTR_E;
|
||||
|
||||
if (GetLength(source, idx, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
dcrl->sigLength = length;
|
||||
|
||||
b = source[*idx];
|
||||
*idx += 1;
|
||||
if (b != 0x00)
|
||||
return ASN_EXPECT_0_E;
|
||||
|
||||
dcrl->sigLength--;
|
||||
dcrl->signature = (byte*)&source[*idx];
|
||||
|
||||
*idx += dcrl->sigLength;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* prase crl buffer into decoded state, 0 on success */
|
||||
int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz)
|
||||
{
|
||||
int version, len;
|
||||
word32 oid, idx = 0;
|
||||
Md5 md5;
|
||||
|
||||
CYASSL_MSG("ParseCRL");
|
||||
|
||||
/* raw crl hash */
|
||||
InitMd5(&md5);
|
||||
Md5Update(&md5, buff, sz);
|
||||
Md5Final(&md5, dcrl->crlHash);
|
||||
|
||||
if (GetSequence(buff, &idx, &len, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
dcrl->certBegin = idx;
|
||||
|
||||
if (GetSequence(buff, &idx, &len, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
dcrl->sigIndex = len + idx;
|
||||
|
||||
/* may have version */
|
||||
if (buff[idx] == ASN_INTEGER) {
|
||||
if (GetMyVersion(buff, &idx, &version) < 0)
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (GetAlgoId(buff, &idx, &oid, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetBasicDate(buff, &idx, dcrl->lastDate, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetBasicDate(buff, &idx, dcrl->nextDate, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
|
||||
if (idx != dcrl->sigIndex) {
|
||||
if (GetSequence(buff, &idx, &len, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
len += idx;
|
||||
|
||||
while (idx < len) {
|
||||
if (GetRevoked(buff, &idx, dcrl, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx != dcrl->sigIndex)
|
||||
idx = dcrl->sigIndex; /* skip extensions */
|
||||
|
||||
if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CRL */
|
||||
|
||||
Reference in New Issue
Block a user