In OpenSSL builds, declare STACK for datatypes ...
[openssl.git] / crypto / x509 / x509_obj.c
1 /*
2  * Copyright 1995-2017 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
17 DEFINE_STACK_OF(X509_NAME_ENTRY)
18
19 /*
20  * Limit to ensure we don't overflow: much greater than
21  * anything encountered in practice.
22  */
23
24 #define NAME_ONELINE_MAX    (1024 * 1024)
25
26 char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
27 {
28     const X509_NAME_ENTRY *ne;
29     int i;
30     int n, lold, l, l1, l2, num, j, type;
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             X509err(X509_F_X509_NAME_ONELINE, 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 #ifndef CHARSET_EBCDIC
113             if ((q[j] < ' ') || (q[j] > '~'))
114                 l2 += 3;
115 #else
116             if ((os_toascii[q[j]] < os_toascii[' ']) ||
117                 (os_toascii[q[j]] > os_toascii['~']))
118                 l2 += 3;
119 #endif
120         }
121
122         lold = l;
123         l += 1 + l1 + 1 + l2;
124         if (l > NAME_ONELINE_MAX) {
125             X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
126             goto end;
127         }
128         if (b != NULL) {
129             if (!BUF_MEM_grow(b, l + 1))
130                 goto err;
131             p = &(b->data[lold]);
132         } else if (l > len) {
133             break;
134         } else
135             p = &(buf[lold]);
136         *(p++) = '/';
137         memcpy(p, s, (unsigned int)l1);
138         p += l1;
139         *(p++) = '=';
140
141 #ifndef CHARSET_EBCDIC          /* q was assigned above already. */
142         q = ne->value->data;
143 #endif
144
145         for (j = 0; j < num; j++) {
146             if (!gs_doit[j & 3])
147                 continue;
148 #ifndef CHARSET_EBCDIC
149             n = q[j];
150             if ((n < ' ') || (n > '~')) {
151                 *(p++) = '\\';
152                 *(p++) = 'x';
153                 *(p++) = hex[(n >> 4) & 0x0f];
154                 *(p++) = hex[n & 0x0f];
155             } else
156                 *(p++) = n;
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                 *(p++) = q[j];
166 #endif
167         }
168         *p = '\0';
169     }
170     if (b != NULL) {
171         p = b->data;
172         OPENSSL_free(b);
173     } else
174         p = buf;
175     if (i == 0)
176         *p = '\0';
177     return p;
178  err:
179     X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
180  end:
181     BUF_MEM_free(b);
182     return NULL;
183 }