1/*
| 1/*
|
2 * Copyright 2016-2018 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
| 57
|
34 if (!TEST_ptr(fp)) 35 return 0; 36 37 for (c = 0; !err && PEM_read_bio(fp, &name, &header, &data, &len); ++c) { 38 const int trusted = (strcmp(name, PEM_STRING_X509_TRUSTED) == 0); 39
| 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;
|
40 d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509; 41 i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509; 42 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;
|
43 const unsigned char *p = data;
| 65 const unsigned char *p = data;
|
44 unsigned char *buf = NULL; 45 unsigned char *bufp; 46 long enclen; 47
| 66 unsigned char *buf = NULL; 67 unsigned char *bufp; 68 long enclen; 69
|
48 if (!trusted
| 70 if (!trusted
|
49 && strcmp(name, PEM_STRING_X509) != 0
| 71 && strcmp(name, PEM_STRING_X509) != 0
|
50 && strcmp(name, PEM_STRING_X509_OLD) != 0) { 51 TEST_error("unexpected PEM object: %s", name);
| 72 && strcmp(name, PEM_STRING_X509_OLD) != 0) { 73 fprintf(stderr, "unexpected PEM object: %s\n", name);
|
52 err = 1;
| 74 err = 1;
|
53 goto next;
| 75 goto next;
|
54 } 55 cert = d2i(NULL, &p, len); 56 57 if (cert == NULL || (p - data) != len) {
| 76 } 77 cert = d2i(NULL, &p, len); 78 79 if (cert == NULL || (p - data) != len) {
|
58 TEST_error("error parsing input %s", name);
| 80 fprintf(stderr, "error parsing input %s\n", name);
|
59 err = 1; 60 goto next; 61 } 62 63 /* Test traditional 2-pass encoding into caller allocated buffer */ 64 enclen = i2d(cert, NULL); 65 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) {
|
66 TEST_error("encoded length %ld of %s != input length %ld", 67 enclen, name, len);
| 88 fprintf(stderr, "encoded length %ld of %s != input length %ld\n", 89 enclen, name, len);
|
68 err = 1; 69 goto next; 70 } 71 if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
| 90 err = 1; 91 goto next; 92 } 93 if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
|
72 TEST_perror("malloc");
| 94 perror("malloc");
|
73 err = 1; 74 goto next; 75 } 76 enclen = i2d(cert, &bufp); 77 if (len != enclen) {
| 95 err = 1; 96 goto next; 97 } 98 enclen = i2d(cert, &bufp); 99 if (len != enclen) {
|
78 TEST_error("encoded length %ld of %s != input length %ld", 79 enclen, name, len);
| 100 fprintf(stderr, "encoded length %ld of %s != input length %ld\n", 101 enclen, name, len);
|
80 err = 1; 81 goto next; 82 } 83 enclen = (long) (bufp - buf); 84 if (enclen != len) {
| 102 err = 1; 103 goto next; 104 } 105 enclen = (long) (bufp - buf); 106 if (enclen != len) {
|
85 TEST_error("unexpected buffer position after encoding %s", name);
| 107 fprintf(stderr, "unexpected buffer position after encoding %s\n", 108 name);
|
86 err = 1; 87 goto next; 88 } 89 if (memcmp(buf, data, len) != 0) {
| 109 err = 1; 110 goto next; 111 } 112 if (memcmp(buf, data, len) != 0) {
|
90 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);
|
91 err = 1; 92 goto next; 93 } 94 OPENSSL_free(buf); 95 buf = NULL; 96 97 /* Test 1-pass encoding into library allocated buffer */ 98 enclen = i2d(cert, &buf); 99 if (len != enclen) {
| 115 err = 1; 116 goto next; 117 } 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) {
|
100 TEST_error("encoded length %ld of %s != input length %ld", 101 enclen, name, len);
| 124 fprintf(stderr, "encoded length %ld of %s != input length %ld\n", 125 enclen, name, len);
|
102 err = 1; 103 goto next; 104 } 105 if (memcmp(buf, data, len) != 0) {
| 126 err = 1; 127 goto next; 128 } 129 if (memcmp(buf, data, len) != 0) {
|
106 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);
|
107 err = 1; 108 goto next; 109 } 110 111 if (trusted) { 112 /* Encode just the cert and compare with initial encoding */ 113 OPENSSL_free(buf); 114 buf = NULL; 115 116 /* Test 1-pass encoding into library allocated buffer */ 117 enclen = i2d(cert, &buf); 118 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) {
|
119 TEST_error("encoded length %ld of %s > input length %ld", 120 enclen, name, len);
| 144 fprintf(stderr, "encoded length %ld of %s > input length %ld\n", 145 enclen, name, len);
|
121 err = 1; 122 goto next; 123 } 124 if (memcmp(buf, data, enclen) != 0) {
| 146 err = 1; 147 goto next; 148 } 149 if (memcmp(buf, data, enclen) != 0) {
|
125 TEST_error("encoded cert content does not match input");
| 150 fprintf(stderr, "encoded cert content does not match input\n");
|
126 err = 1; 127 goto next; 128 } 129 } 130
| 151 err = 1; 152 goto next; 153 } 154 } 155
|
131 /* 132 * If any of these were null, PEM_read() would have failed. 133 */
| 156 /* 157 * If any of these were null, PEM_read() would have failed. 158 */
|
134 next: 135 X509_free(cert); 136 OPENSSL_free(buf);
| 159 next: 160 X509_free(cert); 161 OPENSSL_free(buf);
|
137 OPENSSL_free(name); 138 OPENSSL_free(header); 139 OPENSSL_free(data);
| 162 OPENSSL_free(name); 163 OPENSSL_free(header); 164 OPENSSL_free(data);
|
140 }
| 165 }
|
141 BIO_free(fp);
| |
142 143 if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { 144 /* 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 */
|
145 if (c > 0) {
| 169 if (count > 0) {
|
146 ERR_clear_error(); 147 return 1; 148 } 149 } 150 151 /* Some other PEM read error */
| 170 ERR_clear_error(); 171 return 1; 172 } 173 } 174 175 /* Some other PEM read error */
|
| 176 print_errors();
|
152 return 0; 153} 154
| 177 return 0; 178} 179
|
155int setup_tests(void)
| 180int main(int argc, char *argv[])
|
156{
| 181{
|
157 size_t n = test_get_argument_count();
| 182 BIO *bio_err; 183 const char *p; 184 int ret = 1;
|
158
| 185
|
159 if (n == 0) { 160 TEST_error("usage: %s certfile...", test_get_program_name()); 161 return 0;
| 186 progname = argv[0]; 187 if (argc < 2) { 188 test_usage(); 189 EXIT(ret);
|
162 } 163
| 190 } 191
|
164 ADD_ALL_TESTS(test_certs, (int)n); 165 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);
|
166}
| 231}
|