diff options
Diffstat (limited to 'openssl/crypto/asn1/x_name.c')
-rw-r--r-- | openssl/crypto/asn1/x_name.c | 776 |
1 files changed, 391 insertions, 385 deletions
diff --git a/openssl/crypto/asn1/x_name.c b/openssl/crypto/asn1/x_name.c index 22da57040..737c426f2 100644 --- a/openssl/crypto/asn1/x_name.c +++ b/openssl/crypto/asn1/x_name.c @@ -5,21 +5,21 @@ * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. - * + * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * + * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -34,10 +34,10 @@ * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from + * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * + * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -49,7 +49,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence @@ -67,455 +67,461 @@ typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) static int x509_name_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass); + const ASN1_ITEM *it, int tag, int aclass); static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); static int x509_name_encode(X509_NAME *a); static int x509_name_canon(X509_NAME *a); static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname, - unsigned char **in); - +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, + unsigned char **in); static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, - int indent, - const char *fname, - const ASN1_PCTX *pctx); + int indent, + const char *fname, const ASN1_PCTX *pctx); ASN1_SEQUENCE(X509_NAME_ENTRY) = { - ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), - ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) + ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), + ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) } ASN1_SEQUENCE_END(X509_NAME_ENTRY) IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) -/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } - * so declare two template wrappers for this +/* + * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so + * declare two template wrappers for this */ ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) -/* Normally that's where it would end: we'd have two nested STACK structures +/* + * Normally that's where it would end: we'd have two nested STACK structures * representing the ASN1. Unfortunately X509_NAME uses a completely different - * form and caches encodings so we have to process the internal form and convert - * to the external form. + * form and caches encodings so we have to process the internal form and + * convert to the external form. */ const ASN1_EXTERN_FUNCS x509_name_ff = { - NULL, - x509_name_ex_new, - x509_name_ex_free, - 0, /* Default clear behaviour is OK */ - x509_name_ex_d2i, - x509_name_ex_i2d, - x509_name_ex_print + NULL, + x509_name_ex_new, + x509_name_ex_free, + 0, /* Default clear behaviour is OK */ + x509_name_ex_d2i, + x509_name_ex_i2d, + x509_name_ex_print }; -IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) +IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) + IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) { - X509_NAME *ret = NULL; - ret = OPENSSL_malloc(sizeof(X509_NAME)); - if(!ret) goto memerr; - if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) - goto memerr; - if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr; - ret->canon_enc = NULL; - ret->canon_enclen = 0; - ret->modified=1; - *val = (ASN1_VALUE *)ret; - return 1; + X509_NAME *ret = NULL; + ret = OPENSSL_malloc(sizeof(X509_NAME)); + if (!ret) + goto memerr; + if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) + goto memerr; + if ((ret->bytes = BUF_MEM_new()) == NULL) + goto memerr; + ret->canon_enc = NULL; + ret->canon_enclen = 0; + ret->modified = 1; + *val = (ASN1_VALUE *)ret; + return 1; memerr: - ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); - if (ret) - { - if (ret->entries) - sk_X509_NAME_ENTRY_free(ret->entries); - OPENSSL_free(ret); - } - return 0; + ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); + if (ret) { + if (ret->entries) + sk_X509_NAME_ENTRY_free(ret->entries); + OPENSSL_free(ret); + } + return 0; } static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - X509_NAME *a; - if(!pval || !*pval) - return; - a = (X509_NAME *)*pval; - - BUF_MEM_free(a->bytes); - sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); - if (a->canon_enc) - OPENSSL_free(a->canon_enc); - OPENSSL_free(a); - *pval = NULL; + X509_NAME *a; + if (!pval || !*pval) + return; + a = (X509_NAME *)*pval; + + BUF_MEM_free(a->bytes); + sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); + if (a->canon_enc) + OPENSSL_free(a->canon_enc); + OPENSSL_free(a); + *pval = NULL; } static int x509_name_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) + const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx) { - const unsigned char *p = *in, *q; - union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; - ASN1_VALUE *a; } intname = {NULL}; - union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; - int i, j, ret; - STACK_OF(X509_NAME_ENTRY) *entries; - X509_NAME_ENTRY *entry; - q = p; - - /* Get internal representation of Name */ - ret = ASN1_item_ex_d2i(&intname.a, - &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), - tag, aclass, opt, ctx); - - if(ret <= 0) return ret; - - if(*val) x509_name_ex_free(val, NULL); - if(!x509_name_ex_new(&nm.a, NULL)) goto err; - /* We've decoded it: now cache encoding */ - if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err; - memcpy(nm.x->bytes->data, q, p - q); - - /* Convert internal representation to X509_NAME structure */ - for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { - entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); - for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { - entry = sk_X509_NAME_ENTRY_value(entries, j); - entry->set = i; - if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) - goto err; - } - sk_X509_NAME_ENTRY_free(entries); - } - sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); - ret = x509_name_canon(nm.x); - if (!ret) - goto err; - nm.x->modified = 0; - *val = nm.a; - *in = p; - return ret; -err: - if (nm.x != NULL) - X509_NAME_free(nm.x); - ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - return 0; + const unsigned char *p = *in, *q; + union { + STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; + } intname = { + NULL + }; + union { + X509_NAME *x; + ASN1_VALUE *a; + } nm = { + NULL + }; + int i, j, ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + q = p; + + /* Get internal representation of Name */ + ret = ASN1_item_ex_d2i(&intname.a, + &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + tag, aclass, opt, ctx); + + if (ret <= 0) + return ret; + + if (*val) + x509_name_ex_free(val, NULL); + if (!x509_name_ex_new(&nm.a, NULL)) + goto err; + /* We've decoded it: now cache encoding */ + if (!BUF_MEM_grow(nm.x->bytes, p - q)) + goto err; + memcpy(nm.x->bytes->data, q, p - q); + + /* Convert internal representation to X509_NAME structure */ + for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { + entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); + for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { + entry = sk_X509_NAME_ENTRY_value(entries, j); + entry->set = i; + if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) + goto err; + } + sk_X509_NAME_ENTRY_free(entries); + } + sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); + ret = x509_name_canon(nm.x); + if (!ret) + goto err; + nm.x->modified = 0; + *val = nm.a; + *in = p; + return ret; + err: + if (nm.x != NULL) + X509_NAME_free(nm.x); + ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; } -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) { - int ret; - X509_NAME *a = (X509_NAME *)*val; - if(a->modified) { - ret = x509_name_encode(a); - if(ret < 0) - return ret; - ret = x509_name_canon(a); - if(ret < 0) - return ret; - } - ret = a->bytes->length; - if(out != NULL) { - memcpy(*out,a->bytes->data,ret); - *out+=ret; - } - return ret; + int ret; + X509_NAME *a = (X509_NAME *)*val; + if (a->modified) { + ret = x509_name_encode(a); + if (ret < 0) + return ret; + ret = x509_name_canon(a); + if (ret < 0) + return ret; + } + ret = a->bytes->length; + if (out != NULL) { + memcpy(*out, a->bytes->data, ret); + *out += ret; + } + return ret; } static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) - { - sk_X509_NAME_ENTRY_free(ne); - } +{ + sk_X509_NAME_ENTRY_free(ne); +} static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) - { - sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); - } +{ + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); +} static int x509_name_encode(X509_NAME *a) { - union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; - ASN1_VALUE *a; } intname = {NULL}; - int len; - unsigned char *p; - STACK_OF(X509_NAME_ENTRY) *entries = NULL; - X509_NAME_ENTRY *entry; - int i, set = -1; - intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); - if(!intname.s) goto memerr; - for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - entry = sk_X509_NAME_ENTRY_value(a->entries, i); - if(entry->set != set) { - entries = sk_X509_NAME_ENTRY_new_null(); - if(!entries) goto memerr; - if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, - entries)) - goto memerr; - set = entry->set; - } - if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; - } - len = ASN1_item_ex_i2d(&intname.a, NULL, - ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - if (!BUF_MEM_grow(a->bytes,len)) goto memerr; - p=(unsigned char *)a->bytes->data; - ASN1_item_ex_i2d(&intname.a, - &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, - local_sk_X509_NAME_ENTRY_free); - a->modified = 0; - return len; -memerr: - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, - local_sk_X509_NAME_ENTRY_free); - ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); - return -1; + union { + STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; + } intname = { + NULL + }; + int len; + unsigned char *p; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry; + int i, set = -1; + intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname.s) + goto memerr; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto memerr; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) + goto memerr; + set = entry->set; + } + if (!sk_X509_NAME_ENTRY_push(entries, entry)) + goto memerr; + } + len = ASN1_item_ex_i2d(&intname.a, NULL, + ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + if (!BUF_MEM_grow(a->bytes, len)) + goto memerr; + p = (unsigned char *)a->bytes->data; + ASN1_item_ex_i2d(&intname.a, + &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + a->modified = 0; + return len; + memerr: + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); + return -1; } static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, - int indent, - const char *fname, - const ASN1_PCTX *pctx) - { - if (X509_NAME_print_ex(out, (X509_NAME *)*pval, - indent, pctx->nm_flags) <= 0) - return 0; - return 2; - } - -/* This function generates the canonical encoding of the Name structure. - * In it all strings are converted to UTF8, leading, trailing and - * multiple spaces collapsed, converted to lower case and the leading - * SEQUENCE header removed. - * - * In future we could also normalize the UTF8 too. - * - * By doing this comparison of Name structures can be rapidly - * perfomed by just using memcmp() of the canonical encoding. - * By omitting the leading SEQUENCE name constraints of type - * dirName can also be checked with a simple memcmp(). + int indent, + const char *fname, const ASN1_PCTX *pctx) +{ + if (X509_NAME_print_ex(out, (X509_NAME *)*pval, + indent, pctx->nm_flags) <= 0) + return 0; + return 2; +} + +/* + * This function generates the canonical encoding of the Name structure. In + * it all strings are converted to UTF8, leading, trailing and multiple + * spaces collapsed, converted to lower case and the leading SEQUENCE header + * removed. In future we could also normalize the UTF8 too. By doing this + * comparison of Name structures can be rapidly perfomed by just using + * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name + * constraints of type dirName can also be checked with a simple memcmp(). */ static int x509_name_canon(X509_NAME *a) - { - unsigned char *p; - STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; - STACK_OF(X509_NAME_ENTRY) *entries = NULL; - X509_NAME_ENTRY *entry, *tmpentry = NULL; - int i, set = -1, ret = 0; - - if (a->canon_enc) - { - OPENSSL_free(a->canon_enc); - a->canon_enc = NULL; - } - /* Special case: empty X509_NAME => null encoding */ - if (sk_X509_NAME_ENTRY_num(a->entries) == 0) - { - a->canon_enclen = 0; - return 1; - } - intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); - if(!intname) - goto err; - for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) - { - entry = sk_X509_NAME_ENTRY_value(a->entries, i); - if(entry->set != set) - { - entries = sk_X509_NAME_ENTRY_new_null(); - if(!entries) - goto err; - if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) - goto err; - set = entry->set; - } - tmpentry = X509_NAME_ENTRY_new(); - if (!tmpentry) - goto err; - tmpentry->object = OBJ_dup(entry->object); - if (!asn1_string_canon(tmpentry->value, entry->value)) - goto err; - if(!sk_X509_NAME_ENTRY_push(entries, tmpentry)) - goto err; - tmpentry = NULL; - } - - /* Finally generate encoding */ - - a->canon_enclen = i2d_name_canon(intname, NULL); - - p = OPENSSL_malloc(a->canon_enclen); - - if (!p) - goto err; - - a->canon_enc = p; - - i2d_name_canon(intname, &p); - - ret = 1; - - err: - - if (tmpentry) - X509_NAME_ENTRY_free(tmpentry); - if (intname) - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_pop_free); - return ret; - } +{ + unsigned char *p; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry, *tmpentry = NULL; + int i, set = -1, ret = 0; + + if (a->canon_enc) { + OPENSSL_free(a->canon_enc); + a->canon_enc = NULL; + } + /* Special case: empty X509_NAME => null encoding */ + if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { + a->canon_enclen = 0; + return 1; + } + intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) + goto err; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto err; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) + goto err; + set = entry->set; + } + tmpentry = X509_NAME_ENTRY_new(); + if (!tmpentry) + goto err; + tmpentry->object = OBJ_dup(entry->object); + if (!asn1_string_canon(tmpentry->value, entry->value)) + goto err; + if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) + goto err; + tmpentry = NULL; + } + + /* Finally generate encoding */ + + a->canon_enclen = i2d_name_canon(intname, NULL); + + p = OPENSSL_malloc(a->canon_enclen); + + if (!p) + goto err; + + a->canon_enc = p; + + i2d_name_canon(intname, &p); + + ret = 1; + + err: + + if (tmpentry) + X509_NAME_ENTRY_free(tmpentry); + if (intname) + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + return ret; +} /* Bitmap of all the types of string that will be canonicalized. */ -#define ASN1_MASK_CANON \ - (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ - | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ - | B_ASN1_VISIBLESTRING) - +#define ASN1_MASK_CANON \ + (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ + | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ + | B_ASN1_VISIBLESTRING) static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) - { - unsigned char *to, *from; - int len, i; - - /* If type not in bitmask just copy string across */ - if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) - { - if (!ASN1_STRING_copy(out, in)) - return 0; - return 1; - } - - out->type = V_ASN1_UTF8STRING; - out->length = ASN1_STRING_to_UTF8(&out->data, in); - if (out->length == -1) - return 0; - - to = out->data; - from = to; - - len = out->length; - - /* Convert string in place to canonical form. - * Ultimately we may need to handle a wider range of characters - * but for now ignore anything with MSB set and rely on the - * isspace() and tolower() functions. - */ - - /* Ignore leading spaces */ - while((len > 0) && !(*from & 0x80) && isspace(*from)) - { - from++; - len--; - } - - to = from + len - 1; - - /* Ignore trailing spaces */ - while ((len > 0) && !(*to & 0x80) && isspace(*to)) - { - to--; - len--; - } - - to = out->data; - - i = 0; - while(i < len) - { - /* If MSB set just copy across */ - if (*from & 0x80) - { - *to++ = *from++; - i++; - } - /* Collapse multiple spaces */ - else if (isspace(*from)) - { - /* Copy one space across */ - *to++ = ' '; - /* Ignore subsequent spaces. Note: don't need to - * check len here because we know the last - * character is a non-space so we can't overflow. - */ - do - { - from++; - i++; - } - while(!(*from & 0x80) && isspace(*from)); - } - else - { - *to++ = tolower(*from); - from++; - i++; - } - } - - out->length = to - out->data; - - return 1; - - } - -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, - unsigned char **in) - { - int i, len, ltmp; - ASN1_VALUE *v; - STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; - - len = 0; - for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) - { - v = sk_ASN1_VALUE_value(intname, i); - ltmp = ASN1_item_ex_i2d(&v, in, - ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); - if (ltmp < 0) - return ltmp; - len += ltmp; - } - return len; - } +{ + unsigned char *to, *from; + int len, i; + + /* If type not in bitmask just copy string across */ + if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { + if (!ASN1_STRING_copy(out, in)) + return 0; + return 1; + } + + out->type = V_ASN1_UTF8STRING; + out->length = ASN1_STRING_to_UTF8(&out->data, in); + if (out->length == -1) + return 0; + + to = out->data; + from = to; + + len = out->length; + + /* + * Convert string in place to canonical form. Ultimately we may need to + * handle a wider range of characters but for now ignore anything with + * MSB set and rely on the isspace() and tolower() functions. + */ + + /* Ignore leading spaces */ + while ((len > 0) && !(*from & 0x80) && isspace(*from)) { + from++; + len--; + } + + to = from + len - 1; + + /* Ignore trailing spaces */ + while ((len > 0) && !(*to & 0x80) && isspace(*to)) { + to--; + len--; + } + + to = out->data; + + i = 0; + while (i < len) { + /* If MSB set just copy across */ + if (*from & 0x80) { + *to++ = *from++; + i++; + } + /* Collapse multiple spaces */ + else if (isspace(*from)) { + /* Copy one space across */ + *to++ = ' '; + /* + * Ignore subsequent spaces. Note: don't need to check len here + * because we know the last character is a non-space so we can't + * overflow. + */ + do { + from++; + i++; + } + while (!(*from & 0x80) && isspace(*from)); + } else { + *to++ = tolower(*from); + from++; + i++; + } + } + + out->length = to - out->data; + + return 1; + +} + +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, + unsigned char **in) +{ + int i, len, ltmp; + ASN1_VALUE *v; + STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; + + len = 0; + for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { + v = sk_ASN1_VALUE_value(intname, i); + ltmp = ASN1_item_ex_i2d(&v, in, + ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); + if (ltmp < 0) + return ltmp; + len += ltmp; + } + return len; +} int X509_NAME_set(X509_NAME **xn, X509_NAME *name) - { - X509_NAME *in; - - if (!xn || !name) return(0); - - if (*xn != name) - { - in=X509_NAME_dup(name); - if (in != NULL) - { - X509_NAME_free(*xn); - *xn=in; - } - } - return(*xn != NULL); - } - +{ + X509_NAME *in; + + if (!xn || !name) + return (0); + + if (*xn != name) { + in = X509_NAME_dup(name); + if (in != NULL) { + X509_NAME_free(*xn); + *xn = in; + } + } + return (*xn != NULL); +} + IMPLEMENT_STACK_OF(X509_NAME_ENTRY) + IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) |