x509aux.c revision 1.1.1.3
1/* 2 * Copyright 2016-2019 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 "internal/nelem.h" 20#include "testutil.h" 21 22static int test_certs(int num) 23{ 24 int c; 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; 32 BIO *fp = BIO_new_file(test_get_argument(num), "r"); 33 X509 *reuse = NULL; 34 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 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; 44 const unsigned char *p = data; 45 unsigned char *buf = NULL; 46 unsigned char *bufp; 47 long enclen; 48 49 if (!trusted 50 && strcmp(name, PEM_STRING_X509) != 0 51 && strcmp(name, PEM_STRING_X509_OLD) != 0) { 52 TEST_error("unexpected PEM object: %s", name); 53 err = 1; 54 goto next; 55 } 56 cert = d2i(NULL, &p, len); 57 58 if (cert == NULL || (p - data) != len) { 59 TEST_error("error parsing input %s", 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) { 67 TEST_error("encoded length %ld of %s != input length %ld", 68 enclen, name, len); 69 err = 1; 70 goto next; 71 } 72 if ((buf = bufp = OPENSSL_malloc(len)) == NULL) { 73 TEST_perror("malloc"); 74 err = 1; 75 goto next; 76 } 77 enclen = i2d(cert, &bufp); 78 if (len != enclen) { 79 TEST_error("encoded length %ld of %s != input length %ld", 80 enclen, name, len); 81 err = 1; 82 goto next; 83 } 84 enclen = (long) (bufp - buf); 85 if (enclen != len) { 86 TEST_error("unexpected buffer position after encoding %s", name); 87 err = 1; 88 goto next; 89 } 90 if (memcmp(buf, data, len) != 0) { 91 TEST_error("encoded content of %s does not match input", name); 92 err = 1; 93 goto next; 94 } 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) { 108 TEST_error("encoded length %ld of %s != input length %ld", 109 enclen, name, len); 110 err = 1; 111 goto next; 112 } 113 if (memcmp(buf, data, len) != 0) { 114 TEST_error("encoded content of %s does not match input", 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 TEST_error("encoded length %ld of %s > input length %ld", 128 enclen, name, len); 129 err = 1; 130 goto next; 131 } 132 if (memcmp(buf, data, enclen) != 0) { 133 TEST_error("encoded cert content does not match input"); 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 X509_free(reuse); 151 152 if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { 153 /* Reached end of PEM file */ 154 if (c > 0) { 155 ERR_clear_error(); 156 return 1; 157 } 158 } 159 160 /* Some other PEM read error */ 161 return 0; 162} 163 164int setup_tests(void) 165{ 166 size_t n = test_get_argument_count(); 167 168 if (n == 0) { 169 TEST_error("usage: %s certfile...", test_get_program_name()); 170 return 0; 171 } 172 173 ADD_ALL_TESTS(test_certs, (int)n); 174 return 1; 175} 176