OLD | NEW |
1 /* crypto/asn1/x_name.c */ | 1 /* crypto/asn1/x_name.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
51 * SUCH DAMAGE. | 51 * SUCH DAMAGE. |
52 * | 52 * |
53 * The licence and distribution terms for any publically available version or | 53 * The licence and distribution terms for any publically available version or |
54 * derivative of this code cannot be changed. i.e. this code cannot simply be | 54 * derivative of this code cannot be changed. i.e. this code cannot simply be |
55 * copied and put under another distribution licence | 55 * copied and put under another distribution licence |
56 * [including the GNU Public Licence.] | 56 * [including the GNU Public Licence.] |
57 */ | 57 */ |
58 | 58 |
59 #include <stdio.h> | 59 #include <stdio.h> |
| 60 #include <ctype.h> |
60 #include "cryptlib.h" | 61 #include "cryptlib.h" |
61 #include <openssl/asn1t.h> | 62 #include <openssl/asn1t.h> |
62 #include <openssl/x509.h> | 63 #include <openssl/x509.h> |
| 64 #include "asn1_locl.h" |
63 | 65 |
64 static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len
, const ASN1_ITEM *it, | 66 typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; |
65 » » » » » int tag, int aclass, char opt, ASN1_TLC
*ctx); | 67 DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) |
66 | 68 |
67 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT
EM *it, int tag, int aclass); | 69 static int x509_name_ex_d2i(ASN1_VALUE **val, |
| 70 » » » » const unsigned char **in, long len, |
| 71 » » » » const ASN1_ITEM *it, |
| 72 » » » » int tag, int aclass, char opt, ASN1_TLC *ctx); |
| 73 |
| 74 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, |
| 75 » » » » const ASN1_ITEM *it, int tag, int aclass); |
68 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); | 76 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); |
69 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); | 77 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); |
70 | 78 |
71 static int x509_name_encode(X509_NAME *a); | 79 static int x509_name_encode(X509_NAME *a); |
| 80 static int x509_name_canon(X509_NAME *a); |
| 81 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); |
| 82 static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname, |
| 83 unsigned char **in); |
| 84 |
| 85 |
| 86 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, |
| 87 int indent, |
| 88 const char *fname, |
| 89 const ASN1_PCTX *pctx); |
72 | 90 |
73 ASN1_SEQUENCE(X509_NAME_ENTRY) = { | 91 ASN1_SEQUENCE(X509_NAME_ENTRY) = { |
74 ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), | 92 ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), |
75 ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) | 93 ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) |
76 } ASN1_SEQUENCE_END(X509_NAME_ENTRY) | 94 } ASN1_SEQUENCE_END(X509_NAME_ENTRY) |
77 | 95 |
78 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) | 96 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) |
79 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) | 97 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) |
80 | 98 |
81 /* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } | 99 /* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } |
(...skipping 13 matching lines...) Expand all Loading... |
95 * form and caches encodings so we have to process the internal form and convert | 113 * form and caches encodings so we have to process the internal form and convert |
96 * to the external form. | 114 * to the external form. |
97 */ | 115 */ |
98 | 116 |
99 const ASN1_EXTERN_FUNCS x509_name_ff = { | 117 const ASN1_EXTERN_FUNCS x509_name_ff = { |
100 NULL, | 118 NULL, |
101 x509_name_ex_new, | 119 x509_name_ex_new, |
102 x509_name_ex_free, | 120 x509_name_ex_free, |
103 0, /* Default clear behaviour is OK */ | 121 0, /* Default clear behaviour is OK */ |
104 x509_name_ex_d2i, | 122 x509_name_ex_d2i, |
105 » x509_name_ex_i2d | 123 » x509_name_ex_i2d, |
| 124 » x509_name_ex_print |
106 }; | 125 }; |
107 | 126 |
108 IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) | 127 IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) |
109 | 128 |
110 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) | 129 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) |
111 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) | 130 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) |
112 | 131 |
113 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) | 132 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) |
114 { | 133 { |
115 X509_NAME *ret = NULL; | 134 X509_NAME *ret = NULL; |
116 ret = OPENSSL_malloc(sizeof(X509_NAME)); | 135 ret = OPENSSL_malloc(sizeof(X509_NAME)); |
117 if(!ret) goto memerr; | 136 if(!ret) goto memerr; |
118 if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) | 137 if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) |
119 goto memerr; | 138 goto memerr; |
120 if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr; | 139 if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr; |
| 140 ret->canon_enc = NULL; |
| 141 ret->canon_enclen = 0; |
121 ret->modified=1; | 142 ret->modified=1; |
122 *val = (ASN1_VALUE *)ret; | 143 *val = (ASN1_VALUE *)ret; |
123 return 1; | 144 return 1; |
124 | 145 |
125 memerr: | 146 memerr: |
126 ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); | 147 ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); |
127 if (ret) | 148 if (ret) |
128 { | 149 { |
129 if (ret->entries) | 150 if (ret->entries) |
130 sk_X509_NAME_ENTRY_free(ret->entries); | 151 sk_X509_NAME_ENTRY_free(ret->entries); |
131 OPENSSL_free(ret); | 152 OPENSSL_free(ret); |
132 } | 153 } |
133 return 0; | 154 return 0; |
134 } | 155 } |
135 | 156 |
136 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | 157 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) |
137 { | 158 { |
138 X509_NAME *a; | 159 X509_NAME *a; |
139 if(!pval || !*pval) | 160 if(!pval || !*pval) |
140 return; | 161 return; |
141 a = (X509_NAME *)*pval; | 162 a = (X509_NAME *)*pval; |
142 | 163 |
143 BUF_MEM_free(a->bytes); | 164 BUF_MEM_free(a->bytes); |
144 sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); | 165 sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); |
| 166 if (a->canon_enc) |
| 167 OPENSSL_free(a->canon_enc); |
145 OPENSSL_free(a); | 168 OPENSSL_free(a); |
146 *pval = NULL; | 169 *pval = NULL; |
147 } | 170 } |
148 | 171 |
149 /* Used with sk_pop_free() to free up the internal representation. | 172 static int x509_name_ex_d2i(ASN1_VALUE **val, |
150 * NB: we only free the STACK and not its contents because it is | 173 » » » const unsigned char **in, long len, const ASN1_ITEM *it, |
151 * already present in the X509_NAME structure. | 174 » » » » int tag, int aclass, char opt, ASN1_TLC *ctx) |
152 */ | |
153 | |
154 static void sk_internal_free(void *a) | |
155 { | |
156 » sk_free(a); | |
157 } | |
158 | |
159 static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len
, const ASN1_ITEM *it, | |
160 » » » » » int tag, int aclass, char opt, ASN1_TLC
*ctx) | |
161 { | 175 { |
162 const unsigned char *p = *in, *q; | 176 const unsigned char *p = *in, *q; |
163 » union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; | 177 » union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; |
| 178 » » ASN1_VALUE *a; } intname = {NULL}; |
164 union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; | 179 union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; |
165 int i, j, ret; | 180 int i, j, ret; |
166 STACK_OF(X509_NAME_ENTRY) *entries; | 181 STACK_OF(X509_NAME_ENTRY) *entries; |
167 X509_NAME_ENTRY *entry; | 182 X509_NAME_ENTRY *entry; |
168 q = p; | 183 q = p; |
169 | 184 |
170 /* Get internal representation of Name */ | 185 /* Get internal representation of Name */ |
171 ret = ASN1_item_ex_d2i(&intname.a, | 186 ret = ASN1_item_ex_d2i(&intname.a, |
172 &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), | 187 &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), |
173 tag, aclass, opt, ctx); | 188 tag, aclass, opt, ctx); |
174 | 189 |
175 if(ret <= 0) return ret; | 190 if(ret <= 0) return ret; |
176 | 191 |
177 if(*val) x509_name_ex_free(val, NULL); | 192 if(*val) x509_name_ex_free(val, NULL); |
178 if(!x509_name_ex_new(&nm.a, NULL)) goto err; | 193 if(!x509_name_ex_new(&nm.a, NULL)) goto err; |
179 /* We've decoded it: now cache encoding */ | 194 /* We've decoded it: now cache encoding */ |
180 if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err; | 195 if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err; |
181 memcpy(nm.x->bytes->data, q, p - q); | 196 memcpy(nm.x->bytes->data, q, p - q); |
182 | 197 |
183 /* Convert internal representation to X509_NAME structure */ | 198 /* Convert internal representation to X509_NAME structure */ |
184 » for(i = 0; i < sk_num(intname.s); i++) { | 199 » for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { |
185 » » entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i); | 200 » » entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); |
186 for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { | 201 for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { |
187 entry = sk_X509_NAME_ENTRY_value(entries, j); | 202 entry = sk_X509_NAME_ENTRY_value(entries, j); |
188 entry->set = i; | 203 entry->set = i; |
189 if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) | 204 if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) |
190 goto err; | 205 goto err; |
191 } | 206 } |
192 sk_X509_NAME_ENTRY_free(entries); | 207 sk_X509_NAME_ENTRY_free(entries); |
193 } | 208 } |
194 » sk_free(intname.s); | 209 » sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); |
| 210 » ret = x509_name_canon(nm.x); |
| 211 » if (!ret) |
| 212 » » goto err; |
195 nm.x->modified = 0; | 213 nm.x->modified = 0; |
196 *val = nm.a; | 214 *val = nm.a; |
197 *in = p; | 215 *in = p; |
198 return ret; | 216 return ret; |
199 » err: | 217 err: |
| 218 if (nm.x != NULL) |
| 219 » » X509_NAME_free(nm.x); |
200 ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | 220 ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); |
201 return 0; | 221 return 0; |
202 } | 222 } |
203 | 223 |
204 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT
EM *it, int tag, int aclass) | 224 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT
EM *it, int tag, int aclass) |
205 { | 225 { |
206 int ret; | 226 int ret; |
207 X509_NAME *a = (X509_NAME *)*val; | 227 X509_NAME *a = (X509_NAME *)*val; |
208 if(a->modified) { | 228 if(a->modified) { |
209 » » ret = x509_name_encode((X509_NAME *)a); | 229 » » ret = x509_name_encode(a); |
210 » » if(ret < 0) return ret; | 230 » » if(ret < 0) |
| 231 » » » return ret; |
| 232 » » ret = x509_name_canon(a); |
| 233 » » if(ret < 0) |
| 234 » » » return ret; |
211 } | 235 } |
212 ret = a->bytes->length; | 236 ret = a->bytes->length; |
213 if(out != NULL) { | 237 if(out != NULL) { |
214 memcpy(*out,a->bytes->data,ret); | 238 memcpy(*out,a->bytes->data,ret); |
215 *out+=ret; | 239 *out+=ret; |
216 } | 240 } |
217 return ret; | 241 return ret; |
218 } | 242 } |
219 | 243 |
| 244 static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) |
| 245 { |
| 246 sk_X509_NAME_ENTRY_free(ne); |
| 247 } |
| 248 |
| 249 static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) |
| 250 { |
| 251 sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); |
| 252 } |
| 253 |
220 static int x509_name_encode(X509_NAME *a) | 254 static int x509_name_encode(X509_NAME *a) |
221 { | 255 { |
222 » union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; | 256 » union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; |
| 257 » » ASN1_VALUE *a; } intname = {NULL}; |
223 int len; | 258 int len; |
224 unsigned char *p; | 259 unsigned char *p; |
225 STACK_OF(X509_NAME_ENTRY) *entries = NULL; | 260 STACK_OF(X509_NAME_ENTRY) *entries = NULL; |
226 X509_NAME_ENTRY *entry; | 261 X509_NAME_ENTRY *entry; |
227 int i, set = -1; | 262 int i, set = -1; |
228 » intname.s = sk_new_null(); | 263 » intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); |
229 if(!intname.s) goto memerr; | 264 if(!intname.s) goto memerr; |
230 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { | 265 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { |
231 entry = sk_X509_NAME_ENTRY_value(a->entries, i); | 266 entry = sk_X509_NAME_ENTRY_value(a->entries, i); |
232 if(entry->set != set) { | 267 if(entry->set != set) { |
233 entries = sk_X509_NAME_ENTRY_new_null(); | 268 entries = sk_X509_NAME_ENTRY_new_null(); |
234 if(!entries) goto memerr; | 269 if(!entries) goto memerr; |
235 » » » if(!sk_push(intname.s, (char *)entries)) goto memerr; | 270 » » » if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, |
| 271 » » » » » » » entries)) |
| 272 » » » » goto memerr; |
236 set = entry->set; | 273 set = entry->set; |
237 } | 274 } |
238 if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; | 275 if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; |
239 } | 276 } |
240 len = ASN1_item_ex_i2d(&intname.a, NULL, | 277 len = ASN1_item_ex_i2d(&intname.a, NULL, |
241 ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); | 278 ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); |
242 if (!BUF_MEM_grow(a->bytes,len)) goto memerr; | 279 if (!BUF_MEM_grow(a->bytes,len)) goto memerr; |
243 p=(unsigned char *)a->bytes->data; | 280 p=(unsigned char *)a->bytes->data; |
244 ASN1_item_ex_i2d(&intname.a, | 281 ASN1_item_ex_i2d(&intname.a, |
245 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); | 282 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); |
246 » sk_pop_free(intname.s, sk_internal_free); | 283 » sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, |
| 284 » » » » » local_sk_X509_NAME_ENTRY_free); |
247 a->modified = 0; | 285 a->modified = 0; |
248 return len; | 286 return len; |
249 » memerr: | 287 memerr: |
250 » sk_pop_free(intname.s, sk_internal_free); | 288 » sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, |
| 289 » » » » » local_sk_X509_NAME_ENTRY_free); |
251 ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); | 290 ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); |
252 return -1; | 291 return -1; |
253 } | 292 } |
254 | 293 |
| 294 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, |
| 295 int indent, |
| 296 const char *fname, |
| 297 const ASN1_PCTX *pctx) |
| 298 { |
| 299 if (X509_NAME_print_ex(out, (X509_NAME *)*pval, |
| 300 indent, pctx->nm_flags) <= 0) |
| 301 return 0; |
| 302 return 2; |
| 303 } |
| 304 |
| 305 /* This function generates the canonical encoding of the Name structure. |
| 306 * In it all strings are converted to UTF8, leading, trailing and |
| 307 * multiple spaces collapsed, converted to lower case and the leading |
| 308 * SEQUENCE header removed. |
| 309 * |
| 310 * In future we could also normalize the UTF8 too. |
| 311 * |
| 312 * By doing this comparison of Name structures can be rapidly |
| 313 * perfomed by just using memcmp() of the canonical encoding. |
| 314 * By omitting the leading SEQUENCE name constraints of type |
| 315 * dirName can also be checked with a simple memcmp(). |
| 316 */ |
| 317 |
| 318 static int x509_name_canon(X509_NAME *a) |
| 319 { |
| 320 unsigned char *p; |
| 321 STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; |
| 322 STACK_OF(X509_NAME_ENTRY) *entries = NULL; |
| 323 X509_NAME_ENTRY *entry, *tmpentry = NULL; |
| 324 int i, set = -1, ret = 0; |
| 325 |
| 326 if (a->canon_enc) |
| 327 { |
| 328 OPENSSL_free(a->canon_enc); |
| 329 a->canon_enc = NULL; |
| 330 } |
| 331 /* Special case: empty X509_NAME => null encoding */ |
| 332 if (sk_X509_NAME_ENTRY_num(a->entries) == 0) |
| 333 { |
| 334 a->canon_enclen = 0; |
| 335 return 1; |
| 336 } |
| 337 intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); |
| 338 if(!intname) |
| 339 goto err; |
| 340 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) |
| 341 { |
| 342 entry = sk_X509_NAME_ENTRY_value(a->entries, i); |
| 343 if(entry->set != set) |
| 344 { |
| 345 entries = sk_X509_NAME_ENTRY_new_null(); |
| 346 if(!entries) |
| 347 goto err; |
| 348 if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) |
| 349 goto err; |
| 350 set = entry->set; |
| 351 } |
| 352 tmpentry = X509_NAME_ENTRY_new(); |
| 353 tmpentry->object = OBJ_dup(entry->object); |
| 354 if (!asn1_string_canon(tmpentry->value, entry->value)) |
| 355 goto err; |
| 356 if(!sk_X509_NAME_ENTRY_push(entries, tmpentry)) |
| 357 goto err; |
| 358 tmpentry = NULL; |
| 359 } |
| 360 |
| 361 /* Finally generate encoding */ |
| 362 |
| 363 a->canon_enclen = i2d_name_canon(intname, NULL); |
| 364 |
| 365 p = OPENSSL_malloc(a->canon_enclen); |
| 366 |
| 367 if (!p) |
| 368 goto err; |
| 369 |
| 370 a->canon_enc = p; |
| 371 |
| 372 i2d_name_canon(intname, &p); |
| 373 |
| 374 ret = 1; |
| 375 |
| 376 err: |
| 377 |
| 378 if (tmpentry) |
| 379 X509_NAME_ENTRY_free(tmpentry); |
| 380 if (intname) |
| 381 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, |
| 382 local_sk_X509_NAME_ENTRY_pop_free); |
| 383 return ret; |
| 384 } |
| 385 |
| 386 /* Bitmap of all the types of string that will be canonicalized. */ |
| 387 |
| 388 #define ASN1_MASK_CANON \ |
| 389 (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ |
| 390 | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ |
| 391 | B_ASN1_VISIBLESTRING) |
| 392 |
| 393 |
| 394 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) |
| 395 { |
| 396 unsigned char *to, *from; |
| 397 int len, i; |
| 398 |
| 399 /* If type not in bitmask just copy string across */ |
| 400 if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) |
| 401 { |
| 402 out->type = in->type; |
| 403 if (!ASN1_STRING_set(out, in->data, in->length)) |
| 404 return 0; |
| 405 return 1; |
| 406 } |
| 407 |
| 408 out->type = V_ASN1_UTF8STRING; |
| 409 out->length = ASN1_STRING_to_UTF8(&out->data, in); |
| 410 if (out->length == -1) |
| 411 return 0; |
| 412 |
| 413 to = out->data; |
| 414 from = to; |
| 415 |
| 416 len = out->length; |
| 417 |
| 418 /* Convert string in place to canonical form. |
| 419 * Ultimately we may need to handle a wider range of characters |
| 420 * but for now ignore anything with MSB set and rely on the |
| 421 * isspace() and tolower() functions. |
| 422 */ |
| 423 |
| 424 /* Ignore leading spaces */ |
| 425 while((len > 0) && !(*from & 0x80) && isspace(*from)) |
| 426 { |
| 427 from++; |
| 428 len--; |
| 429 } |
| 430 |
| 431 to = from + len - 1; |
| 432 |
| 433 /* Ignore trailing spaces */ |
| 434 while ((len > 0) && !(*to & 0x80) && isspace(*to)) |
| 435 { |
| 436 to--; |
| 437 len--; |
| 438 } |
| 439 |
| 440 to = out->data; |
| 441 |
| 442 i = 0; |
| 443 while(i < len) |
| 444 { |
| 445 /* If MSB set just copy across */ |
| 446 if (*from & 0x80) |
| 447 { |
| 448 *to++ = *from++; |
| 449 i++; |
| 450 } |
| 451 /* Collapse multiple spaces */ |
| 452 else if (isspace(*from)) |
| 453 { |
| 454 /* Copy one space across */ |
| 455 *to++ = ' '; |
| 456 /* Ignore subsequent spaces. Note: don't need to |
| 457 * check len here because we know the last |
| 458 * character is a non-space so we can't overflow. |
| 459 */ |
| 460 do |
| 461 { |
| 462 from++; |
| 463 i++; |
| 464 } |
| 465 while(!(*from & 0x80) && isspace(*from)); |
| 466 } |
| 467 else |
| 468 { |
| 469 *to++ = tolower(*from); |
| 470 from++; |
| 471 i++; |
| 472 } |
| 473 } |
| 474 |
| 475 out->length = to - out->data; |
| 476 |
| 477 return 1; |
| 478 |
| 479 } |
| 480 |
| 481 static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, |
| 482 unsigned char **in) |
| 483 { |
| 484 int i, len, ltmp; |
| 485 ASN1_VALUE *v; |
| 486 STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; |
| 487 |
| 488 len = 0; |
| 489 for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) |
| 490 { |
| 491 v = sk_ASN1_VALUE_value(intname, i); |
| 492 ltmp = ASN1_item_ex_i2d(&v, in, |
| 493 ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); |
| 494 if (ltmp < 0) |
| 495 return ltmp; |
| 496 len += ltmp; |
| 497 } |
| 498 return len; |
| 499 } |
255 | 500 |
256 int X509_NAME_set(X509_NAME **xn, X509_NAME *name) | 501 int X509_NAME_set(X509_NAME **xn, X509_NAME *name) |
257 { | 502 { |
258 X509_NAME *in; | 503 X509_NAME *in; |
259 | 504 |
260 if (!xn || !name) return(0); | 505 if (!xn || !name) return(0); |
261 | 506 |
262 if (*xn != name) | 507 if (*xn != name) |
263 { | 508 { |
264 in=X509_NAME_dup(name); | 509 in=X509_NAME_dup(name); |
265 if (in != NULL) | 510 if (in != NULL) |
266 { | 511 { |
267 X509_NAME_free(*xn); | 512 X509_NAME_free(*xn); |
268 *xn=in; | 513 *xn=in; |
269 } | 514 } |
270 } | 515 } |
271 return(*xn != NULL); | 516 return(*xn != NULL); |
272 } | 517 } |
273 | 518 |
274 IMPLEMENT_STACK_OF(X509_NAME_ENTRY) | 519 IMPLEMENT_STACK_OF(X509_NAME_ENTRY) |
275 IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) | 520 IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) |
OLD | NEW |