1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/asn1/x_name.c */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com). 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL. 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to. The following conditions 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA, 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed. 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used. 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package. 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in the 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * documentation and/or other materials provided with the distribution. 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * must display the following acknowledgement: 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes cryptographic software written by 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Eric Young (eay@cryptsoft.com)" 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The word 'cryptographic' can be left out if the rouines from the library 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * being used are not cryptographic related :-). 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the apps directory (application code) you must include an acknowledgement: 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE. 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed. i.e. this code cannot simply be 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.] 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h> 60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <ctype.h> 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h" 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/asn1t.h> 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509.h> 64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "asn1_locl.h" 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; 67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_ex_d2i(ASN1_VALUE **val, 70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const unsigned char **in, long len, 71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const ASN1_ITEM *it, 72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int tag, int aclass, char opt, ASN1_TLC *ctx); 73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, 75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const ASN1_ITEM *it, int tag, int aclass); 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int x509_name_encode(X509_NAME *a); 80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_canon(X509_NAME *a); 81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); 82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname, 83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned char **in); 84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, 87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int indent, 88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const char *fname, 89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const ASN1_PCTX *pctx); 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(X509_NAME_ENTRY) = { 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(X509_NAME_ENTRY) 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * so declare two template wrappers for this 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Normally that's where it would end: we'd have two nested STACK structures 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * representing the ASN1. Unfortunately X509_NAME uses a completely different 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * form and caches encodings so we have to process the internal form and convert 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to the external form. 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst ASN1_EXTERN_FUNCS x509_name_ff = { 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x509_name_ex_new, 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x509_name_ex_free, 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0, /* Default clear behaviour is OK */ 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x509_name_ex_d2i, 123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom x509_name_ex_i2d, 124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom x509_name_ex_print 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS(X509_NAME) 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME *ret = NULL; 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = OPENSSL_malloc(sizeof(X509_NAME)); 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!ret) goto memerr; 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto memerr; 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr; 140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret->canon_enc = NULL; 141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret->canon_enclen = 0; 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->modified=1; 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *val = (ASN1_VALUE *)ret; 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memerr: 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret) 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret->entries) 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_NAME_ENTRY_free(ret->entries); 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(ret); 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME *a; 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!pval || !*pval) 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return; 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a = (X509_NAME *)*pval; 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BUF_MEM_free(a->bytes); 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); 166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (a->canon_enc) 167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom OPENSSL_free(a->canon_enc); 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a); 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *pval = NULL; 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_ex_d2i(ASN1_VALUE **val, 173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const unsigned char **in, long len, const ASN1_ITEM *it, 174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int tag, int aclass, char opt, ASN1_TLC *ctx) 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const unsigned char *p = *in, *q; 177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; 178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ASN1_VALUE *a; } intname = {NULL}; 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, j, ret; 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(X509_NAME_ENTRY) *entries; 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME_ENTRY *entry; 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project q = p; 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Get internal representation of Name */ 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = ASN1_item_ex_d2i(&intname.a, 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tag, aclass, opt, ctx); 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(ret <= 0) return ret; 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(*val) x509_name_ex_free(val, NULL); 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!x509_name_ex_new(&nm.a, NULL)) goto err; 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* We've decoded it: now cache encoding */ 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err; 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(nm.x->bytes->data, q, p - q); 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Convert internal representation to X509_NAME structure */ 199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { 200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project entry = sk_X509_NAME_ENTRY_value(entries, j); 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project entry->set = i; 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_X509_NAME_ENTRY_free(entries); 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); 210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret = x509_name_canon(nm.x); 211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!ret) 212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project nm.x->modified = 0; 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *val = nm.a; 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *in = p; 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 217ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstromerr: 218ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (nm.x != NULL) 219ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom X509_NAME_free(nm.x); 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret; 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME *a = (X509_NAME *)*val; 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(a->modified) { 229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret = x509_name_encode(a); 230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(ret < 0) 231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ret; 232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret = x509_name_canon(a); 233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(ret < 0) 234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ret; 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = a->bytes->length; 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(out != NULL) { 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(*out,a->bytes->data,ret); 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *out+=ret; 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) 245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_NAME_ENTRY_free(ne); 247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) 250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); 252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int x509_name_encode(X509_NAME *a) 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; 257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ASN1_VALUE *a; } intname = {NULL}; 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int len; 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *p; 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(X509_NAME_ENTRY) *entries = NULL; 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME_ENTRY *entry; 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, set = -1; 263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!intname.s) goto memerr; 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project entry = sk_X509_NAME_ENTRY_value(a->entries, i); 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(entry->set != set) { 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project entries = sk_X509_NAME_ENTRY_new_null(); 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!entries) goto memerr; 270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, 271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom entries)) 272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto memerr; 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project set = entry->set; 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project len = ASN1_item_ex_i2d(&intname.a, NULL, 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BUF_MEM_grow(a->bytes,len)) goto memerr; 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project p=(unsigned char *)a->bytes->data; 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_item_ex_i2d(&intname.a, 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom local_sk_X509_NAME_ENTRY_free); 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->modified = 0; 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return len; 287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrommemerr: 288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom local_sk_X509_NAME_ENTRY_free); 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, 295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int indent, 296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const char *fname, 297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const ASN1_PCTX *pctx) 298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (X509_NAME_print_ex(out, (X509_NAME *)*pval, 300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom indent, pctx->nm_flags) <= 0) 301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 2; 303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* This function generates the canonical encoding of the Name structure. 306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * In it all strings are converted to UTF8, leading, trailing and 307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * multiple spaces collapsed, converted to lower case and the leading 308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * SEQUENCE header removed. 309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * In future we could also normalize the UTF8 too. 311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * By doing this comparison of Name structures can be rapidly 313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * perfomed by just using memcmp() of the canonical encoding. 314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * By omitting the leading SEQUENCE name constraints of type 315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * dirName can also be checked with a simple memcmp(). 316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */ 317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int x509_name_canon(X509_NAME *a) 319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned char *p; 321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; 322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom STACK_OF(X509_NAME_ENTRY) *entries = NULL; 323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509_NAME_ENTRY *entry, *tmpentry = NULL; 324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int i, set = -1, ret = 0; 325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (a->canon_enc) 327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom OPENSSL_free(a->canon_enc); 329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom a->canon_enc = NULL; 330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Special case: empty X509_NAME => null encoding */ 332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (sk_X509_NAME_ENTRY_num(a->entries) == 0) 333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom a->canon_enclen = 0; 335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); 338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!intname) 339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) 341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom entry = sk_X509_NAME_ENTRY_value(a->entries, i); 343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(entry->set != set) 344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom entries = sk_X509_NAME_ENTRY_new_null(); 346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!entries) 347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) 349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom set = entry->set; 351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom tmpentry = X509_NAME_ENTRY_new(); 353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom tmpentry->object = OBJ_dup(entry->object); 354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!asn1_string_canon(tmpentry->value, entry->value)) 355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!sk_X509_NAME_ENTRY_push(entries, tmpentry)) 357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom tmpentry = NULL; 359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Finally generate encoding */ 362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom a->canon_enclen = i2d_name_canon(intname, NULL); 364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom p = OPENSSL_malloc(a->canon_enclen); 366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!p) 368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom a->canon_enc = p; 371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom i2d_name_canon(intname, &p); 373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ret = 1; 375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom err: 377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (tmpentry) 379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509_NAME_ENTRY_free(tmpentry); 380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (intname) 381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, 382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom local_sk_X509_NAME_ENTRY_pop_free); 383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ret; 384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Bitmap of all the types of string that will be canonicalized. */ 387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define ASN1_MASK_CANON \ 389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ 390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ 391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom | B_ASN1_VISIBLESTRING) 392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) 395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned char *to, *from; 397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int len, i; 398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* If type not in bitmask just copy string across */ 400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) 401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 40221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom if (!ASN1_STRING_copy(out, in)) 403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom out->type = V_ASN1_UTF8STRING; 408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom out->length = ASN1_STRING_to_UTF8(&out->data, in); 409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (out->length == -1) 410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom to = out->data; 413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom from = to; 414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom len = out->length; 416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Convert string in place to canonical form. 418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Ultimately we may need to handle a wider range of characters 419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * but for now ignore anything with MSB set and rely on the 420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * isspace() and tolower() functions. 421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */ 422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Ignore leading spaces */ 424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while((len > 0) && !(*from & 0x80) && isspace(*from)) 425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom from++; 427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom len--; 428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom to = from + len - 1; 431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Ignore trailing spaces */ 433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while ((len > 0) && !(*to & 0x80) && isspace(*to)) 434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom to--; 436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom len--; 437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom to = out->data; 440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom i = 0; 442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while(i < len) 443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* If MSB set just copy across */ 445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (*from & 0x80) 446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *to++ = *from++; 448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom i++; 449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Collapse multiple spaces */ 451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom else if (isspace(*from)) 452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Copy one space across */ 454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *to++ = ' '; 455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Ignore subsequent spaces. Note: don't need to 456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * check len here because we know the last 457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * character is a non-space so we can't overflow. 458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */ 459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom do 460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom from++; 462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom i++; 463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while(!(*from & 0x80) && isspace(*from)); 465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom else 467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 468ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom *to++ = tolower(*from); 469ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom from++; 470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom i++; 471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom out->length = to - out->data; 475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, 481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned char **in) 482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int i, len, ltmp; 484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ASN1_VALUE *v; 485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; 486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom len = 0; 488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) 489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom v = sk_ASN1_VALUE_value(intname, i); 491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ltmp = ASN1_item_ex_i2d(&v, in, 492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); 493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ltmp < 0) 494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ltmp; 495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom len += ltmp; 496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return len; 498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint X509_NAME_set(X509_NAME **xn, X509_NAME *name) 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME *in; 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!xn || !name) return(0); 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*xn != name) 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project in=X509_NAME_dup(name); 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (in != NULL) 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_NAME_free(*xn); 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *xn=in; 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(*xn != NULL); 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_STACK_OF(X509_NAME_ENTRY) 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) 520