diff options
Diffstat (limited to '')
| -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); |
