1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young ([email protected]).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson ([email protected]).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young ([email protected])"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson ([email protected])"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57 #include <openssl/asn1.h>
58
59 #include <limits.h>
60 #include <string.h>
61
62 #include <openssl/bytestring.h>
63 #include <openssl/err.h>
64 #include <openssl/mem.h>
65 #include <openssl/obj.h>
66
67 #include "../bytestring/internal.h"
68 #include "../internal.h"
69 #include "internal.h"
70
71
i2d_ASN1_OBJECT(const ASN1_OBJECT * in,unsigned char ** outp)72 int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) {
73 if (in == NULL) {
74 OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER);
75 return -1;
76 }
77
78 if (in->length <= 0) {
79 OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
80 return -1;
81 }
82
83 CBB cbb, child;
84 if (!CBB_init(&cbb, (size_t)in->length + 2) ||
85 !CBB_add_asn1(&cbb, &child, CBS_ASN1_OBJECT) ||
86 !CBB_add_bytes(&child, in->data, in->length)) {
87 CBB_cleanup(&cbb);
88 return -1;
89 }
90
91 return CBB_finish_i2d(&cbb, outp);
92 }
93
i2t_ASN1_OBJECT(char * buf,int buf_len,const ASN1_OBJECT * a)94 int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) {
95 return OBJ_obj2txt(buf, buf_len, a, 0);
96 }
97
write_str(BIO * bp,const char * str)98 static int write_str(BIO *bp, const char *str) {
99 size_t len = strlen(str);
100 if (len > INT_MAX) {
101 OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
102 return -1;
103 }
104 return BIO_write(bp, str, (int)len) == (int)len ? (int)len : -1;
105 }
106
i2a_ASN1_OBJECT(BIO * bp,const ASN1_OBJECT * a)107 int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) {
108 if (a == NULL || a->data == NULL) {
109 return write_str(bp, "NULL");
110 }
111
112 char buf[80], *allocated = NULL;
113 const char *str = buf;
114 int len = i2t_ASN1_OBJECT(buf, sizeof(buf), a);
115 if (len > (int)sizeof(buf) - 1) {
116 // The input was truncated. Allocate a buffer that fits.
117 allocated = OPENSSL_malloc(len + 1);
118 if (allocated == NULL) {
119 return -1;
120 }
121 len = i2t_ASN1_OBJECT(allocated, len + 1, a);
122 str = allocated;
123 }
124 if (len <= 0) {
125 str = "<INVALID>";
126 }
127
128 int ret = write_str(bp, str);
129 OPENSSL_free(allocated);
130 return ret;
131 }
132
d2i_ASN1_OBJECT(ASN1_OBJECT ** out,const unsigned char ** inp,long len)133 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp,
134 long len) {
135 if (len < 0) {
136 return NULL;
137 }
138
139 CBS cbs, child;
140 CBS_init(&cbs, *inp, (size_t)len);
141 if (!CBS_get_asn1(&cbs, &child, CBS_ASN1_OBJECT)) {
142 OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
143 return NULL;
144 }
145
146 const uint8_t *contents = CBS_data(&child);
147 ASN1_OBJECT *ret = c2i_ASN1_OBJECT(out, &contents, CBS_len(&child));
148 if (ret != NULL) {
149 // |c2i_ASN1_OBJECT| should have consumed the entire input.
150 assert(CBS_data(&cbs) == contents);
151 *inp = CBS_data(&cbs);
152 }
153 return ret;
154 }
155
c2i_ASN1_OBJECT(ASN1_OBJECT ** out,const unsigned char ** inp,long len)156 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp,
157 long len) {
158 if (len < 0) {
159 OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
160 return NULL;
161 }
162
163 CBS cbs;
164 CBS_init(&cbs, *inp, (size_t)len);
165 if (!CBS_is_valid_asn1_oid(&cbs)) {
166 OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
167 return NULL;
168 }
169
170 ASN1_OBJECT *ret = ASN1_OBJECT_create(NID_undef, *inp, (size_t)len,
171 /*sn=*/NULL, /*ln=*/NULL);
172 if (ret == NULL) {
173 return NULL;
174 }
175
176 if (out != NULL) {
177 ASN1_OBJECT_free(*out);
178 *out = ret;
179 }
180 *inp += len; // All bytes were consumed.
181 return ret;
182 }
183
ASN1_OBJECT_new(void)184 ASN1_OBJECT *ASN1_OBJECT_new(void) {
185 ASN1_OBJECT *ret;
186
187 ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
188 if (ret == NULL) {
189 return NULL;
190 }
191 ret->length = 0;
192 ret->data = NULL;
193 ret->nid = 0;
194 ret->sn = NULL;
195 ret->ln = NULL;
196 ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
197 return ret;
198 }
199
ASN1_OBJECT_free(ASN1_OBJECT * a)200 void ASN1_OBJECT_free(ASN1_OBJECT *a) {
201 if (a == NULL) {
202 return;
203 }
204 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
205 OPENSSL_free((void *)a->sn);
206 OPENSSL_free((void *)a->ln);
207 a->sn = a->ln = NULL;
208 }
209 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
210 OPENSSL_free((void *)a->data);
211 a->data = NULL;
212 a->length = 0;
213 }
214 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) {
215 OPENSSL_free(a);
216 }
217 }
218
ASN1_OBJECT_create(int nid,const unsigned char * data,size_t len,const char * sn,const char * ln)219 ASN1_OBJECT *ASN1_OBJECT_create(int nid, const unsigned char *data, size_t len,
220 const char *sn, const char *ln) {
221 if (len > INT_MAX) {
222 OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
223 return NULL;
224 }
225
226 ASN1_OBJECT o;
227 o.sn = sn;
228 o.ln = ln;
229 o.data = data;
230 o.nid = nid;
231 o.length = (int)len;
232 o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
233 ASN1_OBJECT_FLAG_DYNAMIC_DATA;
234 return OBJ_dup(&o);
235 }
236