Merge pull request #336 from dgarske/ASNCertPolicyExtFix

Fixed bug with ASN.1 X509V3 Certificate Policy extension parsing
This commit is contained in:
JacobBarthelmeh
2016-03-08 08:59:24 -07:00

View File

@@ -4596,87 +4596,80 @@ static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */ #endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
/* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert) static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
{ {
word32 idx = 0; word32 idx = 0;
int total_length = 0, length = 0; int total_length = 0, policy_length = 0, length = 0;
WOLFSSL_ENTER("DecodeCertPolicy"); WOLFSSL_ENTER("DecodeCertPolicy");
/* Unwrap certificatePolicies */
if (GetSequence(input, &idx, &total_length, sz) < 0) { if (GetSequence(input, &idx, &total_length, sz) < 0) {
WOLFSSL_MSG("\tdeviceType isn't OID"); WOLFSSL_MSG("\tGet CertPolicy total seq failed");
return ASN_PARSE_E; return ASN_PARSE_E;
} }
if (GetSequence(input, &idx, &length, sz) < 0) { /* Validate total length (2 is the CERT_POLICY_OID+SEQ) */
WOLFSSL_MSG("\tdeviceType isn't OID"); if ((total_length + 2) != sz) {
return ASN_PARSE_E; WOLFSSL_MSG("\tCertPolicy length mismatch");
}
total_length -= (length+1);
if (input[idx++] != ASN_OBJECT_ID) {
WOLFSSL_MSG("\tdeviceType isn't OID");
return ASN_PARSE_E;
}
total_length--;
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tCouldn't read length of deviceType");
return ASN_PARSE_E; return ASN_PARSE_E;
} }
if (length > 0) { /* Unwrap certificatePolicies */
#if defined(WOLFSSL_SEP) do {
cert->deviceType = (byte*)XMALLOC(length, cert->heap, if (GetSequence(input, &idx, &policy_length, sz) < 0) {
DYNAMIC_TYPE_X509_EXT); WOLFSSL_MSG("\tGet CertPolicy seq failed");
if (cert->deviceType == NULL) {
WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
return MEMORY_E;
}
cert->deviceTypeSz = length;
XMEMCPY(cert->deviceType, input + idx, length);
#elif defined(WOLFSSL_CERT_EXT)
/* decode cert policy */
if (DecodePolicyOID(cert->extCertPolicies[0], MAX_CERTPOL_SZ,
input+idx, length) != 0) {
WOLFSSL_MSG("\tCouldn't read Policy OID 1");
return ASN_PARSE_E; return ASN_PARSE_E;
} }
cert->extCertPoliciesNb++;
/* check if we have a second value */ if (input[idx++] != ASN_OBJECT_ID) {
if (total_length) { WOLFSSL_MSG("\tCertPolicy isn't OID");
idx += length; return ASN_PARSE_E;
}
policy_length--;
if (GetSequence(input, &idx, &length, sz) < 0) { if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tdeviceType isn't OID"); WOLFSSL_MSG("\tGet CertPolicy length failed");
return ASN_PARSE_E;
}
policy_length--;
if (length > 0) {
/* Verify length won't overrun buffer */
if (length > (sz - (int)idx)) {
WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
return ASN_PARSE_E; return ASN_PARSE_E;
} }
if (input[idx++] != ASN_OBJECT_ID) { #if defined(WOLFSSL_SEP)
WOLFSSL_MSG("\tdeviceType isn't OID"); cert->deviceType = (byte*)XMALLOC(length, cert->heap,
return ASN_PARSE_E; DYNAMIC_TYPE_X509_EXT);
if (cert->deviceType == NULL) {
WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
return MEMORY_E;
} }
cert->deviceTypeSz = length;
if (GetLength(input, &idx, &length, sz) < 0) { XMEMCPY(cert->deviceType, input + idx, length);
WOLFSSL_MSG("\tCouldn't read length of deviceType"); break;
return ASN_PARSE_E; #elif defined(WOLFSSL_CERT_EXT)
}
/* decode cert policy */ /* decode cert policy */
if (DecodePolicyOID(cert->extCertPolicies[1], MAX_CERTPOL_SZ, if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
input+idx, length) != 0) { input + idx, length) != 0) {
WOLFSSL_MSG("\tCouldn't read Policy OID 2"); WOLFSSL_MSG("\tCouldn't decode CertPolicy");
return ASN_PARSE_E; return ASN_PARSE_E;
} }
cert->extCertPoliciesNb++; cert->extCertPoliciesNb++;
#else
WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
return 0;
#endif
} }
#else idx += policy_length;
WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0); } while((int)idx < total_length
return 0; #if defined(WOLFSSL_CERT_EXT)
#endif && cert->extCertPoliciesNb < MAX_CERTPOL_NB
} #endif
);
WOLFSSL_LEAVE("DecodeCertPolicy", 0); WOLFSSL_LEAVE("DecodeCertPolicy", 0);
return 0; return 0;
@@ -4802,7 +4795,6 @@ static int DecodeCertExtensions(DecodedCert* cert)
break; break;
case CERT_POLICY_OID: case CERT_POLICY_OID:
WOLFSSL_MSG("Certificate Policy extension not supported yet.");
#ifdef WOLFSSL_SEP #ifdef WOLFSSL_SEP
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
cert->extCertPolicySet = 1; cert->extCertPolicySet = 1;
@@ -4810,8 +4802,11 @@ static int DecodeCertExtensions(DecodedCert* cert)
#endif #endif
#endif #endif
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
if (DecodeCertPolicy(&input[idx], length, cert) < 0) if (DecodeCertPolicy(&input[idx], length, cert) < 0) {
return ASN_PARSE_E; return ASN_PARSE_E;
}
#else
WOLFSSL_MSG("Certificate Policy extension not supported yet.");
#endif #endif
break; break;