reimplemented dnota() using RDN enumerator

This commit is contained in:
Martin Willi
2009-07-06 13:15:29 +02:00
parent f48c3c72f4
commit 8309798fae
+50 -78
View File
@@ -21,7 +21,6 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h>
#include "identification.h" #include "identification.h"
@@ -268,38 +267,6 @@ static enumerator_t* create_part_enumerator(private_identification_t *this)
} }
} }
/**
* updates a chunk (!????)
* TODO: We should reconsider this stuff, its not really clear
*/
static void update_chunk(chunk_t *ch, int n)
{
n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
ch->ptr += n; ch->len -= n;
}
/**
* Remove any malicious characters from a chunk. We are very restrictive, but
* whe use these strings only to present it to the user.
*/
static bool sanitize_chunk(chunk_t chunk, chunk_t *clone)
{
char *pos;
bool all_printable = TRUE;
*clone = chunk_clone(chunk);
for (pos = clone->ptr; pos < (char*)(clone->ptr + clone->len); pos++)
{
if (!isprint(*pos))
{
*pos = '?';
all_printable = FALSE;
}
}
return all_printable;
}
/** /**
* Pointer is set to the first RDN in a DN * Pointer is set to the first RDN in a DN
*/ */
@@ -425,53 +392,60 @@ static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid,
} }
/** /**
* Parses an ASN.1 distinguished name int its OID/value pairs * Print a DN with all its RDN in a buffer to present it to the user
*/ */
static bool dntoa(chunk_t dn, chunk_t *str) static void dntoa(chunk_t dn, char *buf, size_t len)
{ {
chunk_t rdn, oid, attribute, value, proper; enumerator_t *e;
asn1_t type; chunk_t oid_data, data;
int oid_code; u_char type;
bool next; int oid, written;
bool first = TRUE; bool finished = FALSE;
if (!init_rdn(dn, &rdn, &attribute, &next)) e = create_rdn_enumerator(dn);
while (e->enumerate(e, &oid_data, &type, &data))
{ {
return FALSE; oid = asn1_known_oid(oid_data);
}
while (next)
{
if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
{
return FALSE;
}
if (first) if (oid == OID_UNKNOWN)
{ /* first OID/value pair */
first = FALSE;
}
else
{ /* separate OID/value pair by a comma */
update_chunk(str, snprintf(str->ptr,str->len,", "));
}
/* print OID */
oid_code = asn1_known_oid(oid);
if (oid_code == OID_UNKNOWN)
{ {
update_chunk(str, snprintf(str->ptr,str->len,"0x#B", &oid)); written = snprintf(buf, len, "%#B=", &oid_data);
} }
else else
{ {
update_chunk(str, snprintf(str->ptr,str->len,"%s", oid_names[oid_code].name)); written = snprintf(buf, len,"%s=", oid_names[oid].name);
}
buf += written;
len -= written;
if (chunk_printable(data, NULL, '?'))
{
written = snprintf(buf, len, "%.*s", data.len, data.ptr);
}
else
{
written = snprintf(buf, len, "%#B", &data);
}
buf += written;
len -= written;
if (data.ptr + data.len != dn.ptr + dn.len)
{
written = snprintf(buf, len, " ");
buf += written;
len -= written;
}
else
{
finished = TRUE;
break;
} }
/* print value */
sanitize_chunk(value, &proper);
update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr));
chunk_free(&proper);
} }
return TRUE; if (!finished)
{
snprintf(buf, len, "(invalid ID_DER_ASN1_DN)");
}
e->destroy(e);
} }
/** /**
@@ -920,8 +894,8 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
const void *const *args) const void *const *args)
{ {
private_identification_t *this = *((private_identification_t**)(args[0])); private_identification_t *this = *((private_identification_t**)(args[0]));
char buf[BUF_LEN]; chunk_t proper;
chunk_t proper, buf_chunk = chunk_from_buf(buf); char buf[512];
if (this == NULL) if (this == NULL)
{ {
@@ -951,23 +925,21 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
case ID_RFC822_ADDR: case ID_RFC822_ADDR:
case ID_DER_ASN1_GN_URI: case ID_DER_ASN1_GN_URI:
case ID_IETF_ATTR_STRING: case ID_IETF_ATTR_STRING:
sanitize_chunk(this->encoded, &proper); chunk_printable(this->encoded, &proper, '?');
snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr); snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
chunk_free(&proper); chunk_free(&proper);
break; break;
case ID_DER_ASN1_DN: case ID_DER_ASN1_DN:
if (!dntoa(this->encoded, &buf_chunk)) dntoa(this->encoded, buf, sizeof(buf));
{
snprintf(buf, sizeof(buf), "(invalid ID_DER_ASN1_DN)");
}
break; break;
case ID_DER_ASN1_GN: case ID_DER_ASN1_GN:
snprintf(buf, sizeof(buf), "(ASN.1 general Name"); snprintf(buf, sizeof(buf), "(ASN.1 general Name");
break; break;
case ID_KEY_ID: case ID_KEY_ID:
if (sanitize_chunk(this->encoded, &proper)) if (chunk_printable(this->encoded, NULL, '?'))
{ /* fully printable, use ascii version */ { /* fully printable, use ascii version */
snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr); snprintf(buf, sizeof(buf), "%.*s",
this->encoded.len, this->encoded.ptr);
} }
else else
{ /* not printable, hex dump */ { /* not printable, hex dump */