1219089Spjd/*
2219089Spjd * Copyright (c) 2005 Kungliga Tekniska H��gskolan
3219089Spjd * (Royal Institute of Technology, Stockholm, Sweden).
4219089Spjd * All rights reserved.
5219089Spjd *
6219089Spjd * Redistribution and use in source and binary forms, with or without
7219089Spjd * modification, are permitted provided that the following conditions
8219089Spjd * are met:
9219089Spjd *
10219089Spjd * 1. Redistributions of source code must retain the above copyright
11219089Spjd *    notice, this list of conditions and the following disclaimer.
12219089Spjd *
13219089Spjd * 2. Redistributions in binary form must reproduce the above copyright
14219089Spjd *    notice, this list of conditions and the following disclaimer in the
15219089Spjd *    documentation and/or other materials provided with the distribution.
16219089Spjd *
17219089Spjd * 3. Neither the name of the Institute nor the names of its contributors
18219089Spjd *    may be used to endorse or promote products derived from this software
19219089Spjd *    without specific prior written permission.
20219089Spjd *
21219089Spjd * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22219089Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23219089Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24219089Spjd * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25219089Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26219089Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27219089Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28219089Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29219089Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30219089Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31219089Spjd * SUCH DAMAGE.
32219089Spjd */
33219089Spjd
34219089Spjd#include "der_locl.h"
35219089Spjd#include <hex.h>
36219089Spjd
37219089SpjdRCSID("$Id$");
38219089Spjd
39219089Spjdint
40219089Spjdder_parse_hex_heim_integer (const char *p, heim_integer *data)
41219089Spjd{
42219089Spjd    ssize_t len;
43219089Spjd
44219089Spjd    data->length = 0;
45219089Spjd    data->negative = 0;
46219089Spjd    data->data = NULL;
47219089Spjd
48219089Spjd    if (*p == '-') {
49219089Spjd	p++;
50219089Spjd	data->negative = 1;
51219089Spjd    }
52219089Spjd
53219089Spjd    len = strlen(p);
54219089Spjd    if (len <= 0) {
55219089Spjd	data->data = NULL;
56219089Spjd	data->length = 0;
57219089Spjd	return EINVAL;
58219089Spjd    }
59219089Spjd
60219089Spjd    data->length = (len / 2) + 1;
61219089Spjd    data->data = malloc(data->length);
62219089Spjd    if (data->data == NULL) {
63219089Spjd	data->length = 0;
64219089Spjd	return ENOMEM;
65219089Spjd    }
66219089Spjd
67219089Spjd    len = hex_decode(p, data->data, data->length);
68219089Spjd    if (len < 0) {
69219089Spjd	free(data->data);
70219089Spjd	data->data = NULL;
71219089Spjd	data->length = 0;
72219089Spjd	return EINVAL;
73219089Spjd    }
74219089Spjd
75219089Spjd    {
76219089Spjd	unsigned char *q = data->data;
77219089Spjd	while(len > 0 && *q == 0) {
78219089Spjd	    q++;
79219089Spjd	    len--;
80219089Spjd	}
81219089Spjd	data->length = len;
82219089Spjd	memmove(data->data, q, len);
83219089Spjd    }
84219089Spjd    return 0;
85219089Spjd}
86219089Spjd
87219089Spjdint
88219089Spjdder_print_hex_heim_integer (const heim_integer *data, char **p)
89219089Spjd{
90219089Spjd    ssize_t len;
91219089Spjd    char *q;
92219089Spjd
93219089Spjd    len = hex_encode(data->data, data->length, p);
94219089Spjd    if (len < 0)
95219089Spjd	return ENOMEM;
96219089Spjd
97219089Spjd    if (data->negative) {
98219089Spjd	len = asprintf(&q, "-%s", *p);
99219089Spjd	free(*p);
100219089Spjd	if (len < 0)
101219089Spjd	    return ENOMEM;
102219089Spjd	*p = q;
103219089Spjd    }
104219089Spjd    return 0;
105219089Spjd}
106219089Spjd
107219089Spjdint
108219089Spjdder_print_heim_oid (const heim_oid *oid, char delim, char **str)
109219089Spjd{
110219089Spjd    struct rk_strpool *p = NULL;
111219089Spjd    size_t i;
112219089Spjd
113219089Spjd    if (oid->length == 0)
114219089Spjd	return EINVAL;
115219089Spjd
116219089Spjd    for (i = 0; i < oid->length ; i++) {
117219089Spjd	p = rk_strpoolprintf(p, "%d", oid->components[i]);
118219089Spjd	if (p && i < oid->length - 1)
119219089Spjd	    p = rk_strpoolprintf(p, "%c", delim);
120219089Spjd	if (p == NULL) {
121219089Spjd	    *str = NULL;
122219089Spjd	    return ENOMEM;
123219089Spjd	}
124219089Spjd    }
125219089Spjd
126219089Spjd    *str = rk_strpoolcollect(p);
127219089Spjd    if (*str == NULL)
128219089Spjd	return ENOMEM;
129219089Spjd    return 0;
130219089Spjd}
131219089Spjd
132219089Spjdint
133219089Spjdder_parse_heim_oid (const char *str, const char *sep, heim_oid *data)
134219089Spjd{
135219089Spjd    char *s, *w, *brkt, *endptr;
136219089Spjd    unsigned int *c;
137219089Spjd    long l;
138219089Spjd
139219089Spjd    data->length = 0;
140219089Spjd    data->components = NULL;
141219089Spjd
142219089Spjd    if (sep == NULL)
143219089Spjd	sep = ".";
144219089Spjd
145219089Spjd    s = strdup(str);
146219089Spjd
147219089Spjd    for (w = strtok_r(s, sep, &brkt);
148219089Spjd	 w != NULL;
149219089Spjd	 w = strtok_r(NULL, sep, &brkt)) {
150219089Spjd
151219089Spjd	c = realloc(data->components,
152219089Spjd		    (data->length + 1) * sizeof(data->components[0]));
153219089Spjd	if (c == NULL) {
154219089Spjd	    der_free_oid(data);
155219089Spjd	    free(s);
156219089Spjd	    return ENOMEM;
157219089Spjd	}
158219089Spjd	data->components = c;
159219089Spjd
160219089Spjd	l = strtol(w, &endptr, 10);
161219089Spjd	if (*endptr != '\0' || l < 0 || l > INT_MAX) {
162219089Spjd	    der_free_oid(data);
163219089Spjd	    free(s);
164219089Spjd	    return EINVAL;
165219089Spjd	}
166219089Spjd	data->components[data->length++] = l;
167219089Spjd    }
168219089Spjd    free(s);
169219089Spjd    return 0;
170219089Spjd}
171219089Spjd