forked from wolfSSL/wolfssl
add FASC-N and UUID alt. name support
This commit is contained in:
@ -14815,6 +14815,130 @@ enum {
|
|||||||
#define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
|
#define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
|
||||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
#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.
|
/* Decode subject alternative names extension.
|
||||||
*
|
*
|
||||||
* RFC 5280 4.2.1.6. Subject Alternative Name
|
* 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;
|
dirEntry->len = strLen;
|
||||||
XMEMCPY(dirEntry->name, &input[idx], strLen);
|
XMEMCPY(dirEntry->name, &input[idx], strLen);
|
||||||
dirEntry->name[strLen] = '\0';
|
dirEntry->name[strLen] = '\0';
|
||||||
|
|
||||||
dirEntry->next = cert->altDirNames;
|
dirEntry->next = cert->altDirNames;
|
||||||
cert->altDirNames = dirEntry;
|
cert->altDirNames = dirEntry;
|
||||||
|
|
||||||
@ -14990,7 +15113,7 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
|
|||||||
return BUFFER_E;
|
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:
|
/* Verify RFC 5280 Sec 4.2.1.6 rule:
|
||||||
"The name MUST NOT be a relative URI" */
|
"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 /* WOLFSSL_QT || OPENSSL_ALL */
|
||||||
#endif /* IGNORE_NAME_CONSTRAINTS */
|
#endif /* IGNORE_NAME_CONSTRAINTS */
|
||||||
#ifdef WOLFSSL_SEP
|
|
||||||
else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
|
else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
|
||||||
{
|
{
|
||||||
int strLen;
|
int strLen;
|
||||||
word32 lenStartIdx = idx;
|
word32 lenStartIdx = idx;
|
||||||
word32 oid = 0;
|
word32 oid = 0;
|
||||||
int ret;
|
int ret;
|
||||||
byte tag;
|
|
||||||
|
|
||||||
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
WOLFSSL_MSG("\tfail: other name length");
|
WOLFSSL_MSG("\tfail: other name length");
|
||||||
@ -15112,72 +15233,34 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
|
|||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oid != HW_NAME_OID) {
|
/* handle parsing other type alt names */
|
||||||
WOLFSSL_MSG("\tincorrect OID");
|
switch (oid) {
|
||||||
return ASN_PARSE_E;
|
#ifdef WOLFSSL_SEP
|
||||||
|
case HW_NAME_OID:
|
||||||
|
ret = DecodeSepHwAltName(cert, input, &idx, sz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
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;
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_SEP */
|
|
||||||
else {
|
else {
|
||||||
int strLen;
|
int strLen;
|
||||||
word32 lenStartIdx = idx;
|
word32 lenStartIdx = idx;
|
||||||
@ -20997,6 +21080,88 @@ int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
|
|||||||
return ret;
|
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) || \
|
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
|
||||||
defined(WOLFSSL_KCAPI_RSA) || \
|
defined(WOLFSSL_KCAPI_RSA) || \
|
||||||
((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
|
((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
|
||||||
|
@ -1143,8 +1143,9 @@ enum Extensions_Sum {
|
|||||||
id-pkix-ocsp-nocheck */
|
id-pkix-ocsp-nocheck */
|
||||||
SUBJ_DIR_ATTR_OID = 123, /* 2.5.29.9 */
|
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 */
|
RFC 5958 - Asymmetric Key Packages */
|
||||||
|
FASCN_OID = 419 /* 2.16.840.1.101.3.6.6 Federal PKI Policy FASC-N */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CertificatePolicy_Sum {
|
enum CertificatePolicy_Sum {
|
||||||
@ -1287,6 +1288,9 @@ struct DNS_entry {
|
|||||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
|
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
|
||||||
char* ipString; /* human readable form of IP address */
|
char* ipString; /* human readable form of IP address */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_FPKI
|
||||||
|
int oidSum; /* provid oid sum for verification */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -826,6 +826,12 @@ WOLFSSL_API int wc_ParseCert(
|
|||||||
WOLFSSL_API int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
|
WOLFSSL_API int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
|
||||||
byte* derKey, word32* derKeySz);
|
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
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user