summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/x_name.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/x_name.c')
-rw-r--r--src/lib/libcrypto/asn1/x_name.c343
1 files changed, 167 insertions, 176 deletions
diff --git a/src/lib/libcrypto/asn1/x_name.c b/src/lib/libcrypto/asn1/x_name.c
index 1885d699ef..caece0f158 100644
--- a/src/lib/libcrypto/asn1/x_name.c
+++ b/src/lib/libcrypto/asn1/x_name.c
@@ -58,212 +58,203 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/objects.h> 61#include <openssl/asn1t.h>
62#include <openssl/asn1_mac.h>
63#include <openssl/x509.h> 62#include <openssl/x509.h>
64 63
65static int i2d_X509_NAME_entries(X509_NAME *a); 64static int x509_name_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it,
66int i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **pp) 65 int tag, int aclass, char opt, ASN1_TLC *ctx);
67 {
68 M_ASN1_I2D_vars(a);
69 66
70 M_ASN1_I2D_len(a->object,i2d_ASN1_OBJECT); 67static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
71 M_ASN1_I2D_len(a->value,i2d_ASN1_PRINTABLE); 68static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
69static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
72 70
73 M_ASN1_I2D_seq_total(); 71static int x509_name_encode(X509_NAME *a);
74 72
75 M_ASN1_I2D_put(a->object,i2d_ASN1_OBJECT); 73ASN1_SEQUENCE(X509_NAME_ENTRY) = {
76 M_ASN1_I2D_put(a->value,i2d_ASN1_PRINTABLE); 74 ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
75 ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
76} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
77 77
78 M_ASN1_I2D_finish(); 78IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
79 } 79IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
80 80
81X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, unsigned char **pp, 81/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
82 long length) 82 * so declare two template wrappers for this
83 { 83 */
84 M_ASN1_D2I_vars(a,X509_NAME_ENTRY *,X509_NAME_ENTRY_new);
85 84
86 M_ASN1_D2I_Init(); 85ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
87 M_ASN1_D2I_start_sequence(); 86 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
88 M_ASN1_D2I_get(ret->object,d2i_ASN1_OBJECT); 87ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
89 M_ASN1_D2I_get(ret->value,d2i_ASN1_PRINTABLE);
90 ret->set=0;
91 M_ASN1_D2I_Finish(a,X509_NAME_ENTRY_free,ASN1_F_D2I_X509_NAME_ENTRY);
92 }
93 88
94int i2d_X509_NAME(X509_NAME *a, unsigned char **pp) 89ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
95 { 90 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
96 int ret; 91ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
97 92
98 if (a == NULL) return(0); 93/* Normally that's where it would end: we'd have two nested STACK structures
99 if (a->modified) 94 * representing the ASN1. Unfortunately X509_NAME uses a completely different
100 { 95 * form and caches encodings so we have to process the internal form and convert
101 ret=i2d_X509_NAME_entries(a); 96 * to the external form.
102 if (ret < 0) return(ret); 97 */
103 }
104
105 ret=a->bytes->length;
106 if (pp != NULL)
107 {
108 memcpy(*pp,a->bytes->data,ret);
109 *pp+=ret;
110 }
111 return(ret);
112 }
113
114static int i2d_X509_NAME_entries(X509_NAME *a)
115 {
116 X509_NAME_ENTRY *ne,*fe=NULL;
117 STACK_OF(X509_NAME_ENTRY) *sk;
118 BUF_MEM *buf=NULL;
119 int set=0,r,ret=0;
120 int i;
121 unsigned char *p;
122 int size=0;
123 98
124 sk=a->entries; 99const ASN1_EXTERN_FUNCS x509_name_ff = {
125 for (i=0; i<sk_X509_NAME_ENTRY_num(sk); i++) 100 NULL,
126 { 101 x509_name_ex_new,
127 ne=sk_X509_NAME_ENTRY_value(sk,i); 102 x509_name_ex_free,
128 if (fe == NULL) 103 0, /* Default clear behaviour is OK */
129 { 104 x509_name_ex_d2i,
130 fe=ne; 105 x509_name_ex_i2d
131 size=0; 106};
132 } 107
108IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
109
110IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
111IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
112
113static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
114{
115 X509_NAME *ret = NULL;
116 ret = OPENSSL_malloc(sizeof(X509_NAME));
117 if(!ret) goto memerr;
118 if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
119 goto memerr;
120 if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
121 ret->modified=1;
122 *val = (ASN1_VALUE *)ret;
123 return 1;
133 124
134 if (ne->set != set) 125 memerr:
135 { 126 ASN1err(ASN1_F_X509_NAME_NEW, ERR_R_MALLOC_FAILURE);
136 ret+=ASN1_object_size(1,size,V_ASN1_SET); 127 if (ret)
137 fe->size=size;
138 fe=ne;
139 size=0;
140 set=ne->set;
141 }
142 size+=i2d_X509_NAME_ENTRY(ne,NULL);
143 }
144 if (fe != NULL)
145 { 128 {
146 /* SET OF needed only if entries is non empty */ 129 if (ret->entries)
147 ret+=ASN1_object_size(1,size,V_ASN1_SET); 130 sk_X509_NAME_ENTRY_free(ret->entries);
148 fe->size=size; 131 OPENSSL_free(ret);
149 } 132 }
133 return 0;
134}
150 135
151 r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); 136static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
152 137{
153 buf=a->bytes; 138 X509_NAME *a;
154 if (!BUF_MEM_grow(buf,r)) goto err; 139 if(!pval || !*pval)
155 p=(unsigned char *)buf->data; 140 return;
156 141 a = (X509_NAME *)*pval;
157 ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
158
159 set= -1;
160 for (i=0; i<sk_X509_NAME_ENTRY_num(sk); i++)
161 {
162 ne=sk_X509_NAME_ENTRY_value(sk,i);
163 if (set != ne->set)
164 {
165 set=ne->set;
166 ASN1_put_object(&p,1,ne->size,
167 V_ASN1_SET,V_ASN1_UNIVERSAL);
168 }
169 i2d_X509_NAME_ENTRY(ne,&p);
170 }
171 a->modified=0;
172 return(r);
173err:
174 return(-1);
175 }
176 142
177X509_NAME *d2i_X509_NAME(X509_NAME **a, unsigned char **pp, long length) 143 BUF_MEM_free(a->bytes);
178 { 144 sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
179 int set=0,i; 145 OPENSSL_free(a);
180 int idx=0; 146 *pval = NULL;
181 unsigned char *orig; 147}
182 M_ASN1_D2I_vars(a,X509_NAME *,X509_NAME_new);
183 148
184 orig= *pp; 149/* Used with sk_pop_free() to free up the internal representation.
185 if (sk_X509_NAME_ENTRY_num(ret->entries) > 0) 150 * NB: we only free the STACK and not its contents because it is
186 { 151 * already present in the X509_NAME structure.
187 while (sk_X509_NAME_ENTRY_num(ret->entries) > 0) 152 */
188 X509_NAME_ENTRY_free(
189 sk_X509_NAME_ENTRY_pop(ret->entries));
190 }
191 153
192 M_ASN1_D2I_Init(); 154static void sk_internal_free(void *a)
193 M_ASN1_D2I_start_sequence(); 155{
194 for (;;) 156 sk_free(a);
195 { 157}
196 if (M_ASN1_D2I_end_sequence()) break; 158
197 M_ASN1_D2I_get_set_type(X509_NAME_ENTRY,ret->entries, 159static int x509_name_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it,
198 d2i_X509_NAME_ENTRY, 160 int tag, int aclass, char opt, ASN1_TLC *ctx)
199 X509_NAME_ENTRY_free); 161{
200 for (; idx < sk_X509_NAME_ENTRY_num(ret->entries); idx++) 162 unsigned char *p = *in, *q;
201 { 163 STACK *intname = NULL;
202 sk_X509_NAME_ENTRY_value(ret->entries,idx)->set=set; 164 int i, j, ret;
203 } 165 X509_NAME *nm = NULL;
204 set++; 166 STACK_OF(X509_NAME_ENTRY) *entries;
167 X509_NAME_ENTRY *entry;
168 q = p;
169
170 /* Get internal representation of Name */
171 ret = ASN1_item_ex_d2i((ASN1_VALUE **)&intname, &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
172 tag, aclass, opt, ctx);
173
174 if(ret <= 0) return ret;
175
176 if(*val) x509_name_ex_free(val, NULL);
177 if(!x509_name_ex_new((ASN1_VALUE **)&nm, NULL)) goto err;
178 /* We've decoded it: now cache encoding */
179 if(!BUF_MEM_grow(nm->bytes, p - q)) goto err;
180 memcpy(nm->bytes->data, q, p - q);
181
182 /* Convert internal representation to X509_NAME structure */
183 for(i = 0; i < sk_num(intname); i++) {
184 entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname, i);
185 for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
186 entry = sk_X509_NAME_ENTRY_value(entries, j);
187 entry->set = i;
188 if(!sk_X509_NAME_ENTRY_push(nm->entries, entry))
189 goto err;
205 } 190 }
206 191 sk_X509_NAME_ENTRY_free(entries);
207 i=(int)(c.p-orig);
208 if (!BUF_MEM_grow(ret->bytes,i)) goto err;
209 memcpy(ret->bytes->data,orig,i);
210 ret->bytes->length=i;
211 ret->modified=0;
212
213 M_ASN1_D2I_Finish(a,X509_NAME_free,ASN1_F_D2I_X509_NAME);
214 } 192 }
215 193 sk_free(intname);
216X509_NAME *X509_NAME_new(void) 194 nm->modified = 0;
217 { 195 *val = (ASN1_VALUE *)nm;
218 X509_NAME *ret=NULL; 196 *in = p;
219 ASN1_CTX c; 197 return ret;
220 198 err:
221 M_ASN1_New_Malloc(ret,X509_NAME); 199 ASN1err(ASN1_F_D2I_X509_NAME, ERR_R_NESTED_ASN1_ERROR);
222 if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) 200 return 0;
223 { c.line=__LINE__; goto err2; } 201}
224 M_ASN1_New(ret->bytes,BUF_MEM_new); 202
225 ret->modified=1; 203static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
226 return(ret); 204{
227 M_ASN1_New_Error(ASN1_F_X509_NAME_NEW); 205 int ret;
206 X509_NAME *a = (X509_NAME *)*val;
207 if(a->modified) {
208 ret = x509_name_encode((X509_NAME *)a);
209 if(ret < 0) return ret;
228 } 210 }
229 211 ret = a->bytes->length;
230X509_NAME_ENTRY *X509_NAME_ENTRY_new(void) 212 if(out != NULL) {
231 { 213 memcpy(*out,a->bytes->data,ret);
232 X509_NAME_ENTRY *ret=NULL; 214 *out+=ret;
233 ASN1_CTX c;
234
235 M_ASN1_New_Malloc(ret,X509_NAME_ENTRY);
236/* M_ASN1_New(ret->object,ASN1_OBJECT_new);*/
237 ret->object=NULL;
238 ret->set=0;
239 M_ASN1_New(ret->value,ASN1_STRING_new);
240 return(ret);
241 M_ASN1_New_Error(ASN1_F_X509_NAME_ENTRY_NEW);
242 } 215 }
216 return ret;
217}
243 218
244void X509_NAME_free(X509_NAME *a) 219static int x509_name_encode(X509_NAME *a)
245 { 220{
246 if(a == NULL) 221 STACK *intname = NULL;
247 return; 222 int len;
248 223 unsigned char *p;
249 BUF_MEM_free(a->bytes); 224 STACK_OF(X509_NAME_ENTRY) *entries = NULL;
250 sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); 225 X509_NAME_ENTRY *entry;
251 OPENSSL_free(a); 226 int i, set = -1;
227 intname = sk_new_null();
228 if(!intname) goto memerr;
229 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
230 entry = sk_X509_NAME_ENTRY_value(a->entries, i);
231 if(entry->set != set) {
232 entries = sk_X509_NAME_ENTRY_new_null();
233 if(!entries) goto memerr;
234 if(!sk_push(intname, (char *)entries)) goto memerr;
235 set = entry->set;
236 }
237 if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
252 } 238 }
239 len = ASN1_item_ex_i2d((ASN1_VALUE **)&intname, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
240 if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
241 p=(unsigned char *)a->bytes->data;
242 ASN1_item_ex_i2d((ASN1_VALUE **)&intname, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
243 sk_pop_free(intname, sk_internal_free);
244 a->modified = 0;
245 return len;
246 memerr:
247 sk_pop_free(intname, sk_internal_free);
248 ASN1err(ASN1_F_D2I_X509_NAME, ERR_R_MALLOC_FAILURE);
249 return -1;
250}
253 251
254void X509_NAME_ENTRY_free(X509_NAME_ENTRY *a)
255 {
256 if (a == NULL) return;
257 ASN1_OBJECT_free(a->object);
258 M_ASN1_BIT_STRING_free(a->value);
259 OPENSSL_free(a);
260 }
261 252
262int X509_NAME_set(X509_NAME **xn, X509_NAME *name) 253int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
263 { 254 {
264 X509_NAME *in; 255 X509_NAME *in;
265 256
266 if (*xn == NULL) return(0); 257 if (!xn || !name) return(0);
267 258
268 if (*xn != name) 259 if (*xn != name)
269 { 260 {