• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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