Coverage Report

Created: 2025-08-28 06:59

/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
}