libksba  1.6.0
About: KSBA is a library to make the tasks of working with X.509 certificates, CMS data and related objects more easy.
  Fossies Dox: libksba-1.6.0.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

name.c
Go to the documentation of this file.
1 /* name.c - Object to access GeneralNames etc.
2  * Copyright (C) 2002, 2012 g10 Code GmbH
3  *
4  * This file is part of KSBA.
5  *
6  * KSBA is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  * - the GNU Lesser General Public License as published by the Free
10  * Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * or
14  *
15  * - the GNU General Public License as published by the Free
16  * Software Foundation; either version 2 of the License, or (at
17  * your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * KSBA is distributed in the hope that it will be useful, but WITHOUT
22  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24  * License for more details.
25  *
26  * You should have received a copies of the GNU General Public License
27  * and the GNU Lesser General Public License along with this program;
28  * if not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include <config.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <assert.h>
36 #include <errno.h>
37 
38 #include "util.h"
39 #include "asn1-func.h"
40 #include "convert.h"
41 #include "ber-help.h"
42 
43 
44 struct ksba_name_s {
45  int ref_count;
46  int n_names; /* number of names */
47  char **names; /* array with the parsed names */
48 };
49 
50 
51 /* Also this is a public function it is not yet usable becuase we
52  don't have a way to set real information. */
53 gpg_error_t
55 {
56  *r_name = xtrycalloc (1, sizeof **r_name);
57  if (!*r_name)
58  return gpg_error_from_errno (errno);
59  (*r_name)->ref_count++;
60 
61  return 0;
62 }
63 
64 void
66 {
67  if (!name)
68  fprintf (stderr, "BUG: ksba_name_ref for NULL\n");
69  else
70  ++name->ref_count;
71 }
72 
73 
74 void
76 {
77  int i;
78 
79  if (!name)
80  return;
81  if (name->ref_count < 1)
82  {
83  fprintf (stderr, "BUG: trying to release an already released name\n");
84  return;
85  }
86  if (--name->ref_count)
87  return;
88 
89  for (i=0; i < name->n_names; i++)
90  xfree (name->names[i]);
91  xfree (name->names);
92  name->n_names = 0;
93  xfree (name);
94 }
95 
96 
97 /* This is an internal function to create an ksba_name_t object from an
98  DER encoded image which must point to an GeneralNames object */
99 gpg_error_t
101  const unsigned char *image, size_t imagelen)
102 {
103  gpg_error_t err;
105  struct tag_info ti;
106  const unsigned char *der;
107  size_t derlen;
108  int n;
109  char *p;
110 
111  if (!r_name || !image)
112  return gpg_error (GPG_ERR_INV_VALUE);
113 
114  *r_name = NULL;
115 
116  /* Count and check for encoding errors - we won't do this again
117  during the second pass */
118  der = image;
119  derlen = imagelen;
120  n = 0;
121  while (derlen)
122  {
123  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
124  if (err)
125  return err;
126  if (ti.class != CLASS_CONTEXT)
127  return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
128  if (ti.ndef)
129  return gpg_error (GPG_ERR_NOT_DER_ENCODED);
130  if (derlen < ti.length)
131  return gpg_error (GPG_ERR_BAD_BER);
132  switch (ti.tag)
133  {
134  case 1: /* rfc822Name - this is an imlicit IA5_STRING */
135  case 4: /* Name */
136  case 6: /* URI */
137  n++;
138  break;
139  default:
140  break;
141  }
142 
143  /* advance pointer */
144  der += ti.length;
145  derlen -= ti.length;
146  }
147 
148  /* allocate array and set all slots to NULL for easier error recovery */
149  err = ksba_name_new (&name);
150  if (err)
151  return err;
152  if (!n)
153  return 0; /* empty GeneralNames */
154  name->names = xtrycalloc (n, sizeof *name->names);
155  if (!name->names)
156  {
158  return gpg_error (GPG_ERR_ENOMEM);
159  }
160  name->n_names = n;
161 
162  /* start the second pass */
163  der = image;
164  derlen = imagelen;
165  n = 0;
166  while (derlen)
167  {
168  char numbuf[21];
169 
170  err = _ksba_ber_parse_tl (&der, &derlen, &ti);
171  assert (!err);
172  switch (ti.tag)
173  {
174  case 1: /* rfc822Name - this is an imlicit IA5_STRING */
175  p = name->names[n] = xtrymalloc (ti.length+3);
176  if (!p)
177  {
179  return gpg_error (GPG_ERR_ENOMEM);
180  }
181  *p++ = '<';
182  memcpy (p, der, ti.length);
183  p += ti.length;
184  *p++ = '>';
185  *p = 0;
186  n++;
187  break;
188  case 4: /* Name */
189  err = _ksba_derdn_to_str (der, ti.length, &p);
190  if (err)
191  return err; /* FIXME: we need to release some of the memory */
192  name->names[n++] = p;
193  break;
194  case 6: /* URI */
195  sprintf (numbuf, "%u:", (unsigned int)ti.length);
196  p = name->names[n] = xtrymalloc (1+5+strlen (numbuf)
197  + ti.length +1+1);
198  if (!p)
199  {
201  return gpg_error (GPG_ERR_ENOMEM);
202  }
203  p = stpcpy (p, "(3:uri");
204  p = stpcpy (p, numbuf);
205  memcpy (p, der, ti.length);
206  p += ti.length;
207  *p++ = ')';
208  *p = 0; /* extra safeguard null */
209  n++;
210  break;
211  default:
212  break;
213  }
214 
215  /* advance pointer */
216  der += ti.length;
217  derlen -= ti.length;
218  }
219  *r_name = name;
220  return 0;
221 }
222 
223 
224 /* By iterating IDX up starting with 0, this function returns the all
225  General Names stored in NAME. The format of the returned name is
226  either a RFC-2253 formated one which can be detected by checking
227  whether the first character is letter or a digit. RFC 2822 conform
228  email addresses are returned enclosed in angle brackets, the
229  opening angle bracket should be used to detect this. Other formats
230  are returned as an S-Expression in canonical format, so a opening
231  parenthesis may be used to detect this encoding, in this case the
232  name may include binary null characters, so strlen might return a
233  length shorter than actually used, the real length is implictly
234  given by the structure of the S-Exp, an extra null is appended for
235  safety reasons. One common format return is probably an Universal
236  Resource Identifier which has the S-expression: "(uri <urivalue>)".
237 
238  The return string has the same lifetime as NAME. */
239 const char *
241 {
242  if (!name || idx < 0)
243  return NULL;
244  if (idx >= name->n_names)
245  return NULL; /* end of list */
246 
247  return name->names[idx];
248 }
249 
250 /* Convenience function to return names representing an URI. Caller
251  must free the return value. Note that this function should not be
252  used for enumeration */
253 char *
255 {
256  const char *s = ksba_name_enum (name, idx);
257  int n;
258  char *buf;
259 
260  if (!s || strncmp (s, "(3:uri", 6))
261  return NULL; /* we do only return URIs */
262  s += 6;
263  for (n=0; *s && *s != ':' && digitp (s); s++)
264  n = n*10 + atoi_1 (s);
265  if (!n || *s != ':')
266  return NULL; /* oops */
267  s++;
268  buf = xtrymalloc (n+1);
269  if (buf)
270  {
271  memcpy (buf, s, n);
272  buf[n] = 0;
273  }
274  return buf;
275 }
@ CLASS_CONTEXT
gpg_error_t _ksba_ber_parse_tl(unsigned char const **buffer, size_t *size, struct tag_info *ti)
Definition: ber-help.c:200
gpg_error_t _ksba_derdn_to_str(const unsigned char *der, size_t derlen, char **r_string)
Definition: dn.c:622
const char * name
Definition: dn.c:47
#define stpcpy(a, b)
Definition: gen-help.h:41
#define GPG_ERR_INV_VALUE
Definition: gen-help.h:82
#define xtrymalloc(a)
Definition: gen-help.h:38
#define gpg_error(a)
Definition: gen-help.h:87
const unsigned char * der
Definition: keyinfo.c:367
unsigned int derlen
Definition: keyinfo.c:366
void ksba_name_ref(ksba_name_t name)
gpg_error_t ksba_name_new(ksba_name_t *r_name)
char * ksba_name_get_uri(ksba_name_t name, int idx)
void ksba_name_release(ksba_name_t name)
const char * ksba_name_enum(ksba_name_t name, int idx)
gpg_error_t _ksba_name_new_from_der(ksba_name_t *r_name, const unsigned char *image, size_t imagelen)
Definition: name.c:100
int ref_count
Definition: name.c:45
char ** names
Definition: name.c:47
int n_names
Definition: name.c:46
unsigned long tag
Definition: ber-help.h:38
unsigned char buf[10]
Definition: ber-help.h:42
unsigned long length
Definition: ber-help.h:39
int ndef
Definition: ber-help.h:40
enum tag_class class
Definition: ber-help.h:36
#define xfree(a)
Definition: util.h:58
#define atoi_1(p)
Definition: util.h:114
#define digitp(p)
Definition: util.h:109
#define xtrycalloc(a, b)
Definition: util.h:55