1/*
| 1/*
|
2 * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
| 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>
| 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 "internal/nelem.h" 20#include "testutil.h"
| |
21
| 19
|
22static int test_certs(int num)
| 20#include "../e_os.h" 21 22static const char *progname; 23 24static void test_usage(void)
|
23{
| 25{
|
24 int c;
| 26 fprintf(stderr, "usage: %s certfile\n", progname); 27} 28 29static void print_errors(void) 30{ 31 unsigned long err; 32 char buffer[1024]; 33 const char *file; 34 const char *data; 35 int line; 36 int flags; 37 38 while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { 39 ERR_error_string_n(err, buffer, sizeof(buffer)); 40 if (flags & ERR_TXT_STRING) 41 fprintf(stderr, "Error: %s:%s:%d:%s\n", buffer, file, line, data); 42 else 43 fprintf(stderr, "Error: %s:%s:%d\n", buffer, file, line); 44 } 45} 46 47static int test_certs(BIO *fp) 48{ 49 int count;
|
25 char *name = 0; 26 char *header = 0; 27 unsigned char *data = 0; 28 long len; 29 typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long); 30 typedef int (*i2d_X509_t)(X509 *, unsigned char **); 31 int err = 0;
| 50 char *name = 0; 51 char *header = 0; 52 unsigned char *data = 0; 53 long len; 54 typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long); 55 typedef int (*i2d_X509_t)(X509 *, unsigned char **); 56 int err = 0;
|
32 BIO *fp = BIO_new_file(test_get_argument(num), "r"); 33 X509 *reuse = NULL;
| |
34
| 57
|
35 if (!TEST_ptr(fp)) 36 return 0; 37 38 for (c = 0; !err && PEM_read_bio(fp, &name, &header, &data, &len); ++c) { 39 const int trusted = (strcmp(name, PEM_STRING_X509_TRUSTED) == 0); 40
| 58 for (count = 0; 59 !err && PEM_read_bio(fp, &name, &header, &data, &len); 60 ++count) { 61 int trusted = strcmp(name, PEM_STRING_X509_TRUSTED) == 0;
|
41 d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509; 42 i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509; 43 X509 *cert = NULL;
| 62 d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509; 63 i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509; 64 X509 *cert = NULL;
|
44 const unsigned char *p = data;
| 65 const unsigned char *p = data;
|
45 unsigned char *buf = NULL; 46 unsigned char *bufp; 47 long enclen; 48
| 66 unsigned char *buf = NULL; 67 unsigned char *bufp; 68 long enclen; 69
|
49 if (!trusted
| 70 if (!trusted
|
50 && strcmp(name, PEM_STRING_X509) != 0
| 71 && strcmp(name, PEM_STRING_X509) != 0
|
51 && strcmp(name, PEM_STRING_X509_OLD) != 0) { 52 TEST_error("unexpected PEM object: %s", name);
| 72 && strcmp(name, PEM_STRING_X509_OLD) != 0) { 73 fprintf(stderr, "unexpected PEM object: %s\n", name);
|
53 err = 1;
| 74 err = 1;
|
54 goto next;
| 75 goto next;
|
55 } 56 cert = d2i(NULL, &p, len); 57 58 if (cert == NULL || (p - data) != len) {
| 76 } 77 cert = d2i(NULL, &p, len); 78 79 if (cert == NULL || (p - data) != len) {
|
59 TEST_error("error parsing input %s", name);
| 80 fprintf(stderr, "error parsing input %s\n", name);
|
60 err = 1; 61 goto next; 62 } 63 64 /* Test traditional 2-pass encoding into caller allocated buffer */ 65 enclen = i2d(cert, NULL); 66 if (len != enclen) {
| 81 err = 1; 82 goto next; 83 } 84 85 /* Test traditional 2-pass encoding into caller allocated buffer */ 86 enclen = i2d(cert, NULL); 87 if (len != enclen) {
|
67 TEST_error("encoded length %ld of %s != input length %ld", 68 enclen, name, len);
| 88 fprintf(stderr, "encoded length %ld of %s != input length %ld\n", 89 enclen, name, len);
|
69 err = 1; 70 goto next; 71 } 72 if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
| 90 err = 1; 91 goto next; 92 } 93 if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
|
73 TEST_perror("malloc");
| 94 perror("malloc");
|
74 err = 1; 75 goto next; 76 } 77 enclen = i2d(cert, &bufp); 78 if (len != enclen) {
| 95 err = 1; 96 goto next; 97 } 98 enclen = i2d(cert, &bufp); 99 if (len != enclen) {
|
79 TEST_error("encoded length %ld of %s != input length %ld", 80 enclen, name, len);
| 100 fprintf(stderr, "encoded length %ld of %s != input length %ld\n", 101 enclen, name, len);
|
81 err = 1; 82 goto next; 83 } 84 enclen = (long) (bufp - buf); 85 if (enclen != len) {
| 102 err = 1; 103 goto next; 104 } 105 enclen = (long) (bufp - buf); 106 if (enclen != len) {
|
86 TEST_error("unexpected buffer position after encoding %s", name);
| 107 fprintf(stderr, "unexpected buffer position after encoding %s\n", 108 name);
|
87 err = 1; 88 goto next; 89 } 90 if (memcmp(buf, data, len) != 0) {
| 109 err = 1; 110 goto next; 111 } 112 if (memcmp(buf, data, len) != 0) {
|
91 TEST_error("encoded content of %s does not match input", name);
| 113 fprintf(stderr, "encoded content of %s does not match input\n", 114 name);
|
92 err = 1; 93 goto next; 94 }
| 115 err = 1; 116 goto next; 117 }
|
95 p = buf; 96 reuse = d2i(&reuse, &p, enclen); 97 if (reuse == NULL || X509_cmp (reuse, cert)) { 98 TEST_error("X509_cmp does not work with %s", name); 99 err = 1; 100 goto next; 101 }
| |
102 OPENSSL_free(buf); 103 buf = NULL; 104 105 /* Test 1-pass encoding into library allocated buffer */ 106 enclen = i2d(cert, &buf); 107 if (len != enclen) {
| 118 OPENSSL_free(buf); 119 buf = NULL; 120 121 /* Test 1-pass encoding into library allocated buffer */ 122 enclen = i2d(cert, &buf); 123 if (len != enclen) {
|
108 TEST_error("encoded length %ld of %s != input length %ld", 109 enclen, name, len);
| 124 fprintf(stderr, "encoded length %ld of %s != input length %ld\n", 125 enclen, name, len);
|
110 err = 1; 111 goto next; 112 } 113 if (memcmp(buf, data, len) != 0) {
| 126 err = 1; 127 goto next; 128 } 129 if (memcmp(buf, data, len) != 0) {
|
114 TEST_error("encoded content of %s does not match input", name);
| 130 fprintf(stderr, "encoded content of %s does not match input\n", 131 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) {
| 132 err = 1; 133 goto next; 134 } 135 136 if (trusted) { 137 /* Encode just the cert and compare with initial encoding */ 138 OPENSSL_free(buf); 139 buf = NULL; 140 141 /* Test 1-pass encoding into library allocated buffer */ 142 enclen = i2d(cert, &buf); 143 if (enclen > len) {
|
127 TEST_error("encoded length %ld of %s > input length %ld", 128 enclen, name, len);
| 144 fprintf(stderr, "encoded length %ld of %s > input length %ld\n", 145 enclen, name, len);
|
129 err = 1; 130 goto next; 131 } 132 if (memcmp(buf, data, enclen) != 0) {
| 146 err = 1; 147 goto next; 148 } 149 if (memcmp(buf, data, enclen) != 0) {
|
133 TEST_error("encoded cert content does not match input");
| 150 fprintf(stderr, "encoded cert content does not match input\n");
|
134 err = 1; 135 goto next; 136 } 137 } 138
| 151 err = 1; 152 goto next; 153 } 154 } 155
|
139 /* 140 * If any of these were null, PEM_read() would have failed. 141 */
| 156 /* 157 * If any of these were null, PEM_read() would have failed. 158 */
|
142 next: 143 X509_free(cert); 144 OPENSSL_free(buf);
| 159 next: 160 X509_free(cert); 161 OPENSSL_free(buf);
|
145 OPENSSL_free(name); 146 OPENSSL_free(header); 147 OPENSSL_free(data);
| 162 OPENSSL_free(name); 163 OPENSSL_free(header); 164 OPENSSL_free(data);
|
148 }
| 165 }
|
149 BIO_free(fp); 150 X509_free(reuse);
| |
151 152 if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { 153 /* Reached end of PEM file */
| 166 167 if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { 168 /* Reached end of PEM file */
|
154 if (c > 0) {
| 169 if (count > 0) {
|
155 ERR_clear_error(); 156 return 1; 157 } 158 } 159 160 /* Some other PEM read error */
| 170 ERR_clear_error(); 171 return 1; 172 } 173 } 174 175 /* Some other PEM read error */
|
| 176 print_errors();
|
161 return 0; 162} 163
| 177 return 0; 178} 179
|
164int setup_tests(void)
| 180int main(int argc, char *argv[])
|
165{
| 181{
|
166 size_t n = test_get_argument_count();
| 182 BIO *bio_err; 183 const char *p; 184 int ret = 1;
|
167
| 185
|
168 if (n == 0) { 169 TEST_error("usage: %s certfile...", test_get_program_name()); 170 return 0;
| 186 progname = argv[0]; 187 if (argc < 2) { 188 test_usage(); 189 EXIT(ret);
|
171 } 172
| 190 } 191
|
173 ADD_ALL_TESTS(test_certs, (int)n); 174 return 1;
| 192 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 193 194 p = getenv("OPENSSL_DEBUG_MEMORY"); 195 if (p != NULL && strcmp(p, "on") == 0) 196 CRYPTO_set_mem_debug(1); 197 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 198 199 argc--; 200 argv++; 201 202 while (argc >= 1) { 203 BIO *f = BIO_new_file(*argv, "r"); 204 int ok; 205 206 if (f == NULL) { 207 fprintf(stderr, "%s: Error opening cert file: '%s': %s\n", 208 progname, *argv, strerror(errno)); 209 EXIT(ret); 210 } 211 ret = !(ok = test_certs(f)); 212 BIO_free(f); 213 214 if (!ok) { 215 printf("%s ERROR\n", *argv); 216 ret = 1; 217 break; 218 } 219 printf("%s OK\n", *argv); 220 221 argc--; 222 argv++; 223 } 224 225#ifndef OPENSSL_NO_CRYPTO_MDEBUG 226 if (CRYPTO_mem_leaks(bio_err) <= 0) 227 ret = 1; 228#endif 229 BIO_free(bio_err); 230 EXIT(ret);
|
175}
| 231}
|