1 /* name.c - Object to access GeneralNames etc.
2 * Copyright (C) 2002, 2012 g10 Code GmbH
4 * This file is part of KSBA.
6 * KSBA is free software; you can redistribute it and/or modify
7 * it under the terms of either
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.
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.
19 * or both in parallel, as here.
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.
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/>.
39 #include "asn1-func.h"
46 int n_names; /* number of names */
47 char **names; /* array with the parsed names */
51 /* Also this is a public function it is not yet usable becuase we
52 don't have a way to set real information. */
54 ksba_name_new (ksba_name_t *r_name)
56 *r_name = xtrycalloc (1, sizeof **r_name);
58 return gpg_error_from_errno (errno);
59 (*r_name)->ref_count++;
65 ksba_name_ref (ksba_name_t name)
68 fprintf (stderr, "BUG: ksba_name_ref for NULL\n");
75 ksba_name_release (ksba_name_t name)
81 if (name->ref_count < 1)
83 fprintf (stderr, "BUG: trying to release an already released name\n");
86 if (--name->ref_count)
89 for (i=0; i < name->n_names; i++)
90 xfree (name->names[i]);
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 */
100 _ksba_name_new_from_der (ksba_name_t *r_name,
101 const unsigned char *image, size_t imagelen)
106 const unsigned char *der;
111 if (!r_name || !image)
112 return gpg_error (GPG_ERR_INV_VALUE);
116 /* Count and check for encoding errors - we won't do this again
117 during the second pass */
123 err = _ksba_ber_parse_tl (&der, &derlen, &ti);
126 if (ti.class != CLASS_CONTEXT)
127 return gpg_error (GPG_ERR_INV_CERT_OBJ); /* we expected a tag */
129 return gpg_error (GPG_ERR_NOT_DER_ENCODED);
130 if (derlen < ti.length)
131 return gpg_error (GPG_ERR_BAD_BER);
134 case 1: /* rfc822Name - this is an imlicit IA5_STRING */
143 /* advance pointer */
148 /* allocate array and set all slots to NULL for easier error recovery */
149 err = ksba_name_new (&name);
153 return 0; /* empty GeneralNames */
154 name->names = xtrycalloc (n, sizeof *name->names);
157 ksba_name_release (name);
158 return gpg_error (GPG_ERR_ENOMEM);
162 /* start the second pass */
170 err = _ksba_ber_parse_tl (&der, &derlen, &ti);
174 case 1: /* rfc822Name - this is an imlicit IA5_STRING */
175 p = name->names[n] = xtrymalloc (ti.length+3);
178 ksba_name_release (name);
179 return gpg_error (GPG_ERR_ENOMEM);
182 memcpy (p, der, ti.length);
189 err = _ksba_derdn_to_str (der, ti.length, &p);
191 return err; /* FIXME: we need to release some of the memory */
192 name->names[n++] = p;
195 sprintf (numbuf, "%u:", (unsigned int)ti.length);
196 p = name->names[n] = xtrymalloc (1+5+strlen (numbuf)
200 ksba_name_release (name);
201 return gpg_error (GPG_ERR_ENOMEM);
203 p = stpcpy (p, "(3:uri");
204 p = stpcpy (p, numbuf);
205 memcpy (p, der, ti.length);
208 *p = 0; /* extra safeguard null */
215 /* advance pointer */
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>)".
238 The return string has the same lifetime as NAME. */
240 ksba_name_enum (ksba_name_t name, int idx)
242 if (!name || idx < 0)
244 if (idx >= name->n_names)
245 return NULL; /* end of list */
247 return name->names[idx];
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 */
254 ksba_name_get_uri (ksba_name_t name, int idx)
256 const char *s = ksba_name_enum (name, idx);
260 if (!s || strncmp (s, "(3:uri", 6))
261 return NULL; /* we do only return URIs */
263 for (n=0; *s && *s != ':' && digitp (s); s++)
264 n = n*10 + atoi_1 (s);
266 return NULL; /* oops */
268 buf = xtrymalloc (n+1);