crl stage 2

This commit is contained in:
toddouska
2012-05-16 17:04:56 -07:00
parent 32095795f2
commit 3ec2b9dbbc
16 changed files with 881 additions and 50 deletions

View File

@@ -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 */