mirror of https://github.com/wolfSSL/wolfssl.git
X.509 with unsupported critical extensions should be rejected
parent
6f55549fed
commit
92c31d81f9
|
@ -2800,7 +2800,7 @@ static int ConfirmSignature(const byte* buf, word32 bufSz,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
@ -2809,7 +2809,7 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) {
|
if (GetSequence(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tBad Sequence");
|
CYASSL_MSG("\tBad Sequence");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
|
@ -2826,7 +2826,7 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: str length");
|
CYASSL_MSG("\tfail: str length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
length -= (idx - lenStartIdx);
|
length -= (idx - lenStartIdx);
|
||||||
|
|
||||||
|
@ -2834,7 +2834,7 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
DYNAMIC_TYPE_ALTNAME);
|
DYNAMIC_TYPE_ALTNAME);
|
||||||
if (dnsEntry == NULL) {
|
if (dnsEntry == NULL) {
|
||||||
CYASSL_MSG("\tOut of Memory");
|
CYASSL_MSG("\tOut of Memory");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
|
dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
|
||||||
|
@ -2842,7 +2842,7 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
if (dnsEntry->name == NULL) {
|
if (dnsEntry->name == NULL) {
|
||||||
CYASSL_MSG("\tOut of Memory");
|
CYASSL_MSG("\tOut of Memory");
|
||||||
XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
|
XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(dnsEntry->name, &input[idx], strLen);
|
XMEMCPY(dnsEntry->name, &input[idx], strLen);
|
||||||
|
@ -2863,50 +2863,50 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: other name length");
|
CYASSL_MSG("\tfail: other name length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
/* Consume the rest of this sequence. */
|
/* Consume the rest of this sequence. */
|
||||||
length -= (strLen + idx - lenStartIdx);
|
length -= (strLen + idx - lenStartIdx);
|
||||||
|
|
||||||
if (GetObjectId(input, &idx, &oid, sz) < 0) {
|
if (GetObjectId(input, &idx, &oid, sz) < 0) {
|
||||||
CYASSL_MSG("\tbad OID");
|
CYASSL_MSG("\tbad OID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oid != HW_NAME_OID) {
|
if (oid != HW_NAME_OID) {
|
||||||
CYASSL_MSG("\tincorrect OID");
|
CYASSL_MSG("\tincorrect OID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
|
if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
|
||||||
CYASSL_MSG("\twrong type");
|
CYASSL_MSG("\twrong type");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: str len");
|
CYASSL_MSG("\tfail: str len");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSequence(input, &idx, &strLen, sz) < 0) {
|
if (GetSequence(input, &idx, &strLen, sz) < 0) {
|
||||||
CYASSL_MSG("\tBad Sequence");
|
CYASSL_MSG("\tBad Sequence");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[idx++] != ASN_OBJECT_ID) {
|
if (input[idx++] != ASN_OBJECT_ID) {
|
||||||
CYASSL_MSG("\texpected OID");
|
CYASSL_MSG("\texpected OID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
CYASSL_MSG("\tfailed: str len");
|
CYASSL_MSG("\tfailed: str len");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0);
|
cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0);
|
||||||
if (cert->hwType == NULL) {
|
if (cert->hwType == NULL) {
|
||||||
CYASSL_MSG("\tOut of Memory");
|
CYASSL_MSG("\tOut of Memory");
|
||||||
return;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(cert->hwType, &input[idx], strLen);
|
XMEMCPY(cert->hwType, &input[idx], strLen);
|
||||||
|
@ -2915,18 +2915,18 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (input[idx++] != ASN_OCTET_STRING) {
|
if (input[idx++] != ASN_OCTET_STRING) {
|
||||||
CYASSL_MSG("\texpected Octet String");
|
CYASSL_MSG("\texpected Octet String");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
CYASSL_MSG("\tfailed: str len");
|
CYASSL_MSG("\tfailed: str len");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0);
|
cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0);
|
||||||
if (cert->hwSerialNum == NULL) {
|
if (cert->hwSerialNum == NULL) {
|
||||||
CYASSL_MSG("\tOut of Memory");
|
CYASSL_MSG("\tOut of Memory");
|
||||||
return;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
|
XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
|
||||||
|
@ -2937,34 +2937,38 @@ static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
#endif /* CYASSL_SEP */
|
#endif /* CYASSL_SEP */
|
||||||
else {
|
else {
|
||||||
CYASSL_MSG("\tNot DNS type");
|
CYASSL_MSG("\tNot DNS type");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
|
static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
|
||||||
CYASSL_ENTER("DecodeBasicCaConstraint");
|
CYASSL_ENTER("DecodeBasicCaConstraint");
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) return;
|
if (GetSequence(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (length == 0) return;
|
|
||||||
/* If the basic ca constraint is false, this extension may be named, but
|
/* If the basic ca constraint is false, this extension may be named, but
|
||||||
* left empty. So, if the length is 0, just return. */
|
* left empty. So, if the length is 0, just return. */
|
||||||
|
|
||||||
if (input[idx++] != ASN_BOOLEAN)
|
if (input[idx++] != ASN_BOOLEAN)
|
||||||
{
|
{
|
||||||
CYASSL_MSG("\tfail: constraint not BOOLEAN");
|
CYASSL_MSG("\tfail: constraint not BOOLEAN");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0)
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
{
|
{
|
||||||
CYASSL_MSG("\tfail: length");
|
CYASSL_MSG("\tfail: length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[idx++])
|
if (input[idx++])
|
||||||
|
@ -2973,22 +2977,24 @@ static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
/* If there isn't any more data, return. */
|
/* If there isn't any more data, return. */
|
||||||
if (idx >= (word32)sz)
|
if (idx >= (word32)sz)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
/* Anything left should be the optional pathlength */
|
/* Anything left should be the optional pathlength */
|
||||||
if (input[idx++] != ASN_INTEGER) {
|
if (input[idx++] != ASN_INTEGER) {
|
||||||
CYASSL_MSG("\tfail: pathlen not INTEGER");
|
CYASSL_MSG("\tfail: pathlen not INTEGER");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[idx++] != 1) {
|
if (input[idx++] != 1) {
|
||||||
CYASSL_MSG("\tfail: pathlen too long");
|
CYASSL_MSG("\tfail: pathlen too long");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
cert->pathLength = input[idx];
|
cert->pathLength = input[idx];
|
||||||
cert->extBasicConstPlSet = 1;
|
cert->extBasicConstPlSet = 1;
|
||||||
#endif /* OPENSSL_EXTRA */
|
#endif /* OPENSSL_EXTRA */
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2997,7 +3003,7 @@ static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
|
||||||
#define GENERALNAME_URI 6
|
#define GENERALNAME_URI 6
|
||||||
/* From RFC3280 SS4.2.1.7, GeneralName */
|
/* From RFC3280 SS4.2.1.7, GeneralName */
|
||||||
|
|
||||||
static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
@ -3005,10 +3011,12 @@ static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
||||||
CYASSL_ENTER("DecodeCrlDist");
|
CYASSL_ENTER("DecodeCrlDist");
|
||||||
|
|
||||||
/* Unwrap the list of Distribution Points*/
|
/* Unwrap the list of Distribution Points*/
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) return;
|
if (GetSequence(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Unwrap a single Distribution Point */
|
/* Unwrap a single Distribution Point */
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) return;
|
if (GetSequence(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* The Distribution Point has three explicit optional members
|
/* The Distribution Point has three explicit optional members
|
||||||
* First check for a DistributionPointName
|
* First check for a DistributionPointName
|
||||||
|
@ -3016,18 +3024,21 @@ static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
||||||
if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (input[idx] ==
|
if (input[idx] ==
|
||||||
(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
|
(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
|
if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
cert->extCrlInfoSz = length;
|
cert->extCrlInfoSz = length;
|
||||||
cert->extCrlInfo = input + idx;
|
cert->extCrlInfo = input + idx;
|
||||||
|
@ -3047,7 +3058,8 @@ static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
||||||
input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
|
input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
idx += length;
|
idx += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3056,7 +3068,8 @@ static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
||||||
input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
|
input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
idx += length;
|
idx += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3066,11 +3079,11 @@ static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
|
||||||
"but we only use the first one.");
|
"but we only use the first one.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
|
static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
|
||||||
/*
|
/*
|
||||||
* Read the first of the Authority Information Access records. If there are
|
* Read the first of the Authority Information Access records. If there are
|
||||||
* any issues, return without saving the record.
|
* any issues, return without saving the record.
|
||||||
|
@ -3084,18 +3097,22 @@ static void DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
|
||||||
CYASSL_ENTER("DecodeAuthInfo");
|
CYASSL_ENTER("DecodeAuthInfo");
|
||||||
|
|
||||||
/* Unwrap the list of AIAs */
|
/* Unwrap the list of AIAs */
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) return;
|
if (GetSequence(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
while (idx < (word32)sz) {
|
while (idx < (word32)sz) {
|
||||||
/* Unwrap a single AIA */
|
/* Unwrap a single AIA */
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) return;
|
if (GetSequence(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
oid = 0;
|
oid = 0;
|
||||||
if (GetObjectId(input, &idx, &oid, sz) < 0) return;
|
if (GetObjectId(input, &idx, &oid, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Only supporting URIs right now. */
|
/* Only supporting URIs right now. */
|
||||||
b = input[idx++];
|
b = input[idx++];
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
|
if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
|
||||||
oid == AIA_OCSP_OID)
|
oid == AIA_OCSP_OID)
|
||||||
|
@ -3107,11 +3124,11 @@ static void DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
|
||||||
idx += length;
|
idx += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
|
static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
@ -3120,17 +3137,17 @@ static void DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) {
|
if (GetSequence(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: should be a SEQUENCE\n");
|
CYASSL_MSG("\tfail: should be a SEQUENCE\n");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
|
if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
|
||||||
CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n");
|
CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) {
|
if (GetLength(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: extension data length");
|
CYASSL_MSG("\tfail: extension data length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
|
@ -3148,11 +3165,11 @@ static void DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
ShaFinal(&sha, cert->extAuthKeyId);
|
ShaFinal(&sha, cert->extAuthKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
@ -3161,12 +3178,12 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (input[idx++] != ASN_OCTET_STRING) {
|
if (input[idx++] != ASN_OCTET_STRING) {
|
||||||
CYASSL_MSG("\tfail: should be an OCTET STRING");
|
CYASSL_MSG("\tfail: should be an OCTET STRING");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) {
|
if (GetLength(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: extension data length");
|
CYASSL_MSG("\tfail: extension data length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
|
@ -3184,12 +3201,12 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
ShaFinal(&sha, cert->extSubjKeyId);
|
ShaFinal(&sha, cert->extSubjKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
static void DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
|
static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length;
|
int length;
|
||||||
|
@ -3198,12 +3215,12 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
|
|
||||||
if (input[idx++] != ASN_BIT_STRING) {
|
if (input[idx++] != ASN_BIT_STRING) {
|
||||||
CYASSL_MSG("\tfail: key usage expected bit string");
|
CYASSL_MSG("\tfail: key usage expected bit string");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) {
|
if (GetLength(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: key usage bad length");
|
CYASSL_MSG("\tfail: key usage bad length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
unusedBits = input[idx++];
|
unusedBits = input[idx++];
|
||||||
|
@ -3216,13 +3233,13 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
else if (length == 1)
|
else if (length == 1)
|
||||||
cert->extKeyUsage = (word16)(input[idx] << 1);
|
cert->extKeyUsage = (word16)(input[idx] << 1);
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* OPENSSL_EXTRA */
|
#endif /* OPENSSL_EXTRA */
|
||||||
|
|
||||||
|
|
||||||
#ifdef CYASSL_SEP
|
#ifdef CYASSL_SEP
|
||||||
static void DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
|
static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
@ -3232,40 +3249,41 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
/* Unwrap certificatePolicies */
|
/* Unwrap certificatePolicies */
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) {
|
if (GetSequence(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tdeviceType isn't OID");
|
CYASSL_MSG("\tdeviceType isn't OID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) {
|
if (GetSequence(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tdeviceType isn't OID");
|
CYASSL_MSG("\tdeviceType isn't OID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input[idx++] != ASN_OBJECT_ID) {
|
if (input[idx++] != ASN_OBJECT_ID) {
|
||||||
CYASSL_MSG("\tdeviceType isn't OID");
|
CYASSL_MSG("\tdeviceType isn't OID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) {
|
if (GetLength(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tCouldn't read length of deviceType");
|
CYASSL_MSG("\tCouldn't read length of deviceType");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0);
|
cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0);
|
||||||
if (cert->deviceType == NULL) {
|
if (cert->deviceType == NULL) {
|
||||||
CYASSL_MSG("\tCouldn't alloc memory for deviceType");
|
CYASSL_MSG("\tCouldn't alloc memory for deviceType");
|
||||||
return;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
cert->deviceTypeSz = length;
|
cert->deviceTypeSz = length;
|
||||||
XMEMCPY(cert->deviceType, input + idx, length);
|
XMEMCPY(cert->deviceType, input + idx, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
CYASSL_LEAVE("DecodeCertPolicy", 0);
|
CYASSL_LEAVE("DecodeCertPolicy", 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CYASSL_SEP */
|
#endif /* CYASSL_SEP */
|
||||||
|
|
||||||
|
|
||||||
static void DecodeCertExtensions(DecodedCert* cert)
|
static int DecodeCertExtensions(DecodedCert* cert)
|
||||||
/*
|
/*
|
||||||
* Processing the Certificate Extensions. This does not modify the current
|
* Processing the Certificate Extensions. This does not modify the current
|
||||||
* index. It is works starting with the recorded extensions pointer.
|
* index. It is works starting with the recorded extensions pointer.
|
||||||
|
@ -3277,27 +3295,32 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
int length;
|
int length;
|
||||||
word32 oid;
|
word32 oid;
|
||||||
byte critical = 0;
|
byte critical = 0;
|
||||||
|
byte criticalFail = 0;
|
||||||
|
|
||||||
CYASSL_ENTER("DecodeCertExtensions");
|
CYASSL_ENTER("DecodeCertExtensions");
|
||||||
|
|
||||||
if (input == NULL || sz == 0) return;
|
if (input == NULL || sz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (input[idx++] != ASN_EXTENSIONS) return;
|
if (input[idx++] != ASN_EXTENSIONS)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) return;
|
if (GetLength(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) return;
|
if (GetSequence(input, &idx, &length, sz) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
while (idx < (word32)sz) {
|
while (idx < (word32)sz) {
|
||||||
if (GetSequence(input, &idx, &length, sz) < 0) {
|
if (GetSequence(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: should be a SEQUENCE");
|
CYASSL_MSG("\tfail: should be a SEQUENCE");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
oid = 0;
|
oid = 0;
|
||||||
if (GetObjectId(input, &idx, &oid, sz) < 0) {
|
if (GetObjectId(input, &idx, &oid, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: OBJECT ID");
|
CYASSL_MSG("\tfail: OBJECT ID");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for critical flag */
|
/* check for critical flag */
|
||||||
|
@ -3307,7 +3330,7 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
idx++;
|
idx++;
|
||||||
if (GetLength(input, &idx, &boolLength, sz) < 0) {
|
if (GetLength(input, &idx, &boolLength, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: critical boolean length");
|
CYASSL_MSG("\tfail: critical boolean length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
if (input[idx++])
|
if (input[idx++])
|
||||||
critical = 1;
|
critical = 1;
|
||||||
|
@ -3316,12 +3339,12 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
/* process the extension based on the OID */
|
/* process the extension based on the OID */
|
||||||
if (input[idx++] != ASN_OCTET_STRING) {
|
if (input[idx++] != ASN_OCTET_STRING) {
|
||||||
CYASSL_MSG("\tfail: should be an OCTET STRING");
|
CYASSL_MSG("\tfail: should be an OCTET STRING");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLength(input, &idx, &length, sz) < 0) {
|
if (GetLength(input, &idx, &length, sz) < 0) {
|
||||||
CYASSL_MSG("\tfail: extension data length");
|
CYASSL_MSG("\tfail: extension data length");
|
||||||
return;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (oid) {
|
switch (oid) {
|
||||||
|
@ -3330,15 +3353,18 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
cert->extBasicConstSet = 1;
|
cert->extBasicConstSet = 1;
|
||||||
cert->extBasicConstCrit = critical;
|
cert->extBasicConstCrit = critical;
|
||||||
#endif
|
#endif
|
||||||
DecodeBasicCaConstraint(&input[idx], length, cert);
|
if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CRL_DIST_OID:
|
case CRL_DIST_OID:
|
||||||
DecodeCrlDist(&input[idx], length, cert);
|
if (DecodeCrlDist(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUTH_INFO_OID:
|
case AUTH_INFO_OID:
|
||||||
DecodeAuthInfo(&input[idx], length, cert);
|
if (DecodeAuthInfo(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALT_NAMES_OID:
|
case ALT_NAMES_OID:
|
||||||
|
@ -3346,7 +3372,8 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
cert->extSubjAltNameSet = 1;
|
cert->extSubjAltNameSet = 1;
|
||||||
cert->extSubjAltNameCrit = critical;
|
cert->extSubjAltNameCrit = critical;
|
||||||
#endif
|
#endif
|
||||||
DecodeAltNames(&input[idx], length, cert);
|
if (DecodeAltNames(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUTH_KEY_OID:
|
case AUTH_KEY_OID:
|
||||||
|
@ -3354,7 +3381,8 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
cert->extAuthKeyIdCrit = critical;
|
cert->extAuthKeyIdCrit = critical;
|
||||||
#endif
|
#endif
|
||||||
DecodeAuthKeyId(&input[idx], length, cert);
|
if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBJ_KEY_OID:
|
case SUBJ_KEY_OID:
|
||||||
|
@ -3362,7 +3390,8 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
cert->extSubjKeyIdCrit = critical;
|
cert->extSubjKeyIdCrit = critical;
|
||||||
#endif
|
#endif
|
||||||
DecodeSubjKeyId(&input[idx], length, cert);
|
if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef CYASSL_SEP
|
#ifdef CYASSL_SEP
|
||||||
|
@ -3371,7 +3400,8 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
cert->extCertPolicySet = 1;
|
cert->extCertPolicySet = 1;
|
||||||
cert->extCertPolicyCrit = critical;
|
cert->extCertPolicyCrit = critical;
|
||||||
#endif
|
#endif
|
||||||
DecodeCertPolicy(&input[idx], length, cert);
|
if (DecodeCertPolicy(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3379,19 +3409,24 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
case KEY_USAGE_OID:
|
case KEY_USAGE_OID:
|
||||||
cert->extKeyUsageSet = 1;
|
cert->extKeyUsageSet = 1;
|
||||||
cert->extKeyUsageCrit = critical;
|
cert->extKeyUsageCrit = critical;
|
||||||
DecodeKeyUsage(&input[idx], length, cert);
|
if (DecodeKeyUsage(&input[idx], length, cert) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CYASSL_MSG("\tExtension type not handled, skipping");
|
/* While it is a failure to not support critical extensions,
|
||||||
|
* still parse the certificate ignoring the unsupported
|
||||||
|
* extention to allow caller to accept it with the verify
|
||||||
|
* callback. */
|
||||||
|
if (critical)
|
||||||
|
criticalFail = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
idx += length;
|
idx += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
CYASSL_LEAVE("DecodeCertExtensions", 0);
|
return criticalFail ? ASN_CRIT_EXT_E : 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3447,7 +3482,8 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
{
|
{
|
||||||
word32 confirmOID;
|
word32 confirmOID;
|
||||||
int ret;
|
int ret;
|
||||||
int badDate = 0;
|
int badDate = 0;
|
||||||
|
int criticalExt = 0;
|
||||||
|
|
||||||
if ((ret = DecodeToKey(cert, verify)) < 0) {
|
if ((ret = DecodeToKey(cert, verify)) < 0) {
|
||||||
if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
|
if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
|
||||||
|
@ -3465,7 +3501,13 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
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 */
|
||||||
}
|
}
|
||||||
DecodeCertExtensions(cert);
|
if ((ret = DecodeCertExtensions(cert)) < 0) {
|
||||||
|
if (ret == ASN_CRIT_EXT_E)
|
||||||
|
criticalExt = ret;
|
||||||
|
else
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* advance past extensions */
|
/* advance past extensions */
|
||||||
cert->srcIdx = cert->sigIndex;
|
cert->srcIdx = cert->sigIndex;
|
||||||
}
|
}
|
||||||
|
@ -3532,6 +3574,9 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
if (badDate != 0)
|
if (badDate != 0)
|
||||||
return badDate;
|
return badDate;
|
||||||
|
|
||||||
|
if (criticalExt != 0)
|
||||||
|
return criticalExt;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ enum {
|
||||||
ASN_SIG_KEY_E = -157, /* ASN sig error, unsupported key type */
|
ASN_SIG_KEY_E = -157, /* ASN sig error, unsupported key type */
|
||||||
ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */
|
ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */
|
||||||
ASN_NTRU_KEY_E = -159, /* ASN ntru key decode error, invalid input */
|
ASN_NTRU_KEY_E = -159, /* ASN ntru key decode error, invalid input */
|
||||||
|
ASN_CRIT_EXT_E = -160, /* ASN unsupported critical extension */
|
||||||
|
|
||||||
ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */
|
ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */
|
||||||
ASN_ECC_KEY_E = -171, /* ASN ECC bad input */
|
ASN_ECC_KEY_E = -171, /* ASN ECC bad input */
|
||||||
|
|
Loading…
Reference in New Issue