155714Skris/* crypto/asn1/x_name.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include "cryptlib.h" 61109998Smarkm#include <openssl/asn1t.h> 6255714Skris#include <openssl/x509.h> 6355714Skris 64296465Sdelphijstatic int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, 65296465Sdelphij long len, const ASN1_ITEM *it, int tag, 66296465Sdelphij int aclass, char opt, ASN1_TLC *ctx); 6755714Skris 68296465Sdelphijstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, 69296465Sdelphij const ASN1_ITEM *it, int tag, int aclass); 70109998Smarkmstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); 71109998Smarkmstatic void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); 7255714Skris 73109998Smarkmstatic int x509_name_encode(X509_NAME *a); 7455714Skris 75109998SmarkmASN1_SEQUENCE(X509_NAME_ENTRY) = { 76296465Sdelphij ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), 77296465Sdelphij ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) 78109998Smarkm} ASN1_SEQUENCE_END(X509_NAME_ENTRY) 7955714Skris 80109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) 81109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) 8255714Skris 83296465Sdelphij/* 84296465Sdelphij * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so 85296465Sdelphij * declare two template wrappers for this 86109998Smarkm */ 8755714Skris 88109998SmarkmASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = 89296465Sdelphij ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) 90109998SmarkmASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) 9155714Skris 92109998SmarkmASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = 93296465Sdelphij ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) 94109998SmarkmASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) 9555714Skris 96296465Sdelphij/* 97296465Sdelphij * Normally that's where it would end: we'd have two nested STACK structures 98109998Smarkm * representing the ASN1. Unfortunately X509_NAME uses a completely different 99296465Sdelphij * form and caches encodings so we have to process the internal form and 100296465Sdelphij * convert to the external form. 101109998Smarkm */ 10255714Skris 103109998Smarkmconst ASN1_EXTERN_FUNCS x509_name_ff = { 104296465Sdelphij NULL, 105296465Sdelphij x509_name_ex_new, 106296465Sdelphij x509_name_ex_free, 107296465Sdelphij 0, /* Default clear behaviour is OK */ 108296465Sdelphij x509_name_ex_d2i, 109296465Sdelphij x509_name_ex_i2d 110109998Smarkm}; 11155714Skris 112296465SdelphijIMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 11355714Skris 114109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_NAME) 115296465Sdelphij 116109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) 11755714Skris 118109998Smarkmstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) 119109998Smarkm{ 120296465Sdelphij X509_NAME *ret = NULL; 121296465Sdelphij ret = OPENSSL_malloc(sizeof(X509_NAME)); 122296465Sdelphij if (!ret) 123296465Sdelphij goto memerr; 124296465Sdelphij if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) 125296465Sdelphij goto memerr; 126296465Sdelphij if ((ret->bytes = BUF_MEM_new()) == NULL) 127296465Sdelphij goto memerr; 128296465Sdelphij ret->modified = 1; 129296465Sdelphij *val = (ASN1_VALUE *)ret; 130296465Sdelphij return 1; 131109998Smarkm 132109998Smarkm memerr: 133296465Sdelphij ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); 134296465Sdelphij if (ret) { 135296465Sdelphij if (ret->entries) 136296465Sdelphij sk_X509_NAME_ENTRY_free(ret->entries); 137296465Sdelphij OPENSSL_free(ret); 138296465Sdelphij } 139296465Sdelphij return 0; 140109998Smarkm} 14155714Skris 142109998Smarkmstatic void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 143109998Smarkm{ 144296465Sdelphij X509_NAME *a; 145296465Sdelphij if (!pval || !*pval) 146296465Sdelphij return; 147296465Sdelphij a = (X509_NAME *)*pval; 14855714Skris 149296465Sdelphij BUF_MEM_free(a->bytes); 150296465Sdelphij sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); 151296465Sdelphij OPENSSL_free(a); 152296465Sdelphij *pval = NULL; 153109998Smarkm} 15455714Skris 155296465Sdelphij/* 156296465Sdelphij * Used with sk_pop_free() to free up the internal representation. NB: we 157296465Sdelphij * only free the STACK and not its contents because it is already present in 158296465Sdelphij * the X509_NAME structure. 159109998Smarkm */ 16055714Skris 161109998Smarkmstatic void sk_internal_free(void *a) 162109998Smarkm{ 163296465Sdelphij sk_free(a); 164109998Smarkm} 16555714Skris 166296465Sdelphijstatic int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, 167296465Sdelphij long len, const ASN1_ITEM *it, int tag, 168296465Sdelphij int aclass, char opt, ASN1_TLC *ctx) 169109998Smarkm{ 170296465Sdelphij const unsigned char *p = *in, *q; 171296465Sdelphij union { 172296465Sdelphij STACK *s; 173296465Sdelphij ASN1_VALUE *a; 174296465Sdelphij } intname = { 175296465Sdelphij NULL 176296465Sdelphij }; 177296465Sdelphij union { 178296465Sdelphij X509_NAME *x; 179296465Sdelphij ASN1_VALUE *a; 180296465Sdelphij } nm = { 181296465Sdelphij NULL 182296465Sdelphij }; 183296465Sdelphij int i, j, ret; 184296465Sdelphij STACK_OF(X509_NAME_ENTRY) *entries; 185296465Sdelphij X509_NAME_ENTRY *entry; 186296465Sdelphij q = p; 18755714Skris 188296465Sdelphij /* Get internal representation of Name */ 189296465Sdelphij ret = ASN1_item_ex_d2i(&intname.a, 190296465Sdelphij &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), 191296465Sdelphij tag, aclass, opt, ctx); 19255714Skris 193296465Sdelphij if (ret <= 0) 194296465Sdelphij return ret; 195109998Smarkm 196296465Sdelphij if (*val) 197296465Sdelphij x509_name_ex_free(val, NULL); 198296465Sdelphij if (!x509_name_ex_new(&nm.a, NULL)) 199296465Sdelphij goto err; 200296465Sdelphij /* We've decoded it: now cache encoding */ 201296465Sdelphij if (!BUF_MEM_grow(nm.x->bytes, p - q)) 202296465Sdelphij goto err; 203296465Sdelphij memcpy(nm.x->bytes->data, q, p - q); 204296465Sdelphij 205296465Sdelphij /* Convert internal representation to X509_NAME structure */ 206296465Sdelphij for (i = 0; i < sk_num(intname.s); i++) { 207296465Sdelphij entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i); 208296465Sdelphij for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { 209296465Sdelphij entry = sk_X509_NAME_ENTRY_value(entries, j); 210296465Sdelphij entry->set = i; 211296465Sdelphij if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) 212296465Sdelphij goto err; 213296465Sdelphij } 214296465Sdelphij sk_X509_NAME_ENTRY_free(entries); 215296465Sdelphij } 216296465Sdelphij sk_free(intname.s); 217296465Sdelphij nm.x->modified = 0; 218296465Sdelphij *val = nm.a; 219296465Sdelphij *in = p; 220296465Sdelphij return ret; 221296465Sdelphij err: 222296465Sdelphij if (nm.x != NULL) 223296465Sdelphij X509_NAME_free(nm.x); 224296465Sdelphij ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); 225296465Sdelphij return 0; 226109998Smarkm} 22755714Skris 228296465Sdelphijstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, 229296465Sdelphij const ASN1_ITEM *it, int tag, int aclass) 230109998Smarkm{ 231296465Sdelphij int ret; 232296465Sdelphij X509_NAME *a = (X509_NAME *)*val; 233296465Sdelphij if (a->modified) { 234296465Sdelphij ret = x509_name_encode((X509_NAME *)a); 235296465Sdelphij if (ret < 0) 236296465Sdelphij return ret; 237296465Sdelphij } 238296465Sdelphij ret = a->bytes->length; 239296465Sdelphij if (out != NULL) { 240296465Sdelphij memcpy(*out, a->bytes->data, ret); 241296465Sdelphij *out += ret; 242296465Sdelphij } 243296465Sdelphij return ret; 244109998Smarkm} 24555714Skris 246109998Smarkmstatic int x509_name_encode(X509_NAME *a) 247109998Smarkm{ 248296465Sdelphij union { 249296465Sdelphij STACK *s; 250296465Sdelphij ASN1_VALUE *a; 251296465Sdelphij } intname = { 252296465Sdelphij NULL 253296465Sdelphij }; 254296465Sdelphij int len; 255296465Sdelphij unsigned char *p; 256296465Sdelphij STACK_OF(X509_NAME_ENTRY) *entries = NULL; 257296465Sdelphij X509_NAME_ENTRY *entry; 258296465Sdelphij int i, set = -1; 259296465Sdelphij intname.s = sk_new_null(); 260296465Sdelphij if (!intname.s) 261296465Sdelphij goto memerr; 262296465Sdelphij for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 263296465Sdelphij entry = sk_X509_NAME_ENTRY_value(a->entries, i); 264296465Sdelphij if (entry->set != set) { 265296465Sdelphij entries = sk_X509_NAME_ENTRY_new_null(); 266296465Sdelphij if (!entries) 267296465Sdelphij goto memerr; 268296465Sdelphij if (!sk_push(intname.s, (char *)entries)) 269296465Sdelphij goto memerr; 270296465Sdelphij set = entry->set; 271296465Sdelphij } 272296465Sdelphij if (!sk_X509_NAME_ENTRY_push(entries, entry)) 273296465Sdelphij goto memerr; 274296465Sdelphij } 275296465Sdelphij len = ASN1_item_ex_i2d(&intname.a, NULL, 276296465Sdelphij ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 277296465Sdelphij if (!BUF_MEM_grow(a->bytes, len)) 278296465Sdelphij goto memerr; 279296465Sdelphij p = (unsigned char *)a->bytes->data; 280296465Sdelphij ASN1_item_ex_i2d(&intname.a, 281296465Sdelphij &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 282296465Sdelphij sk_pop_free(intname.s, sk_internal_free); 283296465Sdelphij a->modified = 0; 284296465Sdelphij return len; 285296465Sdelphij memerr: 286296465Sdelphij sk_pop_free(intname.s, sk_internal_free); 287296465Sdelphij ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); 288296465Sdelphij return -1; 289109998Smarkm} 29055714Skris 29155714Skrisint X509_NAME_set(X509_NAME **xn, X509_NAME *name) 292296465Sdelphij{ 293296465Sdelphij X509_NAME *in; 29455714Skris 295296465Sdelphij if (!xn || !name) 296296465Sdelphij return (0); 29755714Skris 298296465Sdelphij if (*xn != name) { 299296465Sdelphij in = X509_NAME_dup(name); 300296465Sdelphij if (in != NULL) { 301296465Sdelphij X509_NAME_free(*xn); 302296465Sdelphij *xn = in; 303296465Sdelphij } 304296465Sdelphij } 305296465Sdelphij return (*xn != NULL); 306296465Sdelphij} 307296465Sdelphij 30855714SkrisIMPLEMENT_STACK_OF(X509_NAME_ENTRY) 309296465Sdelphij 31055714SkrisIMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) 311