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