44a9db1829105df2725b6c98230de699905455c9
[openssl.git] / test / x509aux.c
1 /*
2  * Copyright 2016 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             fprintf(stderr, "unexpected PEM object: %s\n", name);
57             err = 1;
58             goto next;
59         }
60         cert = d2i(NULL, &p, len);
61
62         if (cert == NULL || (p - data) != len) {
63             fprintf(stderr, "error parsing input %s\n", 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             fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
72                     enclen, name, len);
73             err = 1;
74             goto next;
75         }
76         if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
77             perror("malloc");
78             err = 1;
79             goto next;
80         }
81         enclen = i2d(cert, &bufp);
82         if (len != enclen) {
83             fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
84                     enclen, name, len);
85             err = 1;
86             goto next;
87         }
88         enclen = (long) (bufp - buf);
89         if (enclen != len) {
90             fprintf(stderr, "unexpected buffer position after encoding %s\n",
91                     name);
92             err = 1;
93             goto next;
94         }
95         if (memcmp(buf, data, len) != 0) {
96             fprintf(stderr, "encoded content of %s does not match input\n",
97                     name);
98             err = 1;
99             goto next;
100         }
101         OPENSSL_free(buf);
102         buf = NULL;
103
104         /* Test 1-pass encoding into library allocated buffer */
105         enclen = i2d(cert, &buf);
106         if (len != enclen) {
107             fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
108                     enclen, name, len);
109             err = 1;
110             goto next;
111         }
112         if (memcmp(buf, data, len) != 0) {
113             fprintf(stderr, "encoded content of %s does not match input\n",
114                     name);
115             err = 1;
116             goto next;
117         }
118
119         if (trusted) {
120             /* Encode just the cert and compare with initial encoding */
121             OPENSSL_free(buf);
122             buf = NULL;
123
124             /* Test 1-pass encoding into library allocated buffer */
125             enclen = i2d(cert, &buf);
126             if (enclen > len) {
127                 fprintf(stderr, "encoded length %ld of %s > input length %ld\n",
128                         enclen, name, len);
129                 err = 1;
130                 goto next;
131             }
132             if (memcmp(buf, data, enclen) != 0) {
133                 fprintf(stderr, "encoded cert content does not match input\n");
134                 err = 1;
135                 goto next;
136             }
137         }
138
139         /*
140          * If any of these were null, PEM_read() would have failed.
141          */
142     next:
143         X509_free(cert);
144         OPENSSL_free(buf);
145         OPENSSL_free(name);
146         OPENSSL_free(header);
147         OPENSSL_free(data);
148     }
149     BIO_free(fp);
150
151     if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
152         /* Reached end of PEM file */
153         if (count > 0) {
154             ERR_clear_error();
155             return 1;
156         }
157     }
158
159     /* Some other PEM read error */
160     return 0;
161 }
162
163 int test_main(int argc, char *argv[])
164 {
165     if (argc < 2) {
166         TEST_error("usage: %s certfile...", argv[0]);
167         return 0;
168     }
169
170     files = &argv[1];
171     ADD_ALL_TESTS(test_certs, argc - 1);
172     return run_tests(argv[0]);
173 }