]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/asn1/a_object.c
Consolidate to a single asn1_time_from_tm() function
[thirdparty/openssl.git] / crypto / asn1 / a_object.c
CommitLineData
2039c421
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
2039c421
RS
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6
RE
8 */
9
10#include <stdio.h>
452ae49d 11#include <limits.h>
cf37aaa3 12#include <ctype.h>
b39fc560 13#include "internal/cryptlib.h"
ec577822
BM
14#include <openssl/buffer.h>
15#include <openssl/asn1.h>
16#include <openssl/objects.h>
1e26a8ba 17#include <openssl/bn.h>
2e430277 18#include "internal/asn1_int.h"
c315a547 19#include "asn1_locl.h"
d02b48c6 20
e83f154f 21int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
0f113f3e
MC
22{
23 unsigned char *p;
24 int objsize;
d02b48c6 25
0f113f3e
MC
26 if ((a == NULL) || (a->data == NULL))
27 return (0);
d02b48c6 28
0f113f3e 29 objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
56f9953c 30 if (pp == NULL || objsize == -1)
0f113f3e 31 return objsize;
d02b48c6 32
0f113f3e
MC
33 p = *pp;
34 ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
35 memcpy(p, a->data, a->length);
36 p += a->length;
d02b48c6 37
0f113f3e
MC
38 *pp = p;
39 return (objsize);
40}
d02b48c6 41
6343829a 42int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
0f113f3e
MC
43{
44 int i, first, len = 0, c, use_bn;
45 char ftmp[24], *tmp = ftmp;
46 int tmpsize = sizeof ftmp;
47 const char *p;
48 unsigned long l;
49 BIGNUM *bl = NULL;
d02b48c6 50
0f113f3e
MC
51 if (num == 0)
52 return (0);
53 else if (num == -1)
54 num = strlen(buf);
d02b48c6 55
0f113f3e
MC
56 p = buf;
57 c = *(p++);
58 num--;
59 if ((c >= '0') && (c <= '2')) {
60 first = c - '0';
61 } else {
62 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
63 goto err;
64 }
d02b48c6 65
0f113f3e
MC
66 if (num <= 0) {
67 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
68 goto err;
69 }
70 c = *(p++);
71 num--;
72 for (;;) {
73 if (num <= 0)
74 break;
75 if ((c != '.') && (c != ' ')) {
76 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
77 goto err;
78 }
79 l = 0;
80 use_bn = 0;
81 for (;;) {
82 if (num <= 0)
83 break;
84 num--;
85 c = *(p++);
86 if ((c == ' ') || (c == '.'))
87 break;
cf37aaa3 88 if (!isdigit(c)) {
0f113f3e
MC
89 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
90 goto err;
91 }
92 if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
93 use_bn = 1;
90945fa3 94 if (bl == NULL)
0f113f3e 95 bl = BN_new();
90945fa3 96 if (bl == NULL || !BN_set_word(bl, l))
0f113f3e
MC
97 goto err;
98 }
99 if (use_bn) {
100 if (!BN_mul_word(bl, 10L)
101 || !BN_add_word(bl, c - '0'))
102 goto err;
103 } else
104 l = l * 10L + (long)(c - '0');
105 }
106 if (len == 0) {
107 if ((first < 2) && (l >= 40)) {
108 ASN1err(ASN1_F_A2D_ASN1_OBJECT,
109 ASN1_R_SECOND_NUMBER_TOO_LARGE);
110 goto err;
111 }
112 if (use_bn) {
113 if (!BN_add_word(bl, first * 40))
114 goto err;
115 } else
116 l += (long)first *40;
117 }
118 i = 0;
119 if (use_bn) {
120 int blsize;
121 blsize = BN_num_bits(bl);
122 blsize = (blsize + 6) / 7;
123 if (blsize > tmpsize) {
124 if (tmp != ftmp)
125 OPENSSL_free(tmp);
126 tmpsize = blsize + 32;
127 tmp = OPENSSL_malloc(tmpsize);
90945fa3 128 if (tmp == NULL)
0f113f3e
MC
129 goto err;
130 }
8b9afbc0
DSH
131 while (blsize--) {
132 BN_ULONG t = BN_div_word(bl, 0x80L);
133 if (t == (BN_ULONG)-1)
134 goto err;
135 tmp[i++] = (unsigned char)t;
136 }
0f113f3e 137 } else {
452ae49d 138
0f113f3e
MC
139 for (;;) {
140 tmp[i++] = (unsigned char)l & 0x7f;
141 l >>= 7L;
142 if (l == 0L)
143 break;
144 }
145
146 }
147 if (out != NULL) {
148 if (len + i > olen) {
149 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
150 goto err;
151 }
152 while (--i > 0)
153 out[len++] = tmp[i] | 0x80;
154 out[len++] = tmp[0];
155 } else
156 len += i;
157 }
158 if (tmp != ftmp)
159 OPENSSL_free(tmp);
23a1d5e9 160 BN_free(bl);
0f113f3e
MC
161 return (len);
162 err:
163 if (tmp != ftmp)
164 OPENSSL_free(tmp);
23a1d5e9 165 BN_free(bl);
0f113f3e
MC
166 return (0);
167}
d02b48c6 168
e83f154f 169int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
3e3d2ea2 170{
0f113f3e 171 return OBJ_obj2txt(buf, buf_len, a, 0);
3e3d2ea2 172}
58964a49 173
e83f154f 174int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
0f113f3e
MC
175{
176 char buf[80], *p = buf;
177 int i;
58964a49 178
0f113f3e
MC
179 if ((a == NULL) || (a->data == NULL))
180 return (BIO_write(bp, "NULL", 4));
181 i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
182 if (i > (int)(sizeof(buf) - 1)) {
183 p = OPENSSL_malloc(i + 1);
90945fa3 184 if (p == NULL)
0f113f3e
MC
185 return -1;
186 i2t_ASN1_OBJECT(p, i + 1, a);
187 }
188 if (i <= 0) {
189 i = BIO_write(bp, "<INVALID>", 9);
190 i += BIO_dump(bp, (const char *)a->data, a->length);
191 return i;
192 }
193 BIO_write(bp, p, i);
194 if (p != buf)
195 OPENSSL_free(p);
196 return (i);
197}
d02b48c6 198
875a644a 199ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
0f113f3e 200 long length)
284ef5f3 201{
0f113f3e
MC
202 const unsigned char *p;
203 long len;
204 int tag, xclass;
205 int inf, i;
206 ASN1_OBJECT *ret = NULL;
207 p = *pp;
208 inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
209 if (inf & 0x80) {
210 i = ASN1_R_BAD_OBJECT_HEADER;
211 goto err;
212 }
d02b48c6 213
0f113f3e
MC
214 if (tag != V_ASN1_OBJECT) {
215 i = ASN1_R_EXPECTING_AN_OBJECT;
216 goto err;
217 }
218 ret = c2i_ASN1_OBJECT(a, &p, len);
219 if (ret)
220 *pp = p;
221 return ret;
222 err:
223 ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
224 return (NULL);
284ef5f3 225}
0042fb5f 226
875a644a 227ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
0f113f3e
MC
228 long len)
229{
331bf00b 230 ASN1_OBJECT *ret = NULL, tobj;
0f113f3e
MC
231 const unsigned char *p;
232 unsigned char *data;
233 int i, length;
0042fb5f 234
0f113f3e
MC
235 /*
236 * Sanity check OID encoding. Need at least one content octet. MSB must
237 * be clear in the last octet. can't have leading 0x80 in subidentifiers,
238 * see: X.690 8.19.2
239 */
240 if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
241 p[len - 1] & 0x80) {
242 ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
243 return NULL;
244 }
245 /* Now 0 < len <= INT_MAX, so the cast is safe. */
246 length = (int)len;
331bf00b
DSH
247 /*
248 * Try to lookup OID in table: these are all valid encodings so if we get
249 * a match we know the OID is valid.
250 */
251 tobj.nid = NID_undef;
252 tobj.data = p;
253 tobj.length = length;
254 tobj.flags = 0;
255 i = OBJ_obj2nid(&tobj);
256 if (i != NID_undef) {
257 /*
258 * Return shared registered OID object: this improves efficiency
259 * because we don't have to return a dynamically allocated OID
260 * and NID lookups can use the cached value.
261 */
262 ret = OBJ_nid2obj(i);
263 if (a) {
264 ASN1_OBJECT_free(*a);
265 *a = ret;
266 }
267 *pp += len;
268 return ret;
269 }
0f113f3e
MC
270 for (i = 0; i < length; i++, p++) {
271 if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
272 ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
273 return NULL;
274 }
275 }
284ef5f3 276
0f113f3e
MC
277 /*
278 * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
279 * ->ln
280 */
281 if ((a == NULL) || ((*a) == NULL) ||
282 !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
283 if ((ret = ASN1_OBJECT_new()) == NULL)
284 return (NULL);
285 } else
286 ret = (*a);
284ef5f3 287
0f113f3e
MC
288 p = *pp;
289 /* detach data from object */
290 data = (unsigned char *)ret->data;
291 ret->data = NULL;
292 /* once detached we can change it */
293 if ((data == NULL) || (ret->length < length)) {
294 ret->length = 0;
b548a1f1 295 OPENSSL_free(data);
b196e7d9 296 data = OPENSSL_malloc(length);
0f113f3e
MC
297 if (data == NULL) {
298 i = ERR_R_MALLOC_FAILURE;
299 goto err;
300 }
301 ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
302 }
303 memcpy(data, p, length);
304 /* reattach data to object, after which it remains const */
305 ret->data = data;
306 ret->length = length;
307 ret->sn = NULL;
308 ret->ln = NULL;
309 /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
310 p += length;
d02b48c6 311
0f113f3e
MC
312 if (a != NULL)
313 (*a) = ret;
314 *pp = p;
315 return (ret);
316 err:
317 ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
2ace7450 318 if ((a == NULL) || (*a != ret))
0f113f3e
MC
319 ASN1_OBJECT_free(ret);
320 return (NULL);
321}
d02b48c6 322
6b691a5c 323ASN1_OBJECT *ASN1_OBJECT_new(void)
0f113f3e
MC
324{
325 ASN1_OBJECT *ret;
d02b48c6 326
64b25758 327 ret = OPENSSL_zalloc(sizeof(*ret));
0f113f3e
MC
328 if (ret == NULL) {
329 ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
330 return (NULL);
331 }
0f113f3e
MC
332 ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
333 return (ret);
334}
d02b48c6 335
6b691a5c 336void ASN1_OBJECT_free(ASN1_OBJECT *a)
0f113f3e
MC
337{
338 if (a == NULL)
339 return;
340 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
341#ifndef CONST_STRICT /* disable purely for compile-time strict
342 * const checking. Doing this on a "real"
343 * compile will cause memory leaks */
b548a1f1
RS
344 OPENSSL_free((void*)a->sn);
345 OPENSSL_free((void*)a->ln);
e778802f 346#endif
0f113f3e
MC
347 a->sn = a->ln = NULL;
348 }
349 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
b548a1f1 350 OPENSSL_free((void*)a->data);
0f113f3e
MC
351 a->data = NULL;
352 a->length = 0;
353 }
354 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
355 OPENSSL_free(a);
356}
d02b48c6 357
6343829a 358ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
0f113f3e
MC
359 const char *sn, const char *ln)
360{
361 ASN1_OBJECT o;
d02b48c6 362
0f113f3e
MC
363 o.sn = sn;
364 o.ln = ln;
365 o.data = data;
366 o.nid = nid;
367 o.length = len;
368 o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
369 ASN1_OBJECT_FLAG_DYNAMIC_DATA;
370 return (OBJ_dup(&o));
371}