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 | |
16 | ASN1_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 | |
22 | IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) |
23 | |
24 | ASN1_SEQUENCE(EDIPARTYNAME) = { |
25 | ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), |
26 | ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) |
27 | } ASN1_SEQUENCE_END(EDIPARTYNAME) |
28 | |
29 | IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) |
30 | |
31 | ASN1_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 | |
45 | IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) |
46 | |
47 | ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = |
48 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) |
49 | ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) |
50 | |
51 | IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) |
52 | |
53 | GENERAL_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. */ |
61 | int 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. */ |
99 | int 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 | |
113 | void 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 | |
146 | void *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 | |
177 | int 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 | |
191 | int 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 | |