Coverage Report

Created: 2026-04-30 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/x509_obj.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 <string.h>
16
17
#include <openssl/buf.h>
18
#include <openssl/err.h>
19
#include <openssl/mem.h>
20
#include <openssl/obj.h>
21
#include <openssl/x509.h>
22
23
#include "../internal.h"
24
#include "internal.h"
25
26
27
// Limit to ensure we don't overflow: much greater than
28
// anything encountered in practice.
29
30
26.6k
#define NAME_ONELINE_MAX (1024 * 1024)
31
32
using namespace bssl;
33
34
6.56k
char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) {
35
6.56k
  X509_NAME_ENTRY *ne;
36
6.56k
  size_t i;
37
6.56k
  int n, lold, l, l1, l2, num, j, type;
38
6.56k
  const char *s;
39
6.56k
  char *p;
40
6.56k
  unsigned char *q;
41
6.56k
  BUF_MEM *b = nullptr;
42
6.56k
  static const char hex[17] = "0123456789ABCDEF";
43
6.56k
  int gs_doit[4];
44
6.56k
  char tmp_buf[80];
45
46
6.56k
  const auto *name = a ? FromOpaque(a) : nullptr;
47
48
6.56k
  if (buf == nullptr) {
49
6.14k
    if ((b = BUF_MEM_new()) == nullptr) {
50
0
      goto err;
51
0
    }
52
6.14k
    if (!BUF_MEM_grow(b, 200)) {
53
0
      goto err;
54
0
    }
55
6.14k
    b->data[0] = '\0';
56
6.14k
    len = 200;
57
6.14k
  } else if (len <= 0) {
58
0
    return nullptr;
59
0
  }
60
6.56k
  if (a == nullptr) {
61
0
    if (b) {
62
0
      buf = b->data;
63
0
      OPENSSL_free(b);
64
0
    }
65
0
    OPENSSL_strlcpy(buf, "NO X509_NAME", len);
66
0
    return buf;
67
0
  }
68
69
6.56k
  len--;  // space for '\0'
70
6.56k
  l = 0;
71
19.9k
  for (i = 0; i < sk_X509_NAME_ENTRY_num(name->entries); i++) {
72
13.3k
    ne = sk_X509_NAME_ENTRY_value(name->entries, i);
73
13.3k
    n = OBJ_obj2nid(ne->object);
74
13.3k
    if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == nullptr)) {
75
8.29k
      i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
76
8.29k
      s = tmp_buf;
77
8.29k
    }
78
13.3k
    l1 = strlen(s);
79
80
13.3k
    type = ne->value.type;
81
13.3k
    num = ne->value.length;
82
13.3k
    if (num > NAME_ONELINE_MAX) {
83
0
      OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG);
84
0
      goto err;
85
0
    }
86
13.3k
    q = ne->value.data;
87
88
13.3k
    if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
89
268
      gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
90
2.27k
      for (j = 0; j < num; j++) {
91
2.00k
        if (q[j] != 0) {
92
1.29k
          gs_doit[j & 3] = 1;
93
1.29k
        }
94
2.00k
      }
95
96
268
      if (gs_doit[0] | gs_doit[1] | gs_doit[2]) {
97
148
        gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
98
148
      } else {
99
120
        gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
100
120
        gs_doit[3] = 1;
101
120
      }
102
13.0k
    } else {
103
13.0k
      gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
104
13.0k
    }
105
106
178k
    for (l2 = j = 0; j < num; j++) {
107
164k
      if (!gs_doit[j & 3]) {
108
141
        continue;
109
141
      }
110
164k
      l2++;
111
164k
      if ((q[j] < ' ') || (q[j] > '~')) {
112
63.2k
        l2 += 3;
113
63.2k
      }
114
164k
    }
115
116
13.3k
    lold = l;
117
13.3k
    l += 1 + l1 + 1 + l2;
118
13.3k
    if (l > NAME_ONELINE_MAX) {
119
0
      OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG);
120
0
      goto err;
121
0
    }
122
13.3k
    if (b != nullptr) {
123
12.1k
      if (!BUF_MEM_grow(b, l + 1)) {
124
0
        goto err;
125
0
      }
126
12.1k
      p = &(b->data[lold]);
127
12.1k
    } else if (l > len) {
128
6
      break;
129
1.23k
    } else {
130
1.23k
      p = &(buf[lold]);
131
1.23k
    }
132
13.3k
    *(p++) = '/';
133
13.3k
    OPENSSL_memcpy(p, s, (unsigned int)l1);
134
13.3k
    p += l1;
135
13.3k
    *(p++) = '=';
136
137
13.3k
    q = ne->value.data;
138
139
177k
    for (j = 0; j < num; j++) {
140
164k
      if (!gs_doit[j & 3]) {
141
141
        continue;
142
141
      }
143
164k
      n = q[j];
144
164k
      if ((n < ' ') || (n > '~')) {
145
63.1k
        *(p++) = '\\';
146
63.1k
        *(p++) = 'x';
147
63.1k
        *(p++) = hex[(n >> 4) & 0x0f];
148
63.1k
        *(p++) = hex[n & 0x0f];
149
101k
      } else {
150
101k
        *(p++) = n;
151
101k
      }
152
164k
    }
153
13.3k
    *p = '\0';
154
13.3k
  }
155
6.56k
  if (b != nullptr) {
156
6.14k
    p = b->data;
157
6.14k
    OPENSSL_free(b);
158
6.14k
  } else {
159
421
    p = buf;
160
421
  }
161
6.56k
  if (i == 0) {
162
736
    *p = '\0';
163
736
  }
164
6.56k
  return p;
165
0
err:
166
0
  BUF_MEM_free(b);
167
0
  return nullptr;
168
6.56k
}