Coverage Report

Created: 2026-04-02 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/x509_v3.cc
Line
Count
Source
1
// Copyright 1995-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 <openssl/asn1.h>
16
#include <openssl/err.h>
17
#include <openssl/evp.h>
18
#include <openssl/obj.h>
19
#include <openssl/stack.h>
20
#include <openssl/x509.h>
21
22
#include "internal.h"
23
24
25
55.2k
int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) {
26
55.2k
  if (x == nullptr) {
27
762
    return 0;
28
762
  }
29
54.5k
  return (int)sk_X509_EXTENSION_num(x);
30
55.2k
}
31
32
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
33
2.96k
                          int lastpos) {
34
2.96k
  const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
35
2.96k
  if (obj == nullptr) {
36
0
    return -1;
37
0
  }
38
2.96k
  return X509v3_get_ext_by_OBJ(x, obj, lastpos);
39
2.96k
}
40
41
int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
42
2.96k
                          const ASN1_OBJECT *obj, int lastpos) {
43
2.96k
  if (sk == nullptr) {
44
281
    return -1;
45
281
  }
46
2.68k
  lastpos++;
47
2.68k
  if (lastpos < 0) {
48
0
    lastpos = 0;
49
0
  }
50
2.68k
  int n = (int)sk_X509_EXTENSION_num(sk);
51
4.25k
  for (; lastpos < n; lastpos++) {
52
3.87k
    const X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk, lastpos);
53
3.87k
    if (OBJ_cmp(ex->object, obj) == 0) {
54
2.30k
      return lastpos;
55
2.30k
    }
56
3.87k
  }
57
378
  return -1;
58
2.68k
}
59
60
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
61
0
                               int lastpos) {
62
0
  if (sk == nullptr) {
63
0
    return -1;
64
0
  }
65
66
0
  lastpos++;
67
0
  if (lastpos < 0) {
68
0
    lastpos = 0;
69
0
  }
70
71
0
  crit = !!crit;
72
0
  int n = (int)sk_X509_EXTENSION_num(sk);
73
0
  for (; lastpos < n; lastpos++) {
74
0
    const X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk, lastpos);
75
0
    if (X509_EXTENSION_get_critical(ex) == crit) {
76
0
      return lastpos;
77
0
    }
78
0
  }
79
0
  return -1;
80
0
}
81
82
51.6k
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) {
83
51.6k
  if (x == nullptr || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) {
84
0
    return nullptr;
85
51.6k
  } else {
86
51.6k
    return sk_X509_EXTENSION_value(x, loc);
87
51.6k
  }
88
51.6k
}
89
90
0
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) {
91
0
  X509_EXTENSION *ret;
92
93
0
  if (x == nullptr || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) {
94
0
    return nullptr;
95
0
  }
96
0
  ret = sk_X509_EXTENSION_delete(x, loc);
97
0
  return ret;
98
0
}
99
100
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
101
10.6k
                                         const X509_EXTENSION *ex, int loc) {
102
10.6k
  X509_EXTENSION *new_ex = nullptr;
103
10.6k
  STACK_OF(X509_EXTENSION) *sk = nullptr;
104
10.6k
  int free_sk = 0, n;
105
106
10.6k
  if (x == nullptr) {
107
0
    OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
108
0
    goto err;
109
0
  }
110
111
10.6k
  if (*x == nullptr) {
112
6.82k
    if ((sk = sk_X509_EXTENSION_new_null()) == nullptr) {
113
0
      goto err;
114
0
    }
115
6.82k
    free_sk = 1;
116
6.82k
  } else {
117
3.82k
    sk = *x;
118
3.82k
  }
119
120
10.6k
  n = (int)sk_X509_EXTENSION_num(sk);
121
10.6k
  if (loc > n) {
122
0
    loc = n;
123
10.6k
  } else if (loc < 0) {
124
10.6k
    loc = n;
125
10.6k
  }
126
127
10.6k
  if ((new_ex = X509_EXTENSION_dup(ex)) == nullptr) {
128
35
    goto err;
129
35
  }
130
10.6k
  if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) {
131
0
    goto err;
132
0
  }
133
10.6k
  if (*x == nullptr) {
134
6.79k
    *x = sk;
135
6.79k
  }
136
10.6k
  return sk;
137
138
35
err:
139
35
  X509_EXTENSION_free(new_ex);
140
35
  if (free_sk) {
141
26
    sk_X509_EXTENSION_free(sk);
142
26
  }
143
35
  return nullptr;
144
10.6k
}
145
146
X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
147
                                             int crit,
148
6.13k
                                             const ASN1_OCTET_STRING *data) {
149
6.13k
  const ASN1_OBJECT *obj;
150
6.13k
  X509_EXTENSION *ret;
151
152
6.13k
  obj = OBJ_nid2obj(nid);
153
6.13k
  if (obj == nullptr) {
154
0
    OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
155
0
    return nullptr;
156
0
  }
157
6.13k
  ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
158
6.13k
  return ret;
159
6.13k
}
160
161
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
162
                                             const ASN1_OBJECT *obj, int crit,
163
14.1k
                                             const ASN1_OCTET_STRING *data) {
164
14.1k
  X509_EXTENSION *ret;
165
166
14.1k
  if ((ex == nullptr) || (*ex == nullptr)) {
167
14.1k
    if ((ret = X509_EXTENSION_new()) == nullptr) {
168
0
      return nullptr;
169
0
    }
170
14.1k
  } else {
171
0
    ret = *ex;
172
0
  }
173
174
14.1k
  if (!X509_EXTENSION_set_object(ret, obj)) {
175
0
    goto err;
176
0
  }
177
14.1k
  if (!X509_EXTENSION_set_critical(ret, crit)) {
178
0
    goto err;
179
0
  }
180
14.1k
  if (!X509_EXTENSION_set_data(ret, data)) {
181
0
    goto err;
182
0
  }
183
184
14.1k
  if ((ex != nullptr) && (*ex == nullptr)) {
185
0
    *ex = ret;
186
0
  }
187
14.1k
  return ret;
188
0
err:
189
0
  if ((ex == nullptr) || (ret != *ex)) {
190
0
    X509_EXTENSION_free(ret);
191
0
  }
192
0
  return nullptr;
193
14.1k
}
194
195
14.1k
int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) {
196
14.1k
  if ((ex == nullptr) || (obj == nullptr)) {
197
0
    return 0;
198
0
  }
199
14.1k
  ASN1_OBJECT_free(ex->object);
200
14.1k
  ex->object = OBJ_dup(obj);
201
14.1k
  return ex->object != nullptr;
202
14.1k
}
203
204
14.1k
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) {
205
14.1k
  if (ex == nullptr) {
206
0
    return 0;
207
0
  }
208
  // The critical field is DEFAULT FALSE, so non-critical extensions should omit
209
  // the value.
210
14.1k
  ex->critical = crit ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_NONE;
211
14.1k
  return 1;
212
14.1k
}
213
214
14.1k
int X509_EXTENSION_set_data(X509_EXTENSION *ex, const ASN1_OCTET_STRING *data) {
215
14.1k
  int i;
216
217
14.1k
  if (ex == nullptr) {
218
0
    return 0;
219
0
  }
220
14.1k
  i = ASN1_OCTET_STRING_set(ex->value, data->data, data->length);
221
14.1k
  if (!i) {
222
0
    return 0;
223
0
  }
224
14.1k
  return 1;
225
14.1k
}
226
227
29.7k
ASN1_OBJECT *X509_EXTENSION_get_object(const X509_EXTENSION *ex) {
228
29.7k
  if (ex == nullptr) {
229
0
    return nullptr;
230
0
  }
231
29.7k
  return ex->object;
232
29.7k
}
233
234
33.9k
ASN1_OCTET_STRING *X509_EXTENSION_get_data(const X509_EXTENSION *ex) {
235
33.9k
  if (ex == nullptr) {
236
0
    return nullptr;
237
0
  }
238
33.9k
  return ex->value;
239
33.9k
}
240
241
54.6k
int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) {
242
54.6k
  if (ex == nullptr) {
243
0
    return 0;
244
0
  }
245
54.6k
  if (ex->critical > 0) {
246
2.35k
    return 1;
247
2.35k
  }
248
52.2k
  return 0;
249
54.6k
}