1 /*
2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3 * 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@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@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com). */
56
57 #include <stdio.h>
58
59 #include <openssl/asn1t.h>
60 #include <openssl/conf.h>
61 #include <openssl/obj.h>
62 #include <openssl/x509v3.h>
63
64 #include "internal.h"
65
66
67 ASN1_SEQUENCE(OTHERNAME) = {
68 ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
69 // Maybe have a true ANY DEFINED BY later
70 ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0),
71 } ASN1_SEQUENCE_END(OTHERNAME)
72
73 IMPLEMENT_ASN1_FUNCTIONS_const(OTHERNAME)
74
75 ASN1_SEQUENCE(EDIPARTYNAME) = {
76 // DirectoryString is a CHOICE type, so use explicit tagging.
77 ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
78 ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1),
79 } ASN1_SEQUENCE_END(EDIPARTYNAME)
80
81 IMPLEMENT_ASN1_FUNCTIONS_const(EDIPARTYNAME)
82
83 ASN1_CHOICE(GENERAL_NAME) = {
84 ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
85 ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
86 ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
87 // Don't decode this
88 ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
89 // X509_NAME is a CHOICE type so use EXPLICIT
90 ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
91 ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
92 ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING,
93 GEN_URI),
94 ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
95 ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID),
96 } ASN1_CHOICE_END(GENERAL_NAME)
97
98 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
99
100 ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF,
101 0, GeneralNames,
102 GENERAL_NAME)
103 ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
104
105 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
106
107 IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME)
108
109 static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) {
110 // nameAssigner is optional and may be NULL.
111 if (a->nameAssigner == NULL) {
112 if (b->nameAssigner != NULL) {
113 return -1;
114 }
115 } else {
116 if (b->nameAssigner == NULL ||
117 ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner) != 0) {
118 return -1;
119 }
120 }
121
122 // partyName may not be NULL.
123 return ASN1_STRING_cmp(a->partyName, b->partyName);
124 }
125
126 // Returns 0 if they are equal, != 0 otherwise.
othername_cmp(const OTHERNAME * a,const OTHERNAME * b)127 static int othername_cmp(const OTHERNAME *a, const OTHERNAME *b) {
128 int result = -1;
129
130 if (!a || !b) {
131 return -1;
132 }
133 // Check their type first.
134 if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) {
135 return result;
136 }
137 // Check the value.
138 result = ASN1_TYPE_cmp(a->value, b->value);
139 return result;
140 }
141
142 // Returns 0 if they are equal, != 0 otherwise.
GENERAL_NAME_cmp(const GENERAL_NAME * a,const GENERAL_NAME * b)143 int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) {
144 if (!a || !b || a->type != b->type) {
145 return -1;
146 }
147
148 switch (a->type) {
149 case GEN_X400:
150 return ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
151
152 case GEN_EDIPARTY:
153 return edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName);
154
155 case GEN_OTHERNAME:
156 return othername_cmp(a->d.otherName, b->d.otherName);
157
158 case GEN_EMAIL:
159 case GEN_DNS:
160 case GEN_URI:
161 return ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
162
163 case GEN_DIRNAME:
164 return X509_NAME_cmp(a->d.dirn, b->d.dirn);
165
166 case GEN_IPADD:
167 return ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
168
169 case GEN_RID:
170 return OBJ_cmp(a->d.rid, b->d.rid);
171 }
172
173 return -1;
174 }
175
GENERAL_NAME_set0_value(GENERAL_NAME * a,int type,void * value)176 void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) {
177 switch (type) {
178 case GEN_X400:
179 a->d.x400Address = value;
180 break;
181
182 case GEN_EDIPARTY:
183 a->d.ediPartyName = value;
184 break;
185
186 case GEN_OTHERNAME:
187 a->d.otherName = value;
188 break;
189
190 case GEN_EMAIL:
191 case GEN_DNS:
192 case GEN_URI:
193 a->d.ia5 = value;
194 break;
195
196 case GEN_DIRNAME:
197 a->d.dirn = value;
198 break;
199
200 case GEN_IPADD:
201 a->d.ip = value;
202 break;
203
204 case GEN_RID:
205 a->d.rid = value;
206 break;
207 }
208 a->type = type;
209 }
210
GENERAL_NAME_get0_value(const GENERAL_NAME * a,int * ptype)211 void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype) {
212 if (ptype) {
213 *ptype = a->type;
214 }
215 switch (a->type) {
216 case GEN_X400:
217 return a->d.x400Address;
218
219 case GEN_EDIPARTY:
220 return a->d.ediPartyName;
221
222 case GEN_OTHERNAME:
223 return a->d.otherName;
224
225 case GEN_EMAIL:
226 case GEN_DNS:
227 case GEN_URI:
228 return a->d.ia5;
229
230 case GEN_DIRNAME:
231 return a->d.dirn;
232
233 case GEN_IPADD:
234 return a->d.ip;
235
236 case GEN_RID:
237 return a->d.rid;
238
239 default:
240 return NULL;
241 }
242 }
243
GENERAL_NAME_set0_othername(GENERAL_NAME * gen,ASN1_OBJECT * oid,ASN1_TYPE * value)244 int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid,
245 ASN1_TYPE *value) {
246 OTHERNAME *oth;
247 oth = OTHERNAME_new();
248 if (!oth) {
249 return 0;
250 }
251 ASN1_TYPE_free(oth->value);
252 oth->type_id = oid;
253 oth->value = value;
254 GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
255 return 1;
256 }
257
GENERAL_NAME_get0_otherName(const GENERAL_NAME * gen,ASN1_OBJECT ** poid,ASN1_TYPE ** pvalue)258 int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **poid,
259 ASN1_TYPE **pvalue) {
260 if (gen->type != GEN_OTHERNAME) {
261 return 0;
262 }
263 if (poid) {
264 *poid = gen->d.otherName->type_id;
265 }
266 if (pvalue) {
267 *pvalue = gen->d.otherName->value;
268 }
269 return 1;
270 }
271