add FASC-N and UUID alt. name support

This commit is contained in:
JacobBarthelmeh
2022-05-22 08:18:36 -07:00
parent 62cb2b4ca9
commit 9e4de4bfc8
3 changed files with 244 additions and 69 deletions

View File

@ -14815,6 +14815,130 @@ enum {
#define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
#endif /* WOLFSSL_ASN_TEMPLATE */
#ifdef WOLFSSL_SEP
/* return 0 on success */
static int DecodeSepHwAltName(DecodedCert* cert, const byte* input,
word32* idxIn, int sz)
{
word32 idx = *idxIn;
int strLen;
int ret;
byte tag;
/* Certificates issued with this OID in the subject alt name are for
* verifying signatures created on a module.
* RFC 4108 Section 5. */
if (cert->hwType != NULL) {
WOLFSSL_MSG("\tAlready seen Hardware Module Name");
return ASN_PARSE_E;
}
if (GetASNTag(input, &idx, &tag, sz) < 0) {
return ASN_PARSE_E;
}
if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
WOLFSSL_MSG("\twrong type");
return ASN_PARSE_E;
}
if (GetLength(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tfail: str len");
return ASN_PARSE_E;
}
if (GetSequence(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tBad Sequence");
return ASN_PARSE_E;
}
ret = GetASNObjectId(input, &idx, &strLen, sz);
if (ret != 0) {
WOLFSSL_MSG("\tbad OID");
return ret;
}
cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
DYNAMIC_TYPE_X509_EXT);
if (cert->hwType == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
XMEMCPY(cert->hwType, &input[idx], strLen);
cert->hwTypeSz = strLen;
idx += strLen;
ret = GetOctetString(input, &idx, &strLen, sz);
if (ret < 0)
return ret;
cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
DYNAMIC_TYPE_X509_EXT);
if (cert->hwSerialNum == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
cert->hwSerialNum[strLen] = '\0';
cert->hwSerialNumSz = strLen;
idx += strLen;
*idxIn = idx;
return 0;
}
#endif /* WOLFSSL_SEP */
#ifdef WOLFSSL_FPKI
/* return 0 on success */
static int DecodeFascNAltName(DecodedCert* cert, const byte* input, word32* idx,
int sz)
{
int ret;
int strLen;
DNS_entry* dnsEntry;
byte tag;
if (GetASNTag(input, idx, &tag, sz) < 0) {
return ASN_PARSE_E;
}
if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
return ASN_PARSE_E;
}
if (GetLength(input, idx, &strLen, sz) < 0)
return ASN_PARSE_E;
ret = GetOctetString(input, idx, &strLen, sz);
if (ret < 0)
return ret;
dnsEntry = AltNameNew(cert->heap);
if (dnsEntry == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
dnsEntry->type = ASN_OTHER_TYPE;
dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
DYNAMIC_TYPE_ALTNAME);
if (dnsEntry->name == NULL) {
WOLFSSL_MSG("\tOut of Memory");
XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
return MEMORY_E;
}
dnsEntry->len = strLen;
XMEMCPY(dnsEntry->name, &input[*idx], strLen);
dnsEntry->name[strLen] = '\0';
dnsEntry->oidSum = FASCN_OID;
AddAltName(cert, dnsEntry);
*idx += strLen;
return 0;
}
#endif /* WOLFSSL_FPKI */
/* Decode subject alternative names extension.
*
* RFC 5280 4.2.1.6. Subject Alternative Name
@ -14931,7 +15055,6 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
dirEntry->len = strLen;
XMEMCPY(dirEntry->name, &input[idx], strLen);
dirEntry->name[strLen] = '\0';
dirEntry->next = cert->altDirNames;
cert->altDirNames = dirEntry;
@ -14990,7 +15113,7 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
return BUFFER_E;
}
#ifndef WOLFSSL_NO_ASN_STRICT
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
/* Verify RFC 5280 Sec 4.2.1.6 rule:
"The name MUST NOT be a relative URI" */
@ -15091,14 +15214,12 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
}
#endif /* WOLFSSL_QT || OPENSSL_ALL */
#endif /* IGNORE_NAME_CONSTRAINTS */
#ifdef WOLFSSL_SEP
else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
{
int strLen;
word32 lenStartIdx = idx;
word32 oid = 0;
int ret;
byte tag;
if (GetLength(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tfail: other name length");
@ -15112,72 +15233,34 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
return ASN_PARSE_E;
}
if (oid != HW_NAME_OID) {
WOLFSSL_MSG("\tincorrect OID");
return ASN_PARSE_E;
}
/* Certificates issued with this OID in the subject alt name are for
* verifying signatures created on a module.
* RFC 4108 Section 5. */
if (cert->hwType != NULL) {
WOLFSSL_MSG("\tAlready seen Hardware Module Name");
return ASN_PARSE_E;
}
if (GetASNTag(input, &idx, &tag, sz) < 0) {
return ASN_PARSE_E;
}
if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
WOLFSSL_MSG("\twrong type");
return ASN_PARSE_E;
}
if (GetLength(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tfail: str len");
return ASN_PARSE_E;
}
if (GetSequence(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tBad Sequence");
return ASN_PARSE_E;
}
ret = GetASNObjectId(input, &idx, &strLen, sz);
if (ret != 0) {
WOLFSSL_MSG("\tbad OID");
/* handle parsing other type alt names */
switch (oid) {
#ifdef WOLFSSL_SEP
case HW_NAME_OID:
ret = DecodeSepHwAltName(cert, input, &idx, sz);
if (ret != 0)
return ret;
}
cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
DYNAMIC_TYPE_X509_EXT);
if (cert->hwType == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
XMEMCPY(cert->hwType, &input[idx], strLen);
cert->hwTypeSz = strLen;
idx += strLen;
ret = GetOctetString(input, &idx, &strLen, sz);
if (ret < 0)
return ret;
cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
DYNAMIC_TYPE_X509_EXT);
if (cert->hwSerialNum == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
cert->hwSerialNum[strLen] = '\0';
cert->hwSerialNumSz = strLen;
idx += strLen;
}
break;
#endif /* WOLFSSL_SEP */
#ifdef WOLFSSL_FPKI
case FASCN_OID:
ret = DecodeFascNAltName(cert, input, &idx, sz);
if (ret != 0)
return ret;
break;
#endif /* WOLFSSL_FPKI */
default:
WOLFSSL_MSG("\tUnsupported other name type, skipping");
if (GetLength(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tfail: unsupported other name length");
return ASN_PARSE_E;
}
length -= (strLen + idx - lenStartIdx);
idx += strLen;
}
(void)ret;
}
else {
int strLen;
word32 lenStartIdx = idx;
@ -20997,6 +21080,88 @@ int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
return ret;
}
#ifdef WOLFSSL_FPKI
/* Search through list for first matching alt name of the same type
* If 'current' is null then the search starts at the head of the list
* otherwise the search starts from the node after 'current' alt name.
* Returns 0 on success
*/
static DNS_entry* wc_GetAltName(struct DecodedCert* cert, int nameType,
DNS_entry* current)
{
DNS_entry* entry;
if (current == NULL) {
entry = cert->altNames;
}
else {
entry = current->next;
}
/* cycle through alt names to check for needed types */
while (entry != NULL) {
if (entry->type == nameType) {
break;
}
entry = entry->next;
}
return entry;
}
/* returns 0 on success */
int wc_GetUUIDFromCert(struct DecodedCert* cert, byte* uuid, word32* uuidSz)
{
int ret = ALT_NAME_E;
DNS_entry* id = NULL;
id = wc_GetAltName(cert, ASN_URI_TYPE, id);
if (id != NULL) {
if (uuid == NULL) {
*uuidSz = id->len;
return LENGTH_ONLY_E;
}
if ((int)*uuidSz < id->len) {
return BUFFER_E;
}
XMEMCPY(uuid, id->name, id->len);
ret = 0; /* success */
}
return ret;
}
/* reutrns 0 on success */
int wc_GetFASCNFromCert(struct DecodedCert* cert, byte* fascn, word32* fascnSz)
{
int ret = ALT_NAME_E;
DNS_entry* id = NULL;
do {
id = wc_GetAltName(cert, ASN_OTHER_TYPE, id);
if (id != NULL && id->oidSum == FASCN_OID) {
if (fascn == NULL) {
*fascnSz = id->len;
return LENGTH_ONLY_E;
}
if ((int)*fascnSz < id->len) {
return BUFFER_E;
}
XMEMCPY(fascn, id->name, id->len);
ret = 0; /* success */
}
} while (id != NULL);
return ret;
}
#endif /* WOLFSSL_FPKI */
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
defined(WOLFSSL_KCAPI_RSA) || \
((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))

View File

@ -1143,8 +1143,9 @@ enum Extensions_Sum {
id-pkix-ocsp-nocheck */
SUBJ_DIR_ATTR_OID = 123, /* 2.5.29.9 */
AKEY_PACKAGE_OID = 1048 /* 2.16.840.1.101.2.1.2.78.5
AKEY_PACKAGE_OID = 1048, /* 2.16.840.1.101.2.1.2.78.5
RFC 5958 - Asymmetric Key Packages */
FASCN_OID = 419 /* 2.16.840.1.101.3.6.6 Federal PKI Policy FASC-N */
};
enum CertificatePolicy_Sum {
@ -1287,6 +1288,9 @@ struct DNS_entry {
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
char* ipString; /* human readable form of IP address */
#endif
#ifdef WOLFSSL_FPKI
int oidSum; /* provid oid sum for verification */
#endif
};

View File

@ -826,6 +826,12 @@ WOLFSSL_API int wc_ParseCert(
WOLFSSL_API int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
byte* derKey, word32* derKeySz);
#ifdef WOLFSSL_FPKI
WOLFSSL_API int wc_GetUUIDFromCert(struct DecodedCert* cert,
byte* uuid, word32* uuidSz);
WOLFSSL_API int wc_GetFASCNFromCert(struct DecodedCert* cert,
byte* fascn, word32* fascnSz);
#endif /* WOLFSSL_FPKI */
#ifdef __cplusplus
} /* extern "C" */
#endif