diff --git a/src/format-dn.c b/src/format-dn.c
index ea5a2c1..2df228b 100644
--- a/src/format-dn.c
+++ b/src/format-dn.c
@@ -1,399 +1,397 @@
/* format-dn.c - Functions to format an ASN.1 Distinuguished Name.
* Copyright (C) 2001, 2004, 2007 Free Software Foundation, Inc.
* Copyright (C) 2009 g10 Code GmbH.
*
* This file is part of GPA.
*
* GPA is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GPA is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
-/*
+/*
This code is based on code taken from GnuPG (sm/certdump.c). It
has been converted to use only Glib stuff.
*/
#include
#include
#include
#include "gpa.h"
#include "format-dn.h"
-struct dn_array_s
+struct dn_array_s
{
char *key;
char *value;
int multivalued;
int done;
};
/* Remove trailing white spaces from STRING. */
static void
trim_trailing_spaces (char *string)
{
char *p, *mark;
-
+
for (mark=NULL, p=string; *p; p++)
{
if (g_ascii_isspace (*p))
{
if (!mark)
mark = p;
}
else
mark = NULL;
}
if (mark)
*mark = '\0' ;
}
/* Helper for the rfc2253 string parser. */
static const char *
parse_dn_part (struct dn_array_s *array, const char *string)
{
static struct {
const char *label;
const char *oid;
- } label_map[] =
+ } label_map[] =
{
/* Note: Take care we expect the LABEL not more than 9 bytes
longer than the OID. */
{"EMail", "1.2.840.113549.1.9.1" },
{"T", "2.5.4.12" },
{"GN", "2.5.4.42" },
{"SN", "2.5.4.4" },
- {"NameDistinguisher", "0.2.262.1.10.7.20"},
+ {"NameDistinguisher", "0.2.262.1.10.7.20"},
{"ADDR", "2.5.4.16" },
{"BC", "2.5.4.15" },
{"D", "2.5.4.13" },
{"PostalCode", "2.5.4.17" },
{"Pseudo", "2.5.4.65" },
{"SerialNumber", "2.5.4.5" },
+ {"Callsign", "1.3.6.1.4.1.12348.1.1"},
{NULL, NULL}
};
const char *s, *s1;
size_t n;
char *p;
int i;
/* Parse attributeType */
for (s = string+1; *s && *s != '='; s++)
;
if (!*s)
return NULL; /* error */
n = s - string;
if (!n)
return NULL; /* empty key */
/* We need to allocate a few bytes more due to the possible mapping
from the shorter OID to the longer label. */
array->key = p = g_try_malloc (n+10);
if (!array->key)
return NULL;
- memcpy (p, string, n);
+ memcpy (p, string, n);
p[n] = 0;
trim_trailing_spaces (p);
if (g_ascii_isdigit (*p))
{
for (i=0; label_map[i].label; i++ )
if ( !strcmp (p, label_map[i].oid) )
{
strcpy (p, label_map[i].label);
break;
}
}
string = s + 1;
if (*string == '#')
- {
+ {
/* Hexstring. */
string++;
for (s=string; g_ascii_isxdigit (*s); s++)
s++;
n = s - string;
if (!n || (n & 1))
return NULL; /* Empty or odd number of digits. */
n /= 2;
array->value = p = g_try_malloc (n+1);
if (!p)
return NULL;
for (s1=string; n; s1 += 2, n--, p++)
{
*(unsigned char *)p = xtoi_2 (s1);
if (!*p)
*p = 0x01; /* Better print a wrong value than truncating
the string. */
}
*p = 0;
}
else
- {
+ {
/* Regular v3 quoted string. */
for (n=0, s=string; *s; s++)
{
if (*s == '\\')
- {
+ {
/* Pair. */
s++;
if (*s == ',' || *s == '=' || *s == '+'
- || *s == '<' || *s == '>' || *s == '#' || *s == ';'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';'
|| *s == '\\' || *s == '\"' || *s == ' ')
n++;
else if (g_ascii_isxdigit (*s) && g_ascii_isxdigit(s[1]))
{
s++;
n++;
}
else
return NULL; /* Invalid escape sequence. */
}
else if (*s == '\"')
return NULL; /* Invalid encoding. */
else if (*s == ',' || *s == '=' || *s == '+'
|| *s == '<' || *s == '>' || *s == ';' )
- break;
+ break;
else
n++;
}
-
+
array->value = p = g_try_malloc (n+1);
if (!p)
return NULL;
for (s=string; n; s++, n--)
{
if (*s == '\\')
- {
+ {
s++;
if (g_ascii_isxdigit (*s))
{
*(unsigned char *)p++ = xtoi_2 (s);
s++;
}
else
*p++ = *s;
}
else
*p++ = *s;
}
*p = 0;
}
return s;
}
/* Parse a DN and return an array-ized one. This is not a validating
parser and it does not support any old-stylish syntax; KSBA is
expected to return only rfc2253 compatible strings. */
static struct dn_array_s *
parse_dn (const char *string)
{
struct dn_array_s *array;
size_t arrayidx, arraysize;
int i;
arraysize = 7; /* C,ST,L,O,OU,CN,email */
arrayidx = 0;
array = g_try_malloc ((arraysize+1) * sizeof *array);
if (!array)
return NULL;
while (*string)
{
while (*string == ' ')
string++;
if (!*string)
break; /* Ready. */
if (arrayidx >= arraysize)
- {
+ {
struct dn_array_s *a2;
arraysize += 5;
a2 = g_try_realloc (array, (arraysize+1) * sizeof *array);
if (!a2)
goto failure;
array = a2;
}
array[arrayidx].key = NULL;
array[arrayidx].value = NULL;
string = parse_dn_part (array+arrayidx, string);
if (!string)
goto failure;
while (*string == ' ')
string++;
array[arrayidx].multivalued = (*string == '+');
array[arrayidx].done = 0;
arrayidx++;
if (*string && *string != ',' && *string != ';' && *string != '+')
goto failure; /* Invalid delimiter. */
if (*string)
string++;
}
array[arrayidx].key = NULL;
array[arrayidx].value = NULL;
return array;
failure:
for (i=0; i < arrayidx; i++)
{
g_free (array[i].key);
g_free (array[i].value);
}
g_free (array);
return NULL;
}
/* Append BUFFER to OUTOPUT while replacing all control characters and
the characters in DELIMITERS by standard C escape sequences. */
-static void
+static void
append_sanitized (GString *output, const void *buffer, size_t length,
const char *delimiters)
{
const unsigned char *p = buffer;
size_t count = 0;
-
+
for (; length; length--, p++, count++)
{
- if (*p < 0x20
+ if (*p < 0x20
|| *p == 0x7f
- || (delimiters
+ || (delimiters
&& (strchr (delimiters, *p) || *p == '\\')))
{
g_string_append_c (output, '\\');
if (*p == '\n')
g_string_append_c (output, 'n');
else if (*p == '\r')
g_string_append_c (output, 'r');
else if (*p == '\f')
g_string_append_c (output, 'f');
else if (*p == '\v')
g_string_append_c (output, 'v');
else if (*p == '\b')
g_string_append_c (output, 'b');
else if (!*p)
g_string_append_c (output, '0');
else
g_string_append_printf (output, "x%02x", *p);
}
else
g_string_append_c (output, *p);
}
}
/* Print a DN part to STREAM or if STREAM is NULL to FP. */
static void
print_dn_part (GString *output, struct dn_array_s *dn, const char *key)
{
struct dn_array_s *first_dn = dn;
for (; dn->key; dn++)
{
if (!dn->done && !strcmp (dn->key, key))
{
/* Forward to the last multi-valued RDN, so that we can
print them all in reverse in the correct order. Note
that this overrides the the standard sequence but that
seems to a reasonable thing to do with multi-valued
RDNs. */
while (dn->multivalued && dn[1].key)
dn++;
next:
if (!dn->done && dn->value && *dn->value)
{
g_string_append_printf (output, "/%s=", dn->key);
append_sanitized (output, dn->value, strlen (dn->value), "/");
}
dn->done = 1;
if (dn > first_dn && dn[-1].multivalued)
{
dn--;
goto next;
}
}
}
}
/* Print all parts of a DN in a "standard" sequence. We first print
all the known parts, followed by the uncommon ones. */
static void
print_dn_parts (GString *output, struct dn_array_s *dn)
{
const char *stdpart[] = {
- "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL
+ "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL
};
int i;
-
+
for (i=0; stdpart[i]; i++)
print_dn_part (output, dn, stdpart[i]);
/* Now print the rest without any specific ordering */
for (; dn->key; dn++)
print_dn_part (output, dn, dn->key);
}
/* Format an RFC2253 encoded DN or GeneralName. Caller needs to
release the return ed string. This function will never return
NULL. */
char *
-gpa_format_dn (const char *name)
+gpa_format_dn (const char *name)
{
char *retval = NULL;
-
+
if (!name)
retval = g_strdup (_("[Error - No name]"));
else if (*name == '<')
{
const char *s = strchr (name+1, '>');
if (s)
retval = g_strndup (name+1, s - (name+1));
}
else if (*name == '(')
retval = g_strdup (_("[Error - Encoding not supported]"));
else if (g_ascii_isalnum (*name))
{
struct dn_array_s *dn;
int i;
dn = parse_dn (name);
if (dn)
{
GString *output = g_string_sized_new (strlen (name));
- print_dn_parts (output, dn);
+ print_dn_parts (output, dn);
retval = g_string_free (output, FALSE);
for (i=0; dn[i].key; i++)
{
g_free (dn[i].key);
g_free (dn[i].value);
}
g_free (dn);
}
}
-
+
if (!retval)
retval = g_strdup (_("[Error - Invalid encoding]"));
return retval;
}
-
-
-