TAP line filter BIO.
[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 c;
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 (c = 0; !err && PEM_read_bio(fp, &name, &header, &data, &len); ++c) {
42         const int trusted = (strcmp(name, PEM_STRING_X509_TRUSTED) == 0);
43
44         d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509;
45         i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509;
46         X509 *cert = NULL;
47         const unsigned char *p = data;
48         unsigned char *buf = NULL;
49         unsigned char *bufp;
50         long enclen;
51
52         if (!trusted
53             && strcmp(name, PEM_STRING_X509) != 0
54             && strcmp(name, PEM_STRING_X509_OLD) != 0) {
55             TEST_error("unexpected PEM object: %s", name);
56             err = 1;
57             goto next;
58         }
59         cert = d2i(NULL, &p, len);
60
61         if (cert == NULL || (p - data) != len) {
62             TEST_error("error parsing input %s", name);
63             err = 1;
64             goto next;
65         }
66
67         /* Test traditional 2-pass encoding into caller allocated buffer */
68         enclen = i2d(cert, NULL);
69         if (len != enclen) {
70             TEST_error("encoded length %ld of %s != input length %ld",
71                        enclen, name, len);
72             err = 1;
73             goto next;
74         }
75         if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
76             TEST_perror("malloc");
77             err = 1;
78             goto next;
79         }
80         enclen = i2d(cert, &bufp);
81         if (len != enclen) {
82             TEST_error("encoded length %ld of %s != input length %ld",
83                        enclen, name, len);
84             err = 1;
85             goto next;
86         }
87         enclen = (long) (bufp - buf);
88         if (enclen != len) {
89             TEST_error("unexpected buffer position after encoding %s", name);
90             err = 1;
91             goto next;
92         }
93         if (memcmp(buf, data, len) != 0) {
94             TEST_error("encoded content of %s does not match input", name);
95             err = 1;
96             goto next;
97         }
98         OPENSSL_free(buf);
99         buf = NULL;
100
101         /* Test 1-pass encoding into library allocated buffer */
102         enclen = i2d(cert, &buf);
103         if (len != enclen) {
104             TEST_error("encoded length %ld of %s != input length %ld",
105                        enclen, name, len);
106             err = 1;
107             goto next;
108         }
109         if (memcmp(buf, data, len) != 0) {
110             TEST_error("encoded content of %s does not match input", name);
111             err = 1;
112             goto next;
113         }
114
115         if (trusted) {
116             /* Encode just the cert and compare with initial encoding */
117             OPENSSL_free(buf);
118             buf = NULL;
119
120             /* Test 1-pass encoding into library allocated buffer */
121             enclen = i2d(cert, &buf);
122             if (enclen > len) {
123                 TEST_error("encoded length %ld of %s > input length %ld",
124                            enclen, name, len);
125                 err = 1;
126                 goto next;
127             }
128             if (memcmp(buf, data, enclen) != 0) {
129                 TEST_error("encoded cert content does not match input");
130                 err = 1;
131                 goto next;
132             }
133         }
134
135         /*
136          * If any of these were null, PEM_read() would have failed.
137          */
138     next:
139         X509_free(cert);
140         OPENSSL_free(buf);
141         OPENSSL_free(name);
142         OPENSSL_free(header);
143         OPENSSL_free(data);
144     }
145     BIO_free(fp);
146
147     if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
148         /* Reached end of PEM file */
149         if (c > 0) {
150             ERR_clear_error();
151             return 1;
152         }
153     }
154
155     /* Some other PEM read error */
156     return 0;
157 }
158
159 int test_main(int argc, char *argv[])
160 {
161     if (argc < 2) {
162         TEST_error("usage: %s certfile...", argv[0]);
163         return 0;
164     }
165
166     files = &argv[1];
167     ADD_ALL_TESTS(test_certs, argc - 1);
168     return run_tests(argv[0]);
169 }