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