/src/boringssl/crypto/x509/v3_genn.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <stdio.h> |
16 | | |
17 | | #include <openssl/asn1t.h> |
18 | | #include <openssl/conf.h> |
19 | | #include <openssl/obj.h> |
20 | | #include <openssl/x509.h> |
21 | | |
22 | | #include "internal.h" |
23 | | |
24 | | |
25 | | ASN1_SEQUENCE(OTHERNAME) = { |
26 | | ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), |
27 | | // Maybe have a true ANY DEFINED BY later |
28 | | ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0), |
29 | | } ASN1_SEQUENCE_END(OTHERNAME) |
30 | | |
31 | | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(OTHERNAME) |
32 | | |
33 | | ASN1_SEQUENCE(EDIPARTYNAME) = { |
34 | | // DirectoryString is a CHOICE type, so use explicit tagging. |
35 | | ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), |
36 | | ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1), |
37 | | } ASN1_SEQUENCE_END(EDIPARTYNAME) |
38 | | |
39 | | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(EDIPARTYNAME) |
40 | | |
41 | | ASN1_CHOICE(GENERAL_NAME) = { |
42 | | ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), |
43 | | ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), |
44 | | ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), |
45 | | // Don't decode this |
46 | | ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), |
47 | | // X509_NAME is a CHOICE type so use EXPLICIT |
48 | | ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), |
49 | | ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), |
50 | | ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, |
51 | | GEN_URI), |
52 | | ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), |
53 | | ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID), |
54 | | } ASN1_CHOICE_END(GENERAL_NAME) |
55 | | |
56 | | IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) |
57 | | |
58 | | ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, |
59 | | 0, GeneralNames, |
60 | | GENERAL_NAME) |
61 | | ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) |
62 | | |
63 | | IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) |
64 | | |
65 | | IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME) |
66 | | |
67 | 0 | static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) { |
68 | | // nameAssigner is optional and may be NULL. |
69 | 0 | if (a->nameAssigner == NULL) { |
70 | 0 | if (b->nameAssigner != NULL) { |
71 | 0 | return -1; |
72 | 0 | } |
73 | 0 | } else { |
74 | 0 | if (b->nameAssigner == NULL || |
75 | 0 | ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner) != 0) { |
76 | 0 | return -1; |
77 | 0 | } |
78 | 0 | } |
79 | | |
80 | | // partyName may not be NULL. |
81 | 0 | return ASN1_STRING_cmp(a->partyName, b->partyName); |
82 | 0 | } |
83 | | |
84 | | // Returns 0 if they are equal, != 0 otherwise. |
85 | 0 | static int othername_cmp(const OTHERNAME *a, const OTHERNAME *b) { |
86 | 0 | int result = -1; |
87 | |
|
88 | 0 | if (!a || !b) { |
89 | 0 | return -1; |
90 | 0 | } |
91 | | // Check their type first. |
92 | 0 | if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) { |
93 | 0 | return result; |
94 | 0 | } |
95 | | // Check the value. |
96 | 0 | result = ASN1_TYPE_cmp(a->value, b->value); |
97 | 0 | return result; |
98 | 0 | } |
99 | | |
100 | | // Returns 0 if they are equal, != 0 otherwise. |
101 | 0 | int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) { |
102 | 0 | if (!a || !b || a->type != b->type) { |
103 | 0 | return -1; |
104 | 0 | } |
105 | | |
106 | 0 | switch (a->type) { |
107 | 0 | case GEN_X400: |
108 | 0 | return ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); |
109 | | |
110 | 0 | case GEN_EDIPARTY: |
111 | 0 | return edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); |
112 | | |
113 | 0 | case GEN_OTHERNAME: |
114 | 0 | return othername_cmp(a->d.otherName, b->d.otherName); |
115 | | |
116 | 0 | case GEN_EMAIL: |
117 | 0 | case GEN_DNS: |
118 | 0 | case GEN_URI: |
119 | 0 | return ASN1_STRING_cmp(a->d.ia5, b->d.ia5); |
120 | | |
121 | 0 | case GEN_DIRNAME: |
122 | 0 | return X509_NAME_cmp(a->d.dirn, b->d.dirn); |
123 | | |
124 | 0 | case GEN_IPADD: |
125 | 0 | return ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); |
126 | | |
127 | 0 | case GEN_RID: |
128 | 0 | return OBJ_cmp(a->d.rid, b->d.rid); |
129 | 0 | } |
130 | | |
131 | 0 | return -1; |
132 | 0 | } |
133 | | |
134 | 0 | void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) { |
135 | 0 | switch (type) { |
136 | 0 | case GEN_X400: |
137 | 0 | a->d.x400Address = reinterpret_cast<ASN1_STRING *>(value); |
138 | 0 | break; |
139 | | |
140 | 0 | case GEN_EDIPARTY: |
141 | 0 | a->d.ediPartyName = reinterpret_cast<EDIPARTYNAME *>(value); |
142 | 0 | break; |
143 | | |
144 | 0 | case GEN_OTHERNAME: |
145 | 0 | a->d.otherName = reinterpret_cast<OTHERNAME *>(value); |
146 | 0 | break; |
147 | | |
148 | 0 | case GEN_EMAIL: |
149 | 0 | case GEN_DNS: |
150 | 0 | case GEN_URI: |
151 | 0 | a->d.ia5 = reinterpret_cast<ASN1_STRING *>(value); |
152 | 0 | break; |
153 | | |
154 | 0 | case GEN_DIRNAME: |
155 | 0 | a->d.dirn = reinterpret_cast<X509_NAME *>(value); |
156 | 0 | break; |
157 | | |
158 | 0 | case GEN_IPADD: |
159 | 0 | a->d.ip = reinterpret_cast<ASN1_STRING *>(value); |
160 | 0 | break; |
161 | | |
162 | 0 | case GEN_RID: |
163 | 0 | a->d.rid = reinterpret_cast<ASN1_OBJECT *>(value); |
164 | 0 | break; |
165 | 0 | } |
166 | 0 | a->type = type; |
167 | 0 | } |
168 | | |
169 | 0 | void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *out_type) { |
170 | 0 | if (out_type) { |
171 | 0 | *out_type = a->type; |
172 | 0 | } |
173 | 0 | switch (a->type) { |
174 | 0 | case GEN_X400: |
175 | 0 | return a->d.x400Address; |
176 | | |
177 | 0 | case GEN_EDIPARTY: |
178 | 0 | return a->d.ediPartyName; |
179 | | |
180 | 0 | case GEN_OTHERNAME: |
181 | 0 | return a->d.otherName; |
182 | | |
183 | 0 | case GEN_EMAIL: |
184 | 0 | case GEN_DNS: |
185 | 0 | case GEN_URI: |
186 | 0 | return a->d.ia5; |
187 | | |
188 | 0 | case GEN_DIRNAME: |
189 | 0 | return a->d.dirn; |
190 | | |
191 | 0 | case GEN_IPADD: |
192 | 0 | return a->d.ip; |
193 | | |
194 | 0 | case GEN_RID: |
195 | 0 | return a->d.rid; |
196 | | |
197 | 0 | default: |
198 | 0 | return NULL; |
199 | 0 | } |
200 | 0 | } |
201 | | |
202 | | int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid, |
203 | 0 | ASN1_TYPE *value) { |
204 | 0 | OTHERNAME *oth; |
205 | 0 | oth = OTHERNAME_new(); |
206 | 0 | if (!oth) { |
207 | 0 | return 0; |
208 | 0 | } |
209 | 0 | ASN1_TYPE_free(oth->value); |
210 | 0 | oth->type_id = oid; |
211 | 0 | oth->value = value; |
212 | 0 | GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); |
213 | 0 | return 1; |
214 | 0 | } |
215 | | |
216 | | int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **out_oid, |
217 | 0 | ASN1_TYPE **out_value) { |
218 | 0 | if (gen->type != GEN_OTHERNAME) { |
219 | 0 | return 0; |
220 | 0 | } |
221 | 0 | if (out_oid != NULL) { |
222 | 0 | *out_oid = gen->d.otherName->type_id; |
223 | 0 | } |
224 | 0 | if (out_value != NULL) { |
225 | 0 | *out_value = gen->d.otherName->value; |
226 | 0 | } |
227 | 0 | return 1; |
228 | 0 | } |