diff options
-rw-r--r-- | src/lib/libcrypto/x509/x509_local.h | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_obj.c | 221 |
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, | |||
439 | void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, | 441 | void *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 | ||
444 | int X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne); | ||
445 | |||
442 | int X509V3_add_value(const char *name, const char *value, | 446 | int X509V3_add_value(const char *name, const char *value, |
443 | STACK_OF(CONF_VALUE) **extlist); | 447 | STACK_OF(CONF_VALUE) **extlist); |
444 | int X509V3_add_value_uchar(const char *name, const unsigned char *value, | 448 | int 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 | ||
70 | static int | ||
71 | X509_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 | |||
89 | static int | ||
90 | X509_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 | |||
108 | static int | ||
109 | X509_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 | |||
146 | int | ||
147 | X509_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 | |||
70 | char * | 158 | char * |
71 | X509_NAME_oneline(const X509_NAME *a, char *buf, int len) | 159 | X509_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 | |||
176 | err: | ||
177 | X509error(ERR_R_MALLOC_FAILURE); | ||
178 | if (b != NULL) | ||
179 | BUF_MEM_free(b); | ||
180 | return (NULL); | ||
181 | } | 196 | } |
182 | LCRYPTO_ALIAS(X509_NAME_oneline); | 197 | LCRYPTO_ALIAS(X509_NAME_oneline); |