forked from wolfSSL/wolfssl
ASN X509 subject directory attribute: fix ASN template parsing
Support multiple attributes. When Country of Citizenship, pull out PRINTABLE_STRING explicitly. Each type of attribute has a different format.
This commit is contained in:
@ -19302,18 +19302,14 @@ exit:
|
|||||||
* X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
|
* X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
|
||||||
*/
|
*/
|
||||||
static const ASNItem subjDirAttrASN[] = {
|
static const ASNItem subjDirAttrASN[] = {
|
||||||
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
|
||||||
/* SEQ */ { 1, ASN_SEQUENCE, 1, 1, 0 },
|
/* SEQ */ { 1, ASN_SEQUENCE, 1, 1, 0 },
|
||||||
/* OID */ { 2, ASN_OBJECT_ID, 0, 0, 0 },
|
/* OID */ { 2, ASN_OBJECT_ID, 0, 0, 0 },
|
||||||
/* PLEN */ { 2, ASN_SET, 1, 1, 0 },
|
/* PLEN */ { 2, ASN_SET, 1, 0, 0 },
|
||||||
/* BIT_STR */ { 2, ASN_PRINTABLE_STRING, 0, 0, 0 }
|
|
||||||
};
|
};
|
||||||
enum {
|
enum {
|
||||||
SUBJDIRATTRASN_IDX_SEQ = 0,
|
SUBJDIRATTRASN_IDX_SEQ = 0,
|
||||||
SUBJDIRATTRASN_IDX_SEQ2,
|
|
||||||
SUBJDIRATTRASN_IDX_OID,
|
SUBJDIRATTRASN_IDX_OID,
|
||||||
SUBJDIRATTRASN_IDX_SET,
|
SUBJDIRATTRASN_IDX_SET,
|
||||||
SUBJDIRATTRASN_IDX_STRING,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of items in ASN.1 template for BasicContraints. */
|
/* Number of items in ASN.1 template for BasicContraints. */
|
||||||
@ -19394,28 +19390,43 @@ static int DecodeSubjDirAttr(const byte* input, int sz, DecodedCert* cert)
|
|||||||
DECL_ASNGETDATA(dataASN, subjDirAttrASN_Length);
|
DECL_ASNGETDATA(dataASN, subjDirAttrASN_Length);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
|
int length;
|
||||||
|
|
||||||
WOLFSSL_ENTER("DecodeSubjDirAttr");
|
WOLFSSL_ENTER("DecodeSubjDirAttr");
|
||||||
|
|
||||||
CALLOC_ASNGETDATA(dataASN, subjDirAttrASN_Length, ret, cert->heap);
|
CALLOC_ASNGETDATA(dataASN, subjDirAttrASN_Length, ret, cert->heap);
|
||||||
|
|
||||||
if (ret == 0) {
|
/* Strip outer SEQUENCE. */
|
||||||
|
if ((ret == 0) && (GetSequence(input, &idx, &length, sz) < 0)) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
/* Handle each inner SEQUENCE. */
|
||||||
|
while ((ret == 0) && (idx < (word32)sz)) {
|
||||||
ret = GetASN_Items(subjDirAttrASN, dataASN, subjDirAttrASN_Length, 1,
|
ret = GetASN_Items(subjDirAttrASN, dataASN, subjDirAttrASN_Length, 1,
|
||||||
input, &idx, sz);
|
input, &idx, sz);
|
||||||
}
|
|
||||||
|
|
||||||
/* There may be more than one countryOfCitizenship, but save the
|
/* There may be more than one countryOfCitizenship, but save the
|
||||||
* first one for now. */
|
* first one for now. */
|
||||||
if (dataASN[SUBJDIRATTRASN_IDX_OID].data.oid.sum == SDA_COC_OID) {
|
if ((ret == 0) &&
|
||||||
word32 cuLen;
|
(dataASN[SUBJDIRATTRASN_IDX_OID].data.oid.sum == SDA_COC_OID)) {
|
||||||
|
int cuLen;
|
||||||
|
word32 setIdx = 0;
|
||||||
|
byte* setData;
|
||||||
|
word32 setLen;
|
||||||
|
|
||||||
cuLen = dataASN[SUBJDIRATTRASN_IDX_STRING].data.ref.length;
|
GetASN_GetRef(&dataASN[SUBJDIRATTRASN_IDX_SET], &setData, &setLen);
|
||||||
if (cuLen != COUNTRY_CODE_LEN)
|
if (GetASNHeader(setData, ASN_PRINTABLE_STRING, &setIdx, &cuLen,
|
||||||
return ASN_PARSE_E;
|
setLen) < 0) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
XMEMCPY(cert->countryOfCitizenship,
|
}
|
||||||
dataASN[SUBJDIRATTRASN_IDX_STRING].data.ref.data, cuLen);
|
if ((ret == 0) && (cuLen != COUNTRY_CODE_LEN)) {
|
||||||
cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
|
ret = ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
XMEMCPY(cert->countryOfCitizenship, setData + setIdx, cuLen);
|
||||||
|
cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FREE_ASNGETDATA(dataASN, cert->heap);
|
FREE_ASNGETDATA(dataASN, cert->heap);
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user