summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/x509/x509_local.h6
-rw-r--r--src/lib/libcrypto/x509/x509_obj.c221
2 files changed, 123 insertions, 104 deletions
diff --git a/src/lib/libcrypto/x509/x509_local.h b/src/lib/libcrypto/x509/x509_local.h
index e4d4b4ddd0..5240db1489 100644
--- a/src/lib/libcrypto/x509/x509_local.h
+++ b/src/lib/libcrypto/x509/x509_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_local.h,v 1.33 2024/12/04 20:07:16 tb Exp $ */ 1/* $OpenBSD: x509_local.h,v 1.34 2025/01/26 20:01:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2013. 3 * project 2013.
4 */ 4 */
@@ -61,6 +61,8 @@
61 61
62#include <openssl/x509v3.h> 62#include <openssl/x509v3.h>
63 63
64#include "bytestring.h"
65
64__BEGIN_HIDDEN_DECLS 66__BEGIN_HIDDEN_DECLS
65 67
66#define TS_HASH_EVP EVP_sha1() 68#define TS_HASH_EVP EVP_sha1()
@@ -439,6 +441,8 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
439void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, 441void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
440 const ASN1_OBJECT *obj, int lastpos, int type); 442 const ASN1_OBJECT *obj, int lastpos, int type);
441 443
444int X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne);
445
442int X509V3_add_value(const char *name, const char *value, 446int X509V3_add_value(const char *name, const char *value,
443 STACK_OF(CONF_VALUE) **extlist); 447 STACK_OF(CONF_VALUE) **extlist);
444int X509V3_add_value_uchar(const char *name, const unsigned char *value, 448int X509V3_add_value_uchar(const char *name, const unsigned char *value,
diff --git a/src/lib/libcrypto/x509/x509_obj.c b/src/lib/libcrypto/x509/x509_obj.c
index ea4ae6b98a..25cca54bdb 100644
--- a/src/lib/libcrypto/x509/x509_obj.c
+++ b/src/lib/libcrypto/x509/x509_obj.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_obj.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */ 1/* $OpenBSD: x509_obj.c,v 1.23 2025/01/26 20:01:58 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -67,116 +67,131 @@
67 67
68#include "x509_local.h" 68#include "x509_local.h"
69 69
70static int
71X509_NAME_ENTRY_add_object_cbb(CBB *cbb, const ASN1_OBJECT *aobj)
72{
73 const char *str;
74 char buf[80];
75 int nid;
76
77 /* Prefer SN over LN, and fall back to textual representation of OID. */
78 if ((nid = OBJ_obj2nid(aobj)) != NID_undef) {
79 if ((str = OBJ_nid2sn(nid)) != NULL)
80 return CBB_add_bytes(cbb, str, strlen(str));
81 if ((str = OBJ_nid2ln(nid)) != NULL)
82 return CBB_add_bytes(cbb, str, strlen(str));
83 }
84 if (OBJ_obj2txt(buf, sizeof(buf), aobj, 1) == 0)
85 return 0;
86 return CBB_add_bytes(cbb, buf, strlen(buf));
87}
88
89static int
90X509_NAME_ENTRY_add_u8_cbb(CBB *cbb, uint8_t u8)
91{
92 static const char hex[] = "0123456789ABCDEF";
93
94 if (' ' <= u8 && u8 <= '~')
95 return CBB_add_u8(cbb, u8);
96
97 if (!CBB_add_u8(cbb, '\\'))
98 return 0;
99 if (!CBB_add_u8(cbb, 'x'))
100 return 0;
101 if (!CBB_add_u8(cbb, hex[u8 >> 4]))
102 return 0;
103 if (!CBB_add_u8(cbb, hex[u8 & 0xf]))
104 return 0;
105 return 1;
106}
107
108static int
109X509_NAME_ENTRY_add_value_cbb(CBB *cbb, const ASN1_STRING *astr)
110{
111 CBS cbs;
112 uint8_t u8;
113 size_t i;
114 int mask[4] = { 1, 1, 1, 1 };
115
116 if (astr->type == V_ASN1_GENERALSTRING && astr->length % 4 == 0) {
117 int gs_mask[4] = { 0, 0, 0, 0 };
118
119 i = 0;
120 CBS_init(&cbs, astr->data, astr->length);
121 while (CBS_len(&cbs) > 0) {
122 if (!CBS_get_u8(&cbs, &u8))
123 return 0;
124
125 gs_mask[i++ & 0x3] |= u8;
126 }
127
128 if (gs_mask[0] == 0 && gs_mask[1] == 0 && gs_mask[2] == 0)
129 mask[0] = mask[1] = mask[2] = 0;
130 }
131
132 i = 0;
133 CBS_init(&cbs, astr->data, astr->length);
134 while (CBS_len(&cbs) > 0) {
135 if (!CBS_get_u8(&cbs, &u8))
136 return 0;
137 if (mask[i++ & 0x3] == 0)
138 continue;
139 if (!X509_NAME_ENTRY_add_u8_cbb(cbb, u8))
140 return 0;
141 }
142
143 return 1;
144}
145
146int
147X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne)
148{
149 if (!X509_NAME_ENTRY_add_object_cbb(cbb, ne->object))
150 return 0;
151 if (!CBB_add_u8(cbb, '='))
152 return 0;
153 if (!X509_NAME_ENTRY_add_value_cbb(cbb, ne->value))
154 return 0;
155 return 1;
156}
157
70char * 158char *
71X509_NAME_oneline(const X509_NAME *a, char *buf, int len) 159X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
72{ 160{
73 X509_NAME_ENTRY *ne; 161 CBB cbb;
162 const X509_NAME_ENTRY *ne;
163 uint8_t *line = NULL;
164 size_t line_len = 0;
74 int i; 165 int i;
75 int n, lold, l, l1, l2, num, j, type; 166
76 const char *s; 167 if (!CBB_init(&cbb, 0))
77 char *p; 168 goto err;
78 unsigned char *q; 169
79 BUF_MEM *b = NULL; 170 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
80 static const char hex[17] = "0123456789ABCDEF"; 171 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
81 int gs_doit[4]; 172 if (!CBB_add_u8(&cbb, '/'))
82 char tmp_buf[80];
83
84 if (buf == NULL) {
85 if ((b = BUF_MEM_new()) == NULL)
86 goto err; 173 goto err;
87 if (!BUF_MEM_grow(b, 200)) 174 if (!X509_NAME_ENTRY_add_cbb(&cbb, ne))
88 goto err; 175 goto err;
89 b->data[0] = '\0';
90 len = 200;
91 }
92 if (a == NULL) {
93 if (b) {
94 buf = b->data;
95 free(b);
96 }
97 strlcpy(buf, "NO X509_NAME", len);
98 return buf;
99 } 176 }
100 177
101 len--; /* space for '\0' */ 178 if (!CBB_add_u8(&cbb, '\0'))
102 l = 0; 179 goto err;
103 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
104 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
105 n = OBJ_obj2nid(ne->object);
106 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
107 i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
108 s = tmp_buf;
109 }
110 l1 = strlen(s);
111
112 type = ne->value->type;
113 num = ne->value->length;
114 q = ne->value->data;
115 if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
116 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
117 for (j = 0; j < num; j++)
118 if (q[j] != 0)
119 gs_doit[j & 3] = 1;
120
121 if (gs_doit[0]|gs_doit[1]|gs_doit[2])
122 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
123 else {
124 gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
125 gs_doit[3] = 1;
126 }
127 } else
128 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
129
130 for (l2 = j=0; j < num; j++) {
131 if (!gs_doit[j&3])
132 continue;
133 l2++;
134 if ((q[j] < ' ') || (q[j] > '~'))
135 l2 += 3;
136 }
137 180
138 lold = l; 181 if (!CBB_finish(&cbb, &line, &line_len))
139 l += 1 + l1 + 1 + l2; 182 goto err;
140 if (b != NULL) { 183
141 if (!BUF_MEM_grow(b, l + 1)) 184 if (buf == NULL)
142 goto err; 185 return line;
143 p = &(b->data[lold]); 186
144 } else if (l > len) { 187 strlcpy(buf, line, len);
145 break; 188 free(line);
146 } else 189
147 p = &(buf[lold]); 190 return buf;
148 *(p++) = '/'; 191
149 memcpy(p, s, l1); 192 err:
150 p += l1; 193 CBB_cleanup(&cbb);
151 *(p++) = '='; 194
152 q = ne->value->data; 195 return NULL;
153 for (j = 0; j < num; j++) {
154 if (!gs_doit[j & 3])
155 continue;
156 n = q[j];
157 if ((n < ' ') || (n > '~')) {
158 *(p++) = '\\';
159 *(p++) = 'x';
160 *(p++) = hex[(n >> 4) & 0x0f];
161 *(p++) = hex[n & 0x0f];
162 } else
163 *(p++) = n;
164 }
165 *p = '\0';
166 }
167 if (b != NULL) {
168 p = b->data;
169 free(b);
170 } else
171 p = buf;
172 if (i == 0)
173 *p = '\0';
174 return (p);
175
176err:
177 X509error(ERR_R_MALLOC_FAILURE);
178 if (b != NULL)
179 BUF_MEM_free(b);
180 return (NULL);
181} 196}
182LCRYPTO_ALIAS(X509_NAME_oneline); 197LCRYPTO_ALIAS(X509_NAME_oneline);