#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
-#include <ctype.h>
#include "identification.h"
}
/**
- * 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
*/
static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
}
/**
- * 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;
- asn1_t type;
- int oid_code;
- bool next;
- bool first = TRUE;
-
- if (!init_rdn(dn, &rdn, &attribute, &next))
- {
- return FALSE;
- }
+ enumerator_t *e;
+ chunk_t oid_data, data;
+ u_char type;
+ int oid, written;
+ bool finished = FALSE;
- while (next)
+ e = create_rdn_enumerator(dn);
+ while (e->enumerate(e, &oid_data, &type, &data))
{
- if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
+ oid = asn1_known_oid(oid_data);
+
+ if (oid == OID_UNKNOWN)
{
- return FALSE;
+ written = snprintf(buf, len, "%#B=", &oid_data);
}
+ else
+ {
+ written = snprintf(buf, len,"%s=", oid_names[oid].name);
+ }
+ buf += written;
+ len -= written;
- if (first)
- { /* first OID/value pair */
- first = FALSE;
+ if (chunk_printable(data, NULL, '?'))
+ {
+ written = snprintf(buf, len, "%.*s", data.len, data.ptr);
}
else
- { /* separate OID/value pair by a comma */
- update_chunk(str, snprintf(str->ptr,str->len,", "));
+ {
+ written = snprintf(buf, len, "%#B", &data);
}
+ buf += written;
+ len -= written;
- /* print OID */
- oid_code = asn1_known_oid(oid);
- if (oid_code == OID_UNKNOWN)
+ if (data.ptr + data.len != dn.ptr + dn.len)
{
- update_chunk(str, snprintf(str->ptr,str->len,"0x#B", &oid));
+ written = snprintf(buf, len, " ");
+ buf += written;
+ len -= written;
}
else
{
- update_chunk(str, snprintf(str->ptr,str->len,"%s", oid_names[oid_code].name));
+ 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);
}
/**
const void *const *args)
{
private_identification_t *this = *((private_identification_t**)(args[0]));
- char buf[BUF_LEN];
- chunk_t proper, buf_chunk = chunk_from_buf(buf);
+ chunk_t proper;
+ char buf[512];
if (this == NULL)
{
case ID_RFC822_ADDR:
case ID_DER_ASN1_GN_URI:
case ID_IETF_ATTR_STRING:
- sanitize_chunk(this->encoded, &proper);
+ chunk_printable(this->encoded, &proper, '?');
snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
chunk_free(&proper);
break;
case ID_DER_ASN1_DN:
- if (!dntoa(this->encoded, &buf_chunk))
- {
- snprintf(buf, sizeof(buf), "(invalid ID_DER_ASN1_DN)");
- }
+ dntoa(this->encoded, buf, sizeof(buf));
break;
case ID_DER_ASN1_GN:
snprintf(buf, sizeof(buf), "(ASN.1 general Name");
break;
case ID_KEY_ID:
- if (sanitize_chunk(this->encoded, &proper))
+ if (chunk_printable(this->encoded, NULL, '?'))
{ /* 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
{ /* not printable, hex dump */