1/* 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#include <stdio.h> 11#include "internal/cryptlib.h" 12#include <openssl/objects.h> 13#include <openssl/x509.h> 14#include <openssl/buffer.h> 15#include "crypto/x509.h" 16#include "crypto/ctype.h" 17 18/* 19 * Limit to ensure we don't overflow: much greater than 20 * anything encountered in practice. 21 */ 22 23#define NAME_ONELINE_MAX (1024 * 1024) 24 25char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) 26{ 27 const X509_NAME_ENTRY *ne; 28 int i; 29 int n, lold, l, l1, l2, num, j, type; 30 int prev_set = -1; 31 const char *s; 32 char *p; 33 unsigned char *q; 34 BUF_MEM *b = NULL; 35 static const char hex[17] = "0123456789ABCDEF"; 36 int gs_doit[4]; 37 char tmp_buf[80]; 38#ifdef CHARSET_EBCDIC 39 unsigned char ebcdic_buf[1024]; 40#endif 41 42 if (buf == NULL) { 43 if ((b = BUF_MEM_new()) == NULL) 44 goto err; 45 if (!BUF_MEM_grow(b, 200)) 46 goto err; 47 b->data[0] = '\0'; 48 len = 200; 49 } else if (len == 0) { 50 return NULL; 51 } 52 if (a == NULL) { 53 if (b) { 54 buf = b->data; 55 OPENSSL_free(b); 56 } 57 strncpy(buf, "NO X509_NAME", len); 58 buf[len - 1] = '\0'; 59 return buf; 60 } 61 62 len--; /* space for '\0' */ 63 l = 0; 64 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 65 ne = sk_X509_NAME_ENTRY_value(a->entries, i); 66 n = OBJ_obj2nid(ne->object); 67 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { 68 i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); 69 s = tmp_buf; 70 } 71 l1 = strlen(s); 72 73 type = ne->value->type; 74 num = ne->value->length; 75 if (num > NAME_ONELINE_MAX) { 76 ERR_raise(ERR_LIB_X509, X509_R_NAME_TOO_LONG); 77 goto end; 78 } 79 q = ne->value->data; 80#ifdef CHARSET_EBCDIC 81 if (type == V_ASN1_GENERALSTRING || 82 type == V_ASN1_VISIBLESTRING || 83 type == V_ASN1_PRINTABLESTRING || 84 type == V_ASN1_TELETEXSTRING || 85 type == V_ASN1_IA5STRING) { 86 if (num > (int)sizeof(ebcdic_buf)) 87 num = sizeof(ebcdic_buf); 88 ascii2ebcdic(ebcdic_buf, q, num); 89 q = ebcdic_buf; 90 } 91#endif 92 93 if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { 94 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; 95 for (j = 0; j < num; j++) 96 if (q[j] != 0) 97 gs_doit[j & 3] = 1; 98 99 if (gs_doit[0] | gs_doit[1] | gs_doit[2]) 100 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; 101 else { 102 gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; 103 gs_doit[3] = 1; 104 } 105 } else 106 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; 107 108 for (l2 = j = 0; j < num; j++) { 109 if (!gs_doit[j & 3]) 110 continue; 111 l2++; 112 if (q[j] == '/' || q[j] == '+') 113 l2++; /* char needs to be escaped */ 114 else if ((ossl_toascii(q[j]) < ossl_toascii(' ')) || 115 (ossl_toascii(q[j]) > ossl_toascii('~'))) 116 l2 += 3; 117 } 118 119 lold = l; 120 l += 1 + l1 + 1 + l2; 121 if (l > NAME_ONELINE_MAX) { 122 ERR_raise(ERR_LIB_X509, X509_R_NAME_TOO_LONG); 123 goto end; 124 } 125 if (b != NULL) { 126 if (!BUF_MEM_grow(b, l + 1)) 127 goto err; 128 p = &(b->data[lold]); 129 } else if (l > len) { 130 break; 131 } else 132 p = &(buf[lold]); 133 *(p++) = prev_set == ne->set ? '+' : '/'; 134 memcpy(p, s, (unsigned int)l1); 135 p += l1; 136 *(p++) = '='; 137 138#ifndef CHARSET_EBCDIC /* q was assigned above already. */ 139 q = ne->value->data; 140#endif 141 142 for (j = 0; j < num; j++) { 143 if (!gs_doit[j & 3]) 144 continue; 145#ifndef CHARSET_EBCDIC 146 n = q[j]; 147 if ((n < ' ') || (n > '~')) { 148 *(p++) = '\\'; 149 *(p++) = 'x'; 150 *(p++) = hex[(n >> 4) & 0x0f]; 151 *(p++) = hex[n & 0x0f]; 152 } else { 153 if (n == '/' || n == '+') 154 *(p++) = '\\'; 155 *(p++) = n; 156 } 157#else 158 n = os_toascii[q[j]]; 159 if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { 160 *(p++) = '\\'; 161 *(p++) = 'x'; 162 *(p++) = hex[(n >> 4) & 0x0f]; 163 *(p++) = hex[n & 0x0f]; 164 } else { 165 if (n == os_toascii['/'] || n == os_toascii['+']) 166 *(p++) = '\\'; 167 *(p++) = q[j]; 168 } 169#endif 170 } 171 *p = '\0'; 172 prev_set = ne->set; 173 } 174 if (b != NULL) { 175 p = b->data; 176 OPENSSL_free(b); 177 } else 178 p = buf; 179 if (i == 0) 180 *p = '\0'; 181 return p; 182 err: 183 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 184 end: 185 BUF_MEM_free(b); 186 return NULL; 187} 188