xref: /freebsd/crypto/openssl/crypto/x509/v3_genn.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery  * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*b077aed3SPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*b077aed3SPierre Pronchery  * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery  * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery  */
9*b077aed3SPierre Pronchery 
10*b077aed3SPierre Pronchery #include <stdio.h>
11*b077aed3SPierre Pronchery #include "internal/cryptlib.h"
12*b077aed3SPierre Pronchery #include <openssl/asn1t.h>
13*b077aed3SPierre Pronchery #include <openssl/conf.h>
14*b077aed3SPierre Pronchery #include <openssl/x509v3.h>
15*b077aed3SPierre Pronchery 
16*b077aed3SPierre Pronchery ASN1_SEQUENCE(OTHERNAME) = {
17*b077aed3SPierre Pronchery         ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
18*b077aed3SPierre Pronchery         /* Maybe have a true ANY DEFINED BY later */
19*b077aed3SPierre Pronchery         ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
20*b077aed3SPierre Pronchery } ASN1_SEQUENCE_END(OTHERNAME)
21*b077aed3SPierre Pronchery 
22*b077aed3SPierre Pronchery IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
23*b077aed3SPierre Pronchery 
24*b077aed3SPierre Pronchery ASN1_SEQUENCE(EDIPARTYNAME) = {
25*b077aed3SPierre Pronchery         /* DirectoryString is a CHOICE type so use explicit tagging */
26*b077aed3SPierre Pronchery         ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
27*b077aed3SPierre Pronchery         ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
28*b077aed3SPierre Pronchery } ASN1_SEQUENCE_END(EDIPARTYNAME)
29*b077aed3SPierre Pronchery 
30*b077aed3SPierre Pronchery IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
31*b077aed3SPierre Pronchery 
32*b077aed3SPierre Pronchery ASN1_CHOICE(GENERAL_NAME) = {
33*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
34*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
35*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
36*b077aed3SPierre Pronchery         /* Don't decode this */
37*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
38*b077aed3SPierre Pronchery         /* X509_NAME is a CHOICE type so use EXPLICIT */
39*b077aed3SPierre Pronchery         ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
40*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
41*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
42*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
43*b077aed3SPierre Pronchery         ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
44*b077aed3SPierre Pronchery } ASN1_CHOICE_END(GENERAL_NAME)
45*b077aed3SPierre Pronchery 
46*b077aed3SPierre Pronchery IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
47*b077aed3SPierre Pronchery 
48*b077aed3SPierre Pronchery ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
49*b077aed3SPierre Pronchery         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
50*b077aed3SPierre Pronchery ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
51*b077aed3SPierre Pronchery 
52*b077aed3SPierre Pronchery IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
53*b077aed3SPierre Pronchery 
54*b077aed3SPierre Pronchery GENERAL_NAME *GENERAL_NAME_dup(const GENERAL_NAME *a)
55*b077aed3SPierre Pronchery {
56*b077aed3SPierre Pronchery     return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
57*b077aed3SPierre Pronchery                                     (d2i_of_void *)d2i_GENERAL_NAME,
58*b077aed3SPierre Pronchery                                     (char *)a);
59*b077aed3SPierre Pronchery }
60*b077aed3SPierre Pronchery 
edipartyname_cmp(const EDIPARTYNAME * a,const EDIPARTYNAME * b)61*b077aed3SPierre Pronchery static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
62*b077aed3SPierre Pronchery {
63*b077aed3SPierre Pronchery     int res;
64*b077aed3SPierre Pronchery 
65*b077aed3SPierre Pronchery     if (a == NULL || b == NULL) {
66*b077aed3SPierre Pronchery         /*
67*b077aed3SPierre Pronchery          * Shouldn't be possible in a valid GENERAL_NAME, but we handle it
68*b077aed3SPierre Pronchery          * anyway. OTHERNAME_cmp treats NULL != NULL so we do the same here
69*b077aed3SPierre Pronchery          */
70*b077aed3SPierre Pronchery         return -1;
71*b077aed3SPierre Pronchery     }
72*b077aed3SPierre Pronchery     if (a->nameAssigner == NULL && b->nameAssigner != NULL)
73*b077aed3SPierre Pronchery         return -1;
74*b077aed3SPierre Pronchery     if (a->nameAssigner != NULL && b->nameAssigner == NULL)
75*b077aed3SPierre Pronchery         return 1;
76*b077aed3SPierre Pronchery     /* If we get here then both have nameAssigner set, or both unset */
77*b077aed3SPierre Pronchery     if (a->nameAssigner != NULL) {
78*b077aed3SPierre Pronchery         res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
79*b077aed3SPierre Pronchery         if (res != 0)
80*b077aed3SPierre Pronchery             return res;
81*b077aed3SPierre Pronchery     }
82*b077aed3SPierre Pronchery     /*
83*b077aed3SPierre Pronchery      * partyName is required, so these should never be NULL. We treat it in
84*b077aed3SPierre Pronchery      * the same way as the a == NULL || b == NULL case above
85*b077aed3SPierre Pronchery      */
86*b077aed3SPierre Pronchery     if (a->partyName == NULL || b->partyName == NULL)
87*b077aed3SPierre Pronchery         return -1;
88*b077aed3SPierre Pronchery 
89*b077aed3SPierre Pronchery     return ASN1_STRING_cmp(a->partyName, b->partyName);
90*b077aed3SPierre Pronchery }
91*b077aed3SPierre Pronchery 
92*b077aed3SPierre Pronchery /* Returns 0 if they are equal, != 0 otherwise. */
GENERAL_NAME_cmp(GENERAL_NAME * a,GENERAL_NAME * b)93*b077aed3SPierre Pronchery int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
94*b077aed3SPierre Pronchery {
95*b077aed3SPierre Pronchery     int result = -1;
96*b077aed3SPierre Pronchery 
97*b077aed3SPierre Pronchery     if (!a || !b || a->type != b->type)
98*b077aed3SPierre Pronchery         return -1;
99*b077aed3SPierre Pronchery     switch (a->type) {
100*b077aed3SPierre Pronchery     case GEN_X400:
101*b077aed3SPierre Pronchery         result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
102*b077aed3SPierre Pronchery         break;
103*b077aed3SPierre Pronchery 
104*b077aed3SPierre Pronchery     case GEN_EDIPARTY:
105*b077aed3SPierre Pronchery         result = edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName);
106*b077aed3SPierre Pronchery         break;
107*b077aed3SPierre Pronchery 
108*b077aed3SPierre Pronchery     case GEN_OTHERNAME:
109*b077aed3SPierre Pronchery         result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
110*b077aed3SPierre Pronchery         break;
111*b077aed3SPierre Pronchery 
112*b077aed3SPierre Pronchery     case GEN_EMAIL:
113*b077aed3SPierre Pronchery     case GEN_DNS:
114*b077aed3SPierre Pronchery     case GEN_URI:
115*b077aed3SPierre Pronchery         result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
116*b077aed3SPierre Pronchery         break;
117*b077aed3SPierre Pronchery 
118*b077aed3SPierre Pronchery     case GEN_DIRNAME:
119*b077aed3SPierre Pronchery         result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
120*b077aed3SPierre Pronchery         break;
121*b077aed3SPierre Pronchery 
122*b077aed3SPierre Pronchery     case GEN_IPADD:
123*b077aed3SPierre Pronchery         result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
124*b077aed3SPierre Pronchery         break;
125*b077aed3SPierre Pronchery 
126*b077aed3SPierre Pronchery     case GEN_RID:
127*b077aed3SPierre Pronchery         result = OBJ_cmp(a->d.rid, b->d.rid);
128*b077aed3SPierre Pronchery         break;
129*b077aed3SPierre Pronchery     }
130*b077aed3SPierre Pronchery     return result;
131*b077aed3SPierre Pronchery }
132*b077aed3SPierre Pronchery 
133*b077aed3SPierre Pronchery /* Returns 0 if they are equal, != 0 otherwise. */
OTHERNAME_cmp(OTHERNAME * a,OTHERNAME * b)134*b077aed3SPierre Pronchery int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
135*b077aed3SPierre Pronchery {
136*b077aed3SPierre Pronchery     int result = -1;
137*b077aed3SPierre Pronchery 
138*b077aed3SPierre Pronchery     if (!a || !b)
139*b077aed3SPierre Pronchery         return -1;
140*b077aed3SPierre Pronchery     /* Check their type first. */
141*b077aed3SPierre Pronchery     if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
142*b077aed3SPierre Pronchery         return result;
143*b077aed3SPierre Pronchery     /* Check the value. */
144*b077aed3SPierre Pronchery     result = ASN1_TYPE_cmp(a->value, b->value);
145*b077aed3SPierre Pronchery     return result;
146*b077aed3SPierre Pronchery }
147*b077aed3SPierre Pronchery 
GENERAL_NAME_set0_value(GENERAL_NAME * a,int type,void * value)148*b077aed3SPierre Pronchery void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
149*b077aed3SPierre Pronchery {
150*b077aed3SPierre Pronchery     switch (type) {
151*b077aed3SPierre Pronchery     case GEN_X400:
152*b077aed3SPierre Pronchery         a->d.x400Address = value;
153*b077aed3SPierre Pronchery         break;
154*b077aed3SPierre Pronchery 
155*b077aed3SPierre Pronchery     case GEN_EDIPARTY:
156*b077aed3SPierre Pronchery         a->d.ediPartyName = value;
157*b077aed3SPierre Pronchery         break;
158*b077aed3SPierre Pronchery 
159*b077aed3SPierre Pronchery     case GEN_OTHERNAME:
160*b077aed3SPierre Pronchery         a->d.otherName = value;
161*b077aed3SPierre Pronchery         break;
162*b077aed3SPierre Pronchery 
163*b077aed3SPierre Pronchery     case GEN_EMAIL:
164*b077aed3SPierre Pronchery     case GEN_DNS:
165*b077aed3SPierre Pronchery     case GEN_URI:
166*b077aed3SPierre Pronchery         a->d.ia5 = value;
167*b077aed3SPierre Pronchery         break;
168*b077aed3SPierre Pronchery 
169*b077aed3SPierre Pronchery     case GEN_DIRNAME:
170*b077aed3SPierre Pronchery         a->d.dirn = value;
171*b077aed3SPierre Pronchery         break;
172*b077aed3SPierre Pronchery 
173*b077aed3SPierre Pronchery     case GEN_IPADD:
174*b077aed3SPierre Pronchery         a->d.ip = value;
175*b077aed3SPierre Pronchery         break;
176*b077aed3SPierre Pronchery 
177*b077aed3SPierre Pronchery     case GEN_RID:
178*b077aed3SPierre Pronchery         a->d.rid = value;
179*b077aed3SPierre Pronchery         break;
180*b077aed3SPierre Pronchery     }
181*b077aed3SPierre Pronchery     a->type = type;
182*b077aed3SPierre Pronchery }
183*b077aed3SPierre Pronchery 
GENERAL_NAME_get0_value(const GENERAL_NAME * a,int * ptype)184*b077aed3SPierre Pronchery void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype)
185*b077aed3SPierre Pronchery {
186*b077aed3SPierre Pronchery     if (ptype)
187*b077aed3SPierre Pronchery         *ptype = a->type;
188*b077aed3SPierre Pronchery     switch (a->type) {
189*b077aed3SPierre Pronchery     case GEN_X400:
190*b077aed3SPierre Pronchery         return a->d.x400Address;
191*b077aed3SPierre Pronchery 
192*b077aed3SPierre Pronchery     case GEN_EDIPARTY:
193*b077aed3SPierre Pronchery         return a->d.ediPartyName;
194*b077aed3SPierre Pronchery 
195*b077aed3SPierre Pronchery     case GEN_OTHERNAME:
196*b077aed3SPierre Pronchery         return a->d.otherName;
197*b077aed3SPierre Pronchery 
198*b077aed3SPierre Pronchery     case GEN_EMAIL:
199*b077aed3SPierre Pronchery     case GEN_DNS:
200*b077aed3SPierre Pronchery     case GEN_URI:
201*b077aed3SPierre Pronchery         return a->d.ia5;
202*b077aed3SPierre Pronchery 
203*b077aed3SPierre Pronchery     case GEN_DIRNAME:
204*b077aed3SPierre Pronchery         return a->d.dirn;
205*b077aed3SPierre Pronchery 
206*b077aed3SPierre Pronchery     case GEN_IPADD:
207*b077aed3SPierre Pronchery         return a->d.ip;
208*b077aed3SPierre Pronchery 
209*b077aed3SPierre Pronchery     case GEN_RID:
210*b077aed3SPierre Pronchery         return a->d.rid;
211*b077aed3SPierre Pronchery 
212*b077aed3SPierre Pronchery     default:
213*b077aed3SPierre Pronchery         return NULL;
214*b077aed3SPierre Pronchery     }
215*b077aed3SPierre Pronchery }
216*b077aed3SPierre Pronchery 
GENERAL_NAME_set0_othername(GENERAL_NAME * gen,ASN1_OBJECT * oid,ASN1_TYPE * value)217*b077aed3SPierre Pronchery int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
218*b077aed3SPierre Pronchery                                 ASN1_OBJECT *oid, ASN1_TYPE *value)
219*b077aed3SPierre Pronchery {
220*b077aed3SPierre Pronchery     OTHERNAME *oth;
221*b077aed3SPierre Pronchery     oth = OTHERNAME_new();
222*b077aed3SPierre Pronchery     if (oth == NULL)
223*b077aed3SPierre Pronchery         return 0;
224*b077aed3SPierre Pronchery     ASN1_TYPE_free(oth->value);
225*b077aed3SPierre Pronchery     oth->type_id = oid;
226*b077aed3SPierre Pronchery     oth->value = value;
227*b077aed3SPierre Pronchery     GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
228*b077aed3SPierre Pronchery     return 1;
229*b077aed3SPierre Pronchery }
230*b077aed3SPierre Pronchery 
GENERAL_NAME_get0_otherName(const GENERAL_NAME * gen,ASN1_OBJECT ** poid,ASN1_TYPE ** pvalue)231*b077aed3SPierre Pronchery int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen,
232*b077aed3SPierre Pronchery                                 ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
233*b077aed3SPierre Pronchery {
234*b077aed3SPierre Pronchery     if (gen->type != GEN_OTHERNAME)
235*b077aed3SPierre Pronchery         return 0;
236*b077aed3SPierre Pronchery     if (poid)
237*b077aed3SPierre Pronchery         *poid = gen->d.otherName->type_id;
238*b077aed3SPierre Pronchery     if (pvalue)
239*b077aed3SPierre Pronchery         *pvalue = gen->d.otherName->value;
240*b077aed3SPierre Pronchery     return 1;
241*b077aed3SPierre Pronchery }
242