76fb0473a98e270b1c618040fe8cd12592a95691
[openssl.git] / crypto / x509 / x509_obj.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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/lhash.h>
13 #include <openssl/objects.h>
14 #include <openssl/x509.h>
15 #include <openssl/buffer.h>
16 #include "internal/x509_int.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
25 char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
26 {
27     X509_NAME_ENTRY *ne;
28     int i;
29     int n, lold, l, l1, l2, num, j, type;
30     const char *s;
31     char *p;
32     unsigned char *q;
33     BUF_MEM *b = NULL;
34     static const char hex[17] = "0123456789ABCDEF";
35     int gs_doit[4];
36     char tmp_buf[80];
37 #ifdef CHARSET_EBCDIC
38     unsigned char ebcdic_buf[1024];
39 #endif
40
41     if (buf == NULL) {
42         if ((b = BUF_MEM_new()) == NULL)
43             goto err;
44         if (!BUF_MEM_grow(b, 200))
45             goto err;
46         b->data[0] = '\0';
47         len = 200;
48     } else if (len == 0) {
49         return NULL;
50     }
51     if (a == NULL) {
52         if (b) {
53             buf = b->data;
54             OPENSSL_free(b);
55         }
56         strncpy(buf, "NO X509_NAME", len);
57         buf[len - 1] = '\0';
58         return buf;
59     }
60
61     len--;                      /* space for '\0' */
62     l = 0;
63     for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
64         ne = sk_X509_NAME_ENTRY_value(a->entries, i);
65         n = OBJ_obj2nid(ne->object);
66         if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
67             i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
68             s = tmp_buf;
69         }
70         l1 = strlen(s);
71
72         type = ne->value->type;
73         num = ne->value->length;
74         if (num > NAME_ONELINE_MAX) {
75             X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
76             goto end;
77         }
78         q = ne->value->data;
79 #ifdef CHARSET_EBCDIC
80         if (type == V_ASN1_GENERALSTRING ||
81             type == V_ASN1_VISIBLESTRING ||
82             type == V_ASN1_PRINTABLESTRING ||
83             type == V_ASN1_TELETEXSTRING ||
84             type == V_ASN1_IA5STRING) {
85             if (num > (int)sizeof(ebcdic_buf))
86                 num = sizeof(ebcdic_buf);
87             ascii2ebcdic(ebcdic_buf, q, num);
88             q = ebcdic_buf;
89         }
90 #endif
91
92         if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
93             gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
94             for (j = 0; j < num; j++)
95                 if (q[j] != 0)
96                     gs_doit[j & 3] = 1;
97
98             if (gs_doit[0] | gs_doit[1] | gs_doit[2])
99                 gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
100             else {
101                 gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
102                 gs_doit[3] = 1;
103             }
104         } else
105             gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
106
107         for (l2 = j = 0; j < num; j++) {
108             if (!gs_doit[j & 3])
109                 continue;
110             l2++;
111 #ifndef CHARSET_EBCDIC
112             if ((q[j] < ' ') || (q[j] > '~'))
113                 l2 += 3;
114 #else
115             if ((os_toascii[q[j]] < os_toascii[' ']) ||
116                 (os_toascii[q[j]] > os_toascii['~']))
117                 l2 += 3;
118 #endif
119         }
120
121         lold = l;
122         l += 1 + l1 + 1 + l2;
123         if (l > NAME_ONELINE_MAX) {
124             X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
125             goto end;
126         }
127         if (b != NULL) {
128             if (!BUF_MEM_grow(b, l + 1))
129                 goto err;
130             p = &(b->data[lold]);
131         } else if (l > len) {
132             break;
133         } else
134             p = &(buf[lold]);
135         *(p++) = '/';
136         memcpy(p, s, (unsigned int)l1);
137         p += l1;
138         *(p++) = '=';
139
140 #ifndef CHARSET_EBCDIC          /* q was assigned above already. */
141         q = ne->value->data;
142 #endif
143
144         for (j = 0; j < num; j++) {
145             if (!gs_doit[j & 3])
146                 continue;
147 #ifndef CHARSET_EBCDIC
148             n = q[j];
149             if ((n < ' ') || (n > '~')) {
150                 *(p++) = '\\';
151                 *(p++) = 'x';
152                 *(p++) = hex[(n >> 4) & 0x0f];
153                 *(p++) = hex[n & 0x0f];
154             } else
155                 *(p++) = n;
156 #else
157             n = os_toascii[q[j]];
158             if ((n < os_toascii[' ']) || (n > os_toascii['~'])) {
159                 *(p++) = '\\';
160                 *(p++) = 'x';
161                 *(p++) = hex[(n >> 4) & 0x0f];
162                 *(p++) = hex[n & 0x0f];
163             } else
164                 *(p++) = q[j];
165 #endif
166         }
167         *p = '\0';
168     }
169     if (b != NULL) {
170         p = b->data;
171         OPENSSL_free(b);
172     } else
173         p = buf;
174     if (i == 0)
175         *p = '\0';
176     return (p);
177  err:
178     X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
179  end:
180     BUF_MEM_free(b);
181     return (NULL);
182 }