From 517309724a01206ed1032192b7e2d6dd3a343311 Mon Sep 17 00:00:00 2001 From: TakayukiMatsuo Date: Sat, 7 Aug 2021 02:33:01 +0900 Subject: [PATCH] Add wolfSSL_GENERAL_NAME_print --- src/ssl.c | 144 ++++++++++++++++++++++++++++++++- tests/api.c | 182 ++++++++++++++++++++++++++++++++++++++++++ wolfssl/openssl/ssl.h | 1 + wolfssl/ssl.h | 2 + 4 files changed, 327 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5cb2ff162..5680404a4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20217,6 +20217,145 @@ void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens) wolfSSL_sk_free(gens); } +#ifdef OPENSSL_ALL +/* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO. + * Can handle following GENERAL_NAME_OBJECT types: + * - GEN_OTHERNAME # + * - GEN_EMAIL + * - GEN_DNS + * - GEN_X400 # + * - GEN_DIRNAME + * - GEN_EDIPARTY # + * - GEN_URI + * - GEN_RID + * The each name string to be output has "typename:namestring" format. + * For instance, email name string will be output as "email:info@wolfssl.com". + * However,some types above marked with "#" will be output with + * "typename:". + * + * Parameters: + * - out: WOLFSSL_BIO object which is the output destination + * - gen: WOLFSSL_GENERAL_NAME object to be output its name + * + * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. + */ +int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen) +{ + int ret, i; + unsigned int wd; + unsigned char* p; + (void)wd; + (void)p; + (void)i; + WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print"); + + if (out == NULL || gen == NULL) + return WOLFSSL_FAILURE; + + ret = WOLFSSL_FAILURE; + switch (gen->type) + { + case GEN_OTHERNAME: + ret = wolfSSL_BIO_printf(out, "othername:"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + break; + + case GEN_EMAIL: + ret = wolfSSL_BIO_printf(out, "email:"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) + { + ret = wolfSSL_ASN1_STRING_print(out, gen->d.rfc822Name); + } + break; + + case GEN_DNS: + ret = wolfSSL_BIO_printf(out, "DNS:"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_BIO_printf(out, gen->d.dNSName->strData); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + } + break; + + case GEN_X400: + ret = wolfSSL_BIO_printf(out, "X400Name:"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + break; + + case GEN_DIRNAME: + ret = wolfSSL_BIO_printf(out, "DirName:"); + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0, + XN_FLAG_ONELINE); + } + break; + + case GEN_EDIPARTY: + ret = wolfSSL_BIO_printf(out, "EdiPartyName:"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + break; + + case GEN_URI: + ret = wolfSSL_BIO_printf(out, "URI:"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_ASN1_STRING_print(out, + gen->d.uniformResourceIdentifier); + } + break; + + case GEN_IPADD: + ret = wolfSSL_BIO_printf(out, "IP Address"); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { + + if (!gen->d.iPAddress->length) { + ret = WOLFSSL_FAILURE; + break; + } + p = (unsigned char*)gen->d.iPAddress->strData; + + if (gen->d.iPAddress->length == 4) { + ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d", + p[0],p[1],p[2],p[3]); + } + else if (gen->d.iPAddress->length == 16) { + + for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) { + wd = p[i] << 8 | p[i+1]; + + i += 2; + ret = wolfSSL_BIO_printf(out, ":%X", wd); + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + } + } + else { + ret = wolfSSL_BIO_printf(out, ""); + } + ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + } + break; + + case GEN_RID: + ret = wolfSSL_BIO_printf(out, "Registered ID:"); + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID); + } + break; + + default: + /* unsupported type */ + break; + } + + if (ret == WOLFSSL_FAILURE) + return WOLFSSL_FAILURE; + else + return WOLFSSL_SUCCESS; +} +#endif /* OPENSSL_ALL */ + #if defined(OPENSSL_ALL) void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data) @@ -50785,7 +50924,8 @@ WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r, return r; } #endif /* OPENSSL_EXTRA */ -#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && !defined(NO_ASN) +#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \ + !defined(NO_ASN) #ifndef NO_BIO static int unprintable_char(char c) { @@ -50820,7 +50960,7 @@ int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str) return str->length; } #endif /* !NO_BIO */ -#endif /* (WOLFSSL_QT || OPENSSL_ALL) && !NO_ASN */ +#endif /* (WOLFSSL_QT || OPENSSL_ALL || OPENSSL_EXTRA) && !NO_ASN */ #if defined(OPENSSL_EXTRA) int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509) diff --git a/tests/api.c b/tests/api.c index a1fb0165b..d70a9b7b3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -35886,6 +35886,187 @@ static void test_wolfSSL_sk_GENERAL_NAME(void) #endif } +static void test_wolfSSL_GENERAL_NAME_print(void) +{ +#if defined(OPENSSL_ALL) + + X509* x509; + GENERAL_NAME* gn; + unsigned char buf[4096]; + const unsigned char* bufPt; + int bytes; + XFILE f; + STACK_OF(GENERAL_NAME)* sk; + BIO* out; + unsigned char outbuf[128]; + + X509_EXTENSION* ext; + AUTHORITY_INFO_ACCESS* aia; + ACCESS_DESCRIPTION* ad; + + const unsigned char v4Addr[] = {192,168,53,1}; + const unsigned char v6Addr[] = + {0x20, 0x21, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x77, 0x77}; + const unsigned char email[] = + {'i', 'n', 'f', 'o', '@', 'w', 'o', 'l', + 'f', 's', 's', 'l', '.', 'c', 'o', 'm'}; + + const char* dnsStr = "DNS:example.com"; + const char* uriStr = "URI:http://127.0.0.1:22220"; + const char* v4addStr = "IP Address:192.168.53.1"; + const char* v6addStr = "IP Address:2021:DB8:0:0:0:FF00:42:7777"; + const char* emailStr = "email:info@wolfssl.com"; + const char* othrStr = "othername:"; + const char* x400Str = "X400Name:"; + const char* ediStr = "EdiPartyName:"; + + + printf(testingFmt, "test_wolfSSL_GENERAL_NAME_print()"); + + /* BIO to output */ + AssertNotNull(out = BIO_new(BIO_s_mem())); + + /* test for NULL param */ + gn = NULL; + + AssertIntEQ(GENERAL_NAME_print(NULL, NULL), 0); + AssertIntEQ(GENERAL_NAME_print(NULL, gn), 0); + AssertIntEQ(GENERAL_NAME_print(out, NULL), 0); + + + /* test for GEN_DNS */ + f = XFOPEN(cliCertDerFileExt, "rb"); + AssertTrue((f != XBADFILE)); + AssertIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0); + XFCLOSE(f); + + bufPt = buf; + AssertNotNull(x509 = d2i_X509(NULL, &bufPt, bytes)); + AssertNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + NID_subject_alt_name, NULL, NULL)); + + AssertNotNull(gn = sk_GENERAL_NAME_value(sk, 0)); + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + + XMEMSET(outbuf,0,sizeof(outbuf)); + BIO_read(out, outbuf, sizeof(outbuf)); + AssertIntEQ(XSTRNCMP((const char*)outbuf, dnsStr, XSTRLEN(dnsStr)), 0); + + sk_GENERAL_NAME_pop_free(sk, GENERAL_NAME_free); + X509_free(x509); + + /* test for GEN_URI */ + + f = XFOPEN("./certs/ocsp/root-ca-cert.pem", "rb"); + AssertTrue((f != XBADFILE)); + AssertNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL)); + XFCLOSE(f); + + AssertNotNull(ext = wolfSSL_X509_get_ext(x509, 4)); + aia = (WOLFSSL_AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i(ext); + AssertNotNull(aia); + ad = (WOLFSSL_ACCESS_DESCRIPTION *)wolfSSL_sk_value(aia, 0); + + gn = ad->location; + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, uriStr, XSTRLEN(uriStr)), 0); + + wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL); + XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT); + X509_free(x509); + + /* test for GEN_IPADD */ + + /* ip v4 address */ + AssertNotNull(gn = wolfSSL_GENERAL_NAME_new()); + gn->type = GEN_IPADD; + gn->d.iPAddress->length = sizeof(v4Addr); + AssertIntEQ(wolfSSL_ASN1_STRING_set(gn->d.iPAddress, v4Addr, + sizeof(v4Addr)), 1); + + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, v4addStr, XSTRLEN(v4addStr)), 0); + + GENERAL_NAME_free(gn); + + /* ip v6 address */ + + AssertNotNull(gn = wolfSSL_GENERAL_NAME_new()); + gn->type = GEN_IPADD; + gn->d.iPAddress->length = sizeof(v6Addr); + AssertIntEQ(wolfSSL_ASN1_STRING_set(gn->d.iPAddress, v6Addr, + sizeof(v6Addr)), 1); + + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, v6addStr, XSTRLEN(v6addStr)), 0); + + GENERAL_NAME_free(gn); + + /* test for GEN_EMAIL */ + + AssertNotNull(gn = wolfSSL_GENERAL_NAME_new()); + gn->type = GEN_EMAIL; + gn->d.rfc822Name->length = sizeof(email); + AssertIntEQ(wolfSSL_ASN1_STRING_set(gn->d.rfc822Name, email, + sizeof(email)), 1); + + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, emailStr, XSTRLEN(emailStr)), 0); + + GENERAL_NAME_free(gn); + + /* test for GEN_OTHERNAME */ + + AssertNotNull(gn = wolfSSL_GENERAL_NAME_new()); + gn->type = GEN_OTHERNAME; + + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, othrStr, XSTRLEN(othrStr)), 0); + + GENERAL_NAME_free(gn); + + /* test for GEN_X400 */ + + AssertNotNull(gn = wolfSSL_GENERAL_NAME_new()); + gn->type = GEN_X400; + + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, x400Str, XSTRLEN(x400Str)), 0); + + GENERAL_NAME_free(gn); + + /* test for GEN_EDIPARTY */ + + AssertNotNull(gn = wolfSSL_GENERAL_NAME_new()); + gn->type = GEN_EDIPARTY; + + AssertIntEQ(GENERAL_NAME_print(out, gn), 1); + XMEMSET(outbuf,0,sizeof(outbuf)); + AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0); + AssertIntEQ(XSTRNCMP((const char*)outbuf, ediStr, XSTRLEN(ediStr)), 0); + + GENERAL_NAME_free(gn); + + BIO_free(out); + + printf(resultFmt, passed); +#endif /* OPENSSL_ALL */ +} + static void test_wolfSSL_MD4(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_MD4) @@ -46864,6 +47045,7 @@ void ApiTest(void) test_wolfSSL_ticket_keys(); test_wolfSSL_DES_ecb_encrypt(); test_wolfSSL_sk_GENERAL_NAME(); + test_wolfSSL_GENERAL_NAME_print(); test_wolfSSL_MD4(); test_wolfSSL_RSA(); test_wolfSSL_RSA_DER(); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 0c0e73418..254cdb692 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1231,6 +1231,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define GENERAL_NAME_new wolfSSL_GENERAL_NAME_new #define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free +#define GENERAL_NAME_print wolfSSL_GENERAL_NAME_print #define sk_GENERAL_NAME_push wolfSSL_sk_GENERAL_NAME_push #define sk_GENERAL_NAME_value wolfSSL_sk_GENERAL_NAME_value #define SSL_SESSION_get_ex_data wolfSSL_SESSION_get_ex_data diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 600a426c6..d63a3ee70 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1320,6 +1320,8 @@ WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, void (*f) (WOLFSSL_GENERAL_NAME*)); WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES* name); +WOLFSSL_API int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, + WOLFSSL_GENERAL_NAME* name); WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_AUTHORITY_INFO_ACCESS_free( WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk);