Refactor ssl_x509_names_to_str() for maintainability

pull/13/head
Daniel Roethlisberger 12 years ago
parent 04c9112621
commit d4be8c3e38

@ -243,7 +243,7 @@ pxy_debug_crt(X509 *crt)
free(sj);
}
char *names = ssl_x509_names_to_str(crt, 60);
char *names = ssl_x509_names_to_str(crt);
if (names) {
log_dbg_printf("Common Names: %s\n", names);
free(names);
@ -598,8 +598,8 @@ pxy_srcssl_create(pxy_conn_ctx_t *ctx, SSL *origssl)
}
if (WANT_CONNECT_LOG(ctx)) {
ctx->ssl_names = ssl_x509_names_to_str(cert->crt, 128);
ctx->ssl_orignames = ssl_x509_names_to_str(ctx->origcrt, 128);
ctx->ssl_names = ssl_x509_names_to_str(cert->crt);
ctx->ssl_orignames = ssl_x509_names_to_str(ctx->origcrt);
}
SSL_CTX *sslctx = pxy_srcsslctx_create(ctx, cert->crt, cert->chain,
@ -670,7 +670,7 @@ pxy_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg)
if (ctx->ssl_names) {
free(ctx->ssl_names);
}
ctx->ssl_names = ssl_x509_names_to_str(newcrt, 128);
ctx->ssl_names = ssl_x509_names_to_str(newcrt);
}
SSL_CTX *sslctx, *newsslctx;
newsslctx = pxy_srcsslctx_create(ctx, newcrt, ctx->opts->chain,

106
ssl.c

@ -1080,72 +1080,6 @@ ssl_x509_names_match(X509 *crt, const char *dnsname)
return 0;
}
/*
* Returns a printable representation of a certificate's common names found
* in the Subject DN CN and subjectAltNames extension.
* If the length of the common names exceeds limit characters, the rest is
* truncated.
* Caller must free returned buffer.
* Embedded NULL characters in hostnames are replaced with '!'.
*/
char *
ssl_x509_names_to_str(X509 *crt, size_t limit)
{
GENERAL_NAMES *altnames;
char *cn, *buf;
size_t cnsz;
if ((limit == 0) || (limit > 1023))
limit = 1023;
buf = malloc(limit+1);
if (!buf)
return NULL;
buf[0] = '\0';
cn = ssl_x509_subject_cn(crt, &cnsz);
if (cn) {
strncat(buf, cn, limit);
free(cn);
}
altnames = X509_get_ext_d2i(crt, NID_subject_alt_name, 0, 0);
if (!altnames)
return buf;
for (int i = 0; i < sk_GENERAL_NAME_num(altnames); i++) {
GENERAL_NAME *gn = sk_GENERAL_NAME_value(altnames, i);
if (gn->type == GEN_DNS) {
unsigned char *altname;
int altnamesz;
size_t written;
ASN1_STRING_to_UTF8(&altname, gn->d.dNSName);
altnamesz = ASN1_STRING_length(gn->d.dNSName);
if (altnamesz < 0)
break;
if (strlen(buf) + 1 < limit)
strncat(buf, "/", 1);
written = strlen(buf);
for (int j = 0; j < altnamesz; j++) {
if (written < limit) {
buf[written] = altname[j] ?
altname[j] : '!';
written++;
}
}
OPENSSL_free((char*)altname);
buf[written] = '\0';
if (written == limit) {
buf[limit-3] = '.';
buf[limit-2] = '.';
buf[limit-1] = '.';
GENERAL_NAMES_free(altnames);
return buf;
}
}
}
GENERAL_NAMES_free(altnames);
return buf;
}
/*
* Returns a NULL terminated array of pointers to all common names found
* in the Subject DN CN and subjectAltNames extension (DNSName only).
@ -1211,6 +1145,46 @@ ssl_x509_names(X509 *crt)
return res;
}
/*
* Returns a printable representation of a certificate's common names found
* in the Subject DN CN and subjectAltNames extension, separated by slashes.
* Caller must free returned buffer.
* Embedded NULL characters in hostnames are replaced with '!'.
*/
char *
ssl_x509_names_to_str(X509 *crt)
{
char **names;
size_t sz;
char *buf, *next;
names = ssl_x509_names(crt);
if (!names)
return NULL;
sz = 0;
for (char **p = names; *p; p++) {
sz += strlen(*p) + 1;
}
if (!(buf = malloc(sz)))
goto out;
next = buf;
for (char **p = names; *p; p++) {
char *src = *p;
while (*src) {
*next++ = *src++;
}
*next++ = '/';
}
*--next = '\0';
out:
for (char **p = names; *p; p++)
free(*p);
free(names);
return buf;
}
/*
* Returns a zero-terminated buffer containing the ASN1 IA5 string.
* Returned buffer must be free()'d by caller.

@ -85,9 +85,9 @@ char * ssl_x509_subject(X509 *) NONNULL() MALLOC;
char * ssl_x509_subject_cn(X509 *, size_t *) NONNULL() MALLOC;
#define SSL_X509_FPRSZ 20
int ssl_x509_fingerprint_sha1(X509 *, unsigned char *) NONNULL();
int ssl_x509_names_match(X509 *, const char *) NONNULL();
char * ssl_x509_names_to_str(X509 *, size_t) NONNULL() MALLOC;
char ** ssl_x509_names(X509 *) NONNULL() MALLOC;
int ssl_x509_names_match(X509 *, const char *) NONNULL();
char * ssl_x509_names_to_str(X509 *) NONNULL() MALLOC;
char ** ssl_x509_aias(X509 *, const int) NONNULL(1) MALLOC;
char ** ssl_x509_ocsps(X509 *) NONNULL() MALLOC;
int ssl_x509_is_valid(X509 *) NONNULL();

36
ssl.t

@ -426,6 +426,36 @@ START_TEST(ssl_x509_names_01)
}
END_TEST
START_TEST(ssl_x509_names_to_str_01)
{
X509 *c;
char *names;
c = ssl_x509_load(TESTCERT);
fail_unless(!!c, "loading certificate failed");
names = ssl_x509_names_to_str(c);
fail_unless(!!names, "no string");
fail_unless(!strcmp(names,
"daniel.roe.ch/daniel.roe.ch/www.roe.ch/*.roe.ch"),
"wrong name string");
X509_free(c);
}
END_TEST
START_TEST(ssl_x509_names_to_str_02)
{
X509 *c;
char *names;
c = ssl_x509_load(TESTCERT2);
fail_unless(!!c, "loading certificate failed");
names = ssl_x509_names_to_str(c);
fail_unless(!!names, "no string");
fail_unless(!strcmp(names, "SSLsplit Root CA"), "wrong name string");
X509_free(c);
}
END_TEST
START_TEST(ssl_x509_ocsps_01)
{
X509 *c;
@ -520,6 +550,12 @@ ssl_suite(void)
tcase_add_test(tc, ssl_x509_names_01);
suite_add_tcase(s, tc);
tc = tcase_create("ssl_x509_names_to_str");
tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
tcase_add_test(tc, ssl_x509_names_to_str_01);
tcase_add_test(tc, ssl_x509_names_to_str_02);
suite_add_tcase(s, tc);
tc = tcase_create("ssl_x509_ocsps");
tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
tcase_add_test(tc, ssl_x509_ocsps_01);

Loading…
Cancel
Save