Home | History | Annotate | Download | only in x509v3
      1 /* v3_genn.c */
      2 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL
      3  * project 1999.
      4  */
      5 /* ====================================================================
      6  * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in
     17  *    the documentation and/or other materials provided with the
     18  *    distribution.
     19  *
     20  * 3. All advertising materials mentioning features or use of this
     21  *    software must display the following acknowledgment:
     22  *    "This product includes software developed by the OpenSSL Project
     23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     24  *
     25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26  *    endorse or promote products derived from this software without
     27  *    prior written permission. For written permission, please contact
     28  *    licensing (at) OpenSSL.org.
     29  *
     30  * 5. Products derived from this software may not be called "OpenSSL"
     31  *    nor may "OpenSSL" appear in their names without prior written
     32  *    permission of the OpenSSL Project.
     33  *
     34  * 6. Redistributions of any form whatsoever must retain the following
     35  *    acknowledgment:
     36  *    "This product includes software developed by the OpenSSL Project
     37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     38  *
     39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50  * OF THE POSSIBILITY OF SUCH DAMAGE.
     51  * ====================================================================
     52  *
     53  * This product includes cryptographic software written by Eric Young
     54  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 
     59 
     60 #include <stdio.h>
     61 #include "cryptlib.h"
     62 #include <openssl/asn1t.h>
     63 #include <openssl/conf.h>
     64 #include <openssl/x509v3.h>
     65 
     66 ASN1_SEQUENCE(OTHERNAME) = {
     67 	ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
     68 	/* Maybe have a true ANY DEFINED BY later */
     69 	ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
     70 } ASN1_SEQUENCE_END(OTHERNAME)
     71 
     72 IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
     73 
     74 ASN1_SEQUENCE(EDIPARTYNAME) = {
     75 	ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
     76 	ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
     77 } ASN1_SEQUENCE_END(EDIPARTYNAME)
     78 
     79 IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
     80 
     81 ASN1_CHOICE(GENERAL_NAME) = {
     82 	ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
     83 	ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
     84 	ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
     85 	/* Don't decode this */
     86 	ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
     87 	/* X509_NAME is a CHOICE type so use EXPLICIT */
     88 	ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
     89 	ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
     90 	ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
     91 	ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
     92 	ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
     93 } ASN1_CHOICE_END(GENERAL_NAME)
     94 
     95 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
     96 
     97 ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
     98 	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
     99 ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
    100 
    101 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
    102 
    103 GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
    104 	{
    105 	return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
    106 					 (d2i_of_void *) d2i_GENERAL_NAME,
    107 					 (char *) a);
    108 	}
    109 
    110 /* Returns 0 if they are equal, != 0 otherwise. */
    111 int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
    112 	{
    113 	int result = -1;
    114 
    115 	if (!a || !b || a->type != b->type) return -1;
    116 	switch(a->type)
    117 		{
    118 	case GEN_X400:
    119 	case GEN_EDIPARTY:
    120 		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
    121 		break;
    122 
    123 	case GEN_OTHERNAME:
    124 		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
    125 		break;
    126 
    127 	case GEN_EMAIL:
    128 	case GEN_DNS:
    129 	case GEN_URI:
    130 		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
    131 		break;
    132 
    133 	case GEN_DIRNAME:
    134 		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
    135 		break;
    136 
    137 	case GEN_IPADD:
    138 		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
    139 		break;
    140 
    141 	case GEN_RID:
    142 		result = OBJ_cmp(a->d.rid, b->d.rid);
    143 		break;
    144 		}
    145 	return result;
    146 	}
    147 
    148 /* Returns 0 if they are equal, != 0 otherwise. */
    149 int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
    150 	{
    151 	int result = -1;
    152 
    153 	if (!a || !b) return -1;
    154 	/* Check their type first. */
    155 	if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
    156 		return result;
    157 	/* Check the value. */
    158 	result = ASN1_TYPE_cmp(a->value, b->value);
    159 	return result;
    160 	}
    161 
    162 void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
    163 	{
    164 	switch(type)
    165 		{
    166 	case GEN_X400:
    167 	case GEN_EDIPARTY:
    168 		a->d.other = value;
    169 		break;
    170 
    171 	case GEN_OTHERNAME:
    172 		a->d.otherName = value;
    173 		break;
    174 
    175 	case GEN_EMAIL:
    176 	case GEN_DNS:
    177 	case GEN_URI:
    178 		a->d.ia5 = value;
    179 		break;
    180 
    181 	case GEN_DIRNAME:
    182 		a->d.dirn = value;
    183 		break;
    184 
    185 	case GEN_IPADD:
    186 		a->d.ip = value;
    187 		break;
    188 
    189 	case GEN_RID:
    190 		a->d.rid = value;
    191 		break;
    192 		}
    193 	a->type = type;
    194 	}
    195 
    196 void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
    197 	{
    198 	if (ptype)
    199 		*ptype = a->type;
    200 	switch(a->type)
    201 		{
    202 	case GEN_X400:
    203 	case GEN_EDIPARTY:
    204 		return a->d.other;
    205 
    206 	case GEN_OTHERNAME:
    207 		return a->d.otherName;
    208 
    209 	case GEN_EMAIL:
    210 	case GEN_DNS:
    211 	case GEN_URI:
    212 		return a->d.ia5;
    213 
    214 	case GEN_DIRNAME:
    215 		return a->d.dirn;
    216 
    217 	case GEN_IPADD:
    218 		return a->d.ip;
    219 
    220 	case GEN_RID:
    221 		return a->d.rid;
    222 
    223 	default:
    224 		return NULL;
    225 		}
    226 	}
    227 
    228 int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
    229 				ASN1_OBJECT *oid, ASN1_TYPE *value)
    230 	{
    231 	OTHERNAME *oth;
    232 	oth = OTHERNAME_new();
    233 	if (!oth)
    234 		return 0;
    235 	oth->type_id = oid;
    236 	oth->value = value;
    237 	GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
    238 	return 1;
    239 	}
    240 
    241 int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
    242 				ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
    243 	{
    244 	if (gen->type != GEN_OTHERNAME)
    245 		return 0;
    246 	if (poid)
    247 		*poid = gen->d.otherName->type_id;
    248 	if (pvalue)
    249 		*pvalue = gen->d.otherName->value;
    250 	return 1;
    251 	}
    252 
    253