Coverage Report

Created: 2026-02-16 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/v3_info.cc
Line
Count
Source
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
#include <string.h>
17
18
#include <openssl/asn1.h>
19
#include <openssl/asn1t.h>
20
#include <openssl/conf.h>
21
#include <openssl/err.h>
22
#include <openssl/mem.h>
23
#include <openssl/obj.h>
24
#include <openssl/x509.h>
25
26
#include "internal.h"
27
28
29
using namespace bssl;
30
31
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
32
    const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret);
33
static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method,
34
                                       const X509V3_CTX *ctx,
35
                                       const STACK_OF(CONF_VALUE) *nval);
36
37
const X509V3_EXT_METHOD bssl::v3_info = {
38
    NID_info_access,
39
    X509V3_EXT_MULTILINE,
40
    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
41
    nullptr,
42
    nullptr,
43
    nullptr,
44
    nullptr,
45
    nullptr,
46
    nullptr,
47
    i2v_AUTHORITY_INFO_ACCESS,
48
    v2i_AUTHORITY_INFO_ACCESS,
49
    nullptr,
50
    nullptr,
51
    nullptr,
52
};
53
54
const X509V3_EXT_METHOD bssl::v3_sinfo = {
55
    NID_sinfo_access,
56
    X509V3_EXT_MULTILINE,
57
    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
58
    nullptr,
59
    nullptr,
60
    nullptr,
61
    nullptr,
62
    nullptr,
63
    nullptr,
64
    i2v_AUTHORITY_INFO_ACCESS,
65
    v2i_AUTHORITY_INFO_ACCESS,
66
    nullptr,
67
    nullptr,
68
    nullptr,
69
};
70
71
ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
72
    ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
73
    ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME),
74
} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
75
76
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ACCESS_DESCRIPTION)
77
78
ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = ASN1_EX_TEMPLATE_TYPE(
79
    ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
80
ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
81
82
IMPLEMENT_ASN1_FUNCTIONS_const(AUTHORITY_INFO_ACCESS)
83
84
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
85
46
    const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) {
86
46
  const AUTHORITY_INFO_ACCESS *ainfo =
87
46
      reinterpret_cast<const AUTHORITY_INFO_ACCESS *>(ext);
88
46
  ACCESS_DESCRIPTION *desc;
89
46
  char objtmp[80], *name;
90
46
  CONF_VALUE *vtmp;
91
46
  STACK_OF(CONF_VALUE) *tret = ret;
92
93
98
  for (size_t i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
94
70
    STACK_OF(CONF_VALUE) *tmp;
95
96
70
    desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
97
70
    tmp = i2v_GENERAL_NAME(method, desc->location, tret);
98
70
    if (tmp == nullptr) {
99
18
      goto err;
100
18
    }
101
52
    tret = tmp;
102
52
    vtmp = sk_CONF_VALUE_value(tret, i);
103
52
    i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
104
105
52
    if (OPENSSL_asprintf(&name, "%s - %s", objtmp, vtmp->name) == -1) {
106
0
      goto err;
107
0
    }
108
52
    OPENSSL_free(vtmp->name);
109
52
    vtmp->name = name;
110
52
  }
111
28
  if (ret == nullptr && tret == nullptr) {
112
11
    return sk_CONF_VALUE_new_null();
113
11
  }
114
115
17
  return tret;
116
18
err:
117
18
  if (ret == nullptr && tret != nullptr) {
118
8
    sk_CONF_VALUE_pop_free(tret, X509V3_conf_free);
119
8
  }
120
18
  return nullptr;
121
28
}
122
123
static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method,
124
                                       const X509V3_CTX *ctx,
125
59
                                       const STACK_OF(CONF_VALUE) *nval) {
126
59
  UniquePtr<AUTHORITY_INFO_ACCESS> ainfo(sk_ACCESS_DESCRIPTION_new_null());
127
59
  if (ainfo == nullptr) {
128
0
    return nullptr;
129
0
  }
130
337
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
131
314
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
132
314
    UniquePtr<ACCESS_DESCRIPTION> acc(ACCESS_DESCRIPTION_new());
133
314
    if (acc == nullptr) {
134
0
      return nullptr;
135
0
    }
136
314
    char *ptmp = strchr(cnf->name, ';');
137
314
    if (!ptmp) {
138
19
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
139
19
      return nullptr;
140
19
    }
141
295
    CONF_VALUE ctmp;
142
295
    ctmp.name = ptmp + 1;
143
295
    ctmp.value = cnf->value;
144
295
    if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) {
145
9
      return nullptr;
146
9
    }
147
286
    UniquePtr<char> objtmp(OPENSSL_strndup(cnf->name, ptmp - cnf->name));
148
286
    if (objtmp == nullptr) {
149
0
      return nullptr;
150
0
    }
151
286
    acc->method = OBJ_txt2obj(objtmp.get(), 0);
152
286
    if (!acc->method) {
153
8
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
154
8
      ERR_add_error_data(2, "value=", objtmp.get());
155
8
      return nullptr;
156
8
    }
157
278
    if (!PushToStack(ainfo.get(), std::move(acc))) {
158
0
      return nullptr;
159
0
    }
160
278
  }
161
23
  return ainfo.release();
162
59
}