024bfc9004bb0c15b6880a8e1deb81bed1a74b6f
[openssl.git] / test / x509aux.c
1 /*
2  * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL licenses, (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * https://www.openssl.org/source/license.html
8  * or in the file LICENSE in the source distribution.
9  */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14
15 #include <openssl/x509.h>
16 #include <openssl/pem.h>
17 #include <openssl/conf.h>
18 #include <openssl/err.h>
19 #include "e_os.h"
20 #include "testutil.h"
21
22
23 /* List of files, from argv */
24 static char **files;
25
26 static int test_certs(int num)
27 {
28     int count;
29     char *name = 0;
30     char *header = 0;
31     unsigned char *data = 0;
32     long len;
33     typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long);
34     typedef int (*i2d_X509_t)(X509 *, unsigned char **);
35     int err = 0;
36     BIO *fp = BIO_new_file(files[num], "r");
37
38     if (!TEST_ptr(fp))
39         return 0;
40
41     for (count = 0;
42          !err && PEM_read_bio(fp, &name, &header, &data, &len);
43          ++count) {
44         int trusted = strcmp(name, PEM_STRING_X509_TRUSTED) == 0;
45         d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509;
46         i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509;
47         X509 *cert = NULL;
48         const unsigned char *p = data;
49         unsigned char *buf = NULL;
50         unsigned char *bufp;
51         long enclen;
52
53         if (!trusted
54             && strcmp(name, PEM_STRING_X509) != 0
55             && strcmp(name, PEM_STRING_X509_OLD) != 0) {
56             TEST_error("unexpected PEM object: %s", name);
57             err = 1;
58             goto next;
59         }
60         cert = d2i(NULL, &p, len);
61
62         if (cert == NULL || (p - data) != len) {
63             TEST_error("error parsing input %s", name);
64             err = 1;
65             goto next;
66         }
67
68         /* Test traditional 2-pass encoding into caller allocated buffer */
69         enclen = i2d(cert, NULL);
70         if (len != enclen) {
71             TEST_error("encoded length %ld of %s != input length %ld",
72                        enclen, name, len);
73             err = 1;
74             goto next;
75         }
76         if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
77             TEST_perror("malloc");
78             err = 1;
79             goto next;
80         }
81         enclen = i2d(cert, &bufp);
82         if (len != enclen) {
83             TEST_error("encoded length %ld of %s != input length %ld",
84                        enclen, name, len);
85             err = 1;
86             goto next;
87         }
88         enclen = (long) (bufp - buf);
89         if (enclen != len) {
90             TEST_error("unexpected buffer position after encoding %s", name);
91             err = 1;
92             goto next;
93         }
94         if (memcmp(buf, data, len) != 0) {
95             TEST_error("encoded content of %s does not match input", name);
96             err = 1;
97             goto next;
98         }
99         OPENSSL_free(buf);
100         buf = NULL;
101
102         /* Test 1-pass encoding into library allocated buffer */
103         enclen = i2d(cert, &buf);
104         if (len != enclen) {
105             TEST_error("encoded length %ld of %s != input length %ld",
106                        enclen, name, len);
107             err = 1;
108             goto next;
109         }
110         if (memcmp(buf, data, len) != 0) {
111             TEST_error("encoded content of %s does not match input", name);
112             err = 1;
113             goto next;
114         }
115
116         if (trusted) {
117             /* Encode just the cert and compare with initial encoding */
118             OPENSSL_free(buf);
119             buf = NULL;
120
121             /* Test 1-pass encoding into library allocated buffer */
122             enclen = i2d(cert, &buf);
123             if (enclen > len) {
124                 TEST_error("encoded length %ld of %s > input length %ld",
125                            enclen, name, len);
126                 err = 1;
127                 goto next;
128             }
129             if (memcmp(buf, data, enclen) != 0) {
130                 TEST_error("encoded cert content does not match input");
131                 err = 1;
132                 goto next;
133             }
134         }
135
136         /*
137          * If any of these were null, PEM_read() would have failed.
138          */
139     next:
140         X509_free(cert);
141         OPENSSL_free(buf);
142         OPENSSL_free(name);
143         OPENSSL_free(header);
144         OPENSSL_free(data);
145     }
146     BIO_free(fp);
147
148     if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
149         /* Reached end of PEM file */
150         if (count > 0) {
151             ERR_clear_error();
152             return 1;
153         }
154     }
155
156     /* Some other PEM read error */
157     return 0;
158 }
159
160 int test_main(int argc, char *argv[])
161 {
162     if (argc < 2) {
163         TEST_error("usage: %s certfile...", argv[0]);
164         return 0;
165     }
166
167     files = &argv[1];
168     ADD_ALL_TESTS(test_certs, argc - 1);
169     return run_tests(argv[0]);
170 }