Add support for more extensions to wolfSSL_X509_print_ex.

- Key usage
- Extended key usage
- Subject alt name

Additionally, print out the criticality of the extensions.
This commit is contained in:
Hayden Roche
2022-04-26 14:28:23 -07:00
parent eb28d38fa8
commit f479600066
2 changed files with 926 additions and 695 deletions

View File

@@ -5195,17 +5195,238 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
#ifndef NO_BIO #ifndef NO_BIO
#ifdef XSNPRINTF /* a snprintf function needs to be available */ static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
/* Writes the human readable form of x509 to bio. {
int ret = WOLFSSL_SUCCESS;
int nameCount = 0;
DNS_entry* entry;
if (bio == NULL || x509 == NULL) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && x509->subjAltNameSet
&& x509->altNames != NULL) {
if (wolfSSL_BIO_write(bio,
" X509v3 Subject Alternative Name: ", 45) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && x509->subjAltNameCrit &&
wolfSSL_BIO_write(bio, "critical", (int)XSTRLEN("critical")) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BIO_write(bio, "\n ", 17) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS) {
entry = x509->altNames;
while (entry != NULL) {
++nameCount;
if (nameCount > 1) {
if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
}
if (entry->type == ASN_DNS_TYPE) {
if (entry->name == NULL) {
WOLFSSL_MSG("NULL DNS alt name.");
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, "DNS:", 4) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, entry->name,
(int)XSTRLEN(entry->name))
<= 0) {
ret = WOLFSSL_FAILURE;
break;
}
}
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
else if (entry->type == ASN_IP_TYPE) {
if (entry->ipString == NULL) {
WOLFSSL_MSG("NULL IP address alt name.");
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, "IP Address:", 11) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, entry->ipString,
(int)XSTRLEN(entry->ipString)) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
}
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
else {
WOLFSSL_MSG("Bad alt name type.");
ret = WOLFSSL_FAILURE;
break;
}
entry = entry->next;
}
}
if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
ret = WOLFSSL_FAILURE;
}
}
return ret;
}
#ifdef XSNPRINTF
static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
{
int ret = WOLFSSL_SUCCESS;
word32 i = 0;
int usageCount = 0;
const int usages[] = {
KEYUSE_DIGITAL_SIG,
KEYUSE_CONTENT_COMMIT,
KEYUSE_KEY_ENCIPHER,
KEYUSE_DATA_ENCIPHER,
KEYUSE_KEY_AGREE,
KEYUSE_KEY_CERT_SIGN,
KEYUSE_CRL_SIGN,
KEYUSE_ENCIPHER_ONLY,
KEYUSE_DECIPHER_ONLY
};
const char* usageStrs[] = {
"Digital Signature",
"Non Repudiation",
"Key Encipherment",
"Data Encipherment",
"Key Agreement",
"Certificate Sign",
"CRL Sign",
"Encipher Only",
"Decipher Only"
};
if (bio == NULL || x509 == NULL) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet
&& x509->keyUsage != 0) {
if (wolfSSL_BIO_write(bio, " X509v3 Key Usage: ", 30) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && x509->keyUsageCrit &&
wolfSSL_BIO_write(bio, "critical", 8) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BIO_write(bio, "\n ", 17) <= 0) {
ret = WOLFSSL_FAILURE;
}
for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
i++) {
if (x509->keyUsage & usages[i]) {
++usageCount;
if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, usageStrs[i],
(int)XSTRLEN(usageStrs[i])) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
}
}
if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
ret = WOLFSSL_FAILURE;
}
}
return ret;
}
static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
{
int ret = WOLFSSL_SUCCESS;
word32 i = 0;
int usageCount = 0;
const int usages[] = {
EXTKEYUSE_OCSP_SIGN,
EXTKEYUSE_TIMESTAMP,
EXTKEYUSE_EMAILPROT,
EXTKEYUSE_CODESIGN,
EXTKEYUSE_CLIENT_AUTH,
EXTKEYUSE_SERVER_AUTH
};
const char* usageStrs[] = {
"OCSP Signing",
"Time Stamping",
"E-mail Protection",
"Code Signing",
"TLS Web Client Authentication",
"TLS Web Server Authentication"
};
if (bio == NULL || x509 == NULL) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0
&& x509->extKeyUsage != 0) {
if (wolfSSL_BIO_write(bio,
" X509v3 Extended Key Usage: ", 39) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCrit &&
wolfSSL_BIO_write(bio, "critical", 8) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BIO_write(bio, "\n ", 17) <= 0) {
ret = WOLFSSL_FAILURE;
}
for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
i++) {
if (x509->extKeyUsage & usages[i]) {
++usageCount;
if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, usageStrs[i],
(int)XSTRLEN(usageStrs[i])) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
}
}
if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
ret = WOLFSSL_FAILURE;
}
}
return ret;
}
/* Writes the human readable form of x509 to bio.
* *
* bio WOLFSSL_BIO to write to. * bio WOLFSSL_BIO to write to.
* x509 Certificate to write. * x509 Certificate to write.
* *
* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
*/ */
int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
unsigned long nmflags, unsigned long cflag) unsigned long nmflags, unsigned long cflag)
{ {
WOLFSSL_ENTER("wolfSSL_X509_print_ex"); WOLFSSL_ENTER("wolfSSL_X509_print_ex");
/* flags currently not supported */ /* flags currently not supported */
@@ -5329,13 +5550,8 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
int issSz = 256; int issSz = 256;
#endif #endif
#if defined(WOLFSSL_QT)
issuer = wolfSSL_X509_get_name_oneline( issuer = wolfSSL_X509_get_name_oneline(
wolfSSL_X509_get_issuer_name(x509), buff, issSz); wolfSSL_X509_get_issuer_name(x509), buff, issSz);
#else
issuer = wolfSSL_X509_NAME_oneline(
wolfSSL_X509_get_issuer_name(x509), buff, issSz);
#endif
if (wolfSSL_BIO_write(bio, " Issuer: ", if (wolfSSL_BIO_write(bio, " Issuer: ",
(int)XSTRLEN(" Issuer: ")) <= 0) { (int)XSTRLEN(" Issuer: ")) <= 0) {
@@ -5360,7 +5576,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
} }
} }
#ifndef NO_ASN_TIME #ifndef NO_ASN_TIME
/* print validity */ /* print validity */
{ {
char tmp[80]; char tmp[80];
@@ -5414,7 +5630,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
} }
#endif #endif
/* print subject */ /* print subject */
{ {
@@ -5427,13 +5643,8 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
int subSz = 256; int subSz = 256;
#endif #endif
#if defined(WOLFSSL_QT)
subject = wolfSSL_X509_get_name_oneline( subject = wolfSSL_X509_get_name_oneline(
wolfSSL_X509_get_subject_name(x509), buff, subSz); wolfSSL_X509_get_subject_name(x509), buff, subSz);
#else
subject = wolfSSL_X509_NAME_oneline(
wolfSSL_X509_get_subject_name(x509), buff, subSz);
#endif
if (wolfSSL_BIO_write(bio, "\n Subject: ", if (wolfSSL_BIO_write(bio, "\n Subject: ",
(int)XSTRLEN("\n Subject: ")) <= 0) { (int)XSTRLEN("\n Subject: ")) <= 0) {
@@ -5809,13 +6020,17 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
char val[5]; char val[5];
int valSz = 5; int valSz = 5;
XSNPRINTF(tmp, sizeof(tmp),
" X509v3 Subject Key Identifier: ");
if (x509->subjKeyIdCrit) {
XSTRNCAT(tmp, "critical", sizeof(tmp) - XSTRLEN(tmp) - 1);
}
XSTRNCAT(tmp, "\n", sizeof(tmp) - XSTRLEN(tmp) - 1);
if (wolfSSL_BIO_write(bio, if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
" X509v3 Subject Key Identifier: \n",
(int)XSTRLEN(" X509v3 Subject Key Identifier: \n"))
<= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XMEMSET(tmp, 0, sizeof(tmp));
XSNPRINTF(tmp, sizeof(tmp) - 1, " "); XSNPRINTF(tmp, sizeof(tmp) - 1, " ");
for (i = 0; i < sizeof(tmp) && i < (x509->subjKeyIdSz - 1); i++) { for (i = 0; i < sizeof(tmp) && i < (x509->subjKeyIdSz - 1); i++) {
@@ -5838,12 +6053,17 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
int valSz = 5; int valSz = 5;
int len = 0; int len = 0;
if (wolfSSL_BIO_write(bio, XSNPRINTF(tmp, sizeof(tmp),
" X509v3 Authority Key Identifier: \n", " X509v3 Authority Key Identifier: ");
(int)XSTRLEN(" X509v3 Authority Key Identifier: \n")) if (x509->authKeyIdCrit) {
<= 0) { XSTRNCAT(tmp, "critical", sizeof(tmp) - XSTRLEN(tmp) - 1);
}
XSTRNCAT(tmp, "\n", sizeof(tmp) - XSTRLEN(tmp) - 1);
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XMEMSET(tmp, 0, sizeof(tmp));
XSNPRINTF(tmp, sizeof(tmp) - 1, " keyid"); XSNPRINTF(tmp, sizeof(tmp) - 1, " keyid");
for (i = 0; i < x509->authKeyIdSz; i++) { for (i = 0; i < x509->authKeyIdSz; i++) {
@@ -5868,12 +6088,18 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
if (x509->basicConstSet) { if (x509->basicConstSet) {
char tmp[100]; char tmp[100];
if (wolfSSL_BIO_write(bio, XSNPRINTF(tmp, sizeof(tmp),
"\n X509v3 Basic Constraints: \n", " X509v3 Basic Constraints: ");
(int)XSTRLEN("\n X509v3 Basic Constraints: \n")) if (x509->basicConstCrit) {
<= 0) { XSTRNCAT(tmp, "critical", sizeof(tmp) - XSTRLEN(tmp) - 1);
}
XSTRNCAT(tmp, "\n", sizeof(tmp) - XSTRLEN(tmp) - 1);
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XMEMSET(tmp, 0, sizeof(tmp));
XSNPRINTF(tmp, sizeof(tmp), XSNPRINTF(tmp, sizeof(tmp),
" CA:%s\n", " CA:%s\n",
(x509->isCa)? "TRUE": "FALSE"); (x509->isCa)? "TRUE": "FALSE");
@@ -5882,6 +6108,10 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
} }
} }
X509PrintSubjAltName(bio, x509);
X509PrintKeyUsage(bio, x509);
X509PrintExtendedKeyUsage(bio, x509);
/* print out signature */ /* print out signature */
if (x509->sig.length > 0) { if (x509->sig.length > 0) {
unsigned char* sig; unsigned char* sig;
@@ -5954,15 +6184,15 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
} }
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }
int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
{ {
return wolfSSL_X509_print_ex(bio, x509, 0, 0); return wolfSSL_X509_print_ex(bio, x509, 0, 0);
} }
#ifndef NO_FILESYSTEM #ifndef NO_FILESYSTEM
int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509) int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
{ {
WOLFSSL_BIO* bio; WOLFSSL_BIO* bio;
int ret; int ret;
@@ -5989,14 +6219,14 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
wolfSSL_BIO_free(bio); wolfSSL_BIO_free(bio);
return ret; return ret;
} }
#endif /* NO_FILESYSTEM */ #endif /* NO_FILESYSTEM */
#endif /* XSNPRINTF */ #endif /* XSNPRINTF */
int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp, int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig) const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
{ {
(void)sig; (void)sig;
WOLFSSL_ENTER("wolfSSL_X509_signature_print"); WOLFSSL_ENTER("wolfSSL_X509_signature_print");
@@ -6017,18 +6247,18 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
} }
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }
#endif /* !NO_BIO */ #endif /* !NO_BIO */
#ifndef NO_WOLFSSL_STUB #ifndef NO_WOLFSSL_STUB
void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig, void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509) const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
{ {
(void)psig; (void)psig;
(void)palg; (void)palg;
(void)x509; (void)x509;
WOLFSSL_STUB("wolfSSL_X509_get0_signature"); WOLFSSL_STUB("wolfSSL_X509_get0_signature");
} }
#endif #endif
#endif /* OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */

View File

@@ -51464,10 +51464,11 @@ static void test_wolfSSL_X509_print(void)
AssertNotNull(bio = BIO_new(BIO_s_mem())); AssertNotNull(bio = BIO_new(BIO_s_mem()));
AssertIntEQ(X509_print(bio, x509), SSL_SUCCESS); AssertIntEQ(X509_print(bio, x509), SSL_SUCCESS);
#if defined(WOLFSSL_QT) #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
AssertIntEQ(BIO_get_mem_data(bio, NULL), 3113); /* Will print IP address subject alt name. */
AssertIntEQ(BIO_get_mem_data(bio, NULL), 3329);
#else #else
AssertIntEQ(BIO_get_mem_data(bio, NULL), 3103); AssertIntEQ(BIO_get_mem_data(bio, NULL), 3307);
#endif #endif
BIO_free(bio); BIO_free(bio);