1 /* $OpenBSD: keypairtest.c,v 1.4 2018/04/07 16:42:17 jsing Exp $ */ 2 /* 3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/stat.h> 19 20 #include <err.h> 21 #include <fcntl.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <unistd.h> 25 26 #include <openssl/x509.h> 27 28 #include <tls.h> 29 #include <tls_internal.h> 30 31 #define PUBKEY_HASH \ 32 "SHA256:858d0f94beb0a08eb4f13871ba57bf0a2e081287d0efbaeb3bbac59dd8f1a8e5" 33 34 char *cert_file, *key_file, *ocsp_staple_file; 35 36 static void 37 load_file(const char *filename, const uint8_t **data, size_t *data_len) 38 { 39 struct stat sb; 40 uint8_t *buf; 41 size_t len; 42 ssize_t n; 43 int fd; 44 45 if ((fd = open(filename, O_RDONLY)) == -1) 46 err(1, "failed to open '%s'", filename); 47 if ((fstat(fd, &sb)) == -1) 48 err(1, "failed to stat '%s'", filename); 49 if (sb.st_size < 0) 50 err(1, "file size invalid for '%s'", filename); 51 len = (size_t)sb.st_size; 52 if ((buf = malloc(len)) == NULL) 53 err(1, "out of memory"); 54 n = read(fd, buf, len); 55 if (n < 0 || (size_t)n != len) 56 err(1, "failed to read '%s'", filename); 57 close(fd); 58 59 *data = buf; 60 *data_len = len; 61 } 62 63 static int 64 compare_mem(char *label, const uint8_t *data1, size_t data1_len, 65 const uint8_t *data2, size_t data2_len) 66 { 67 if (data1_len != data2_len) { 68 fprintf(stderr, "FAIL: %s length mismatch (%zu != %zu)\n", 69 label, data1_len, data2_len); 70 return -1; 71 } 72 if (data1 == data2) { 73 fprintf(stderr, "FAIL: %s comparing same memory (%p == %p)\n", 74 label, data1, data2); 75 return -1; 76 } 77 if (memcmp(data1, data2, data1_len) != 0) { 78 fprintf(stderr, "FAIL: %s data mismatch\n", label); 79 return -1; 80 } 81 return 0; 82 } 83 84 static int 85 do_keypair_tests(void) 86 { 87 size_t cert_len, key_len, ocsp_staple_len; 88 const uint8_t *cert, *key, *ocsp_staple; 89 X509 *x509_cert = NULL; 90 struct tls_keypair *kp; 91 struct tls_error err; 92 char *hash = NULL; 93 int failed = 1; 94 95 load_file(cert_file, &cert, &cert_len); 96 load_file(key_file, &key, &key_len); 97 load_file(ocsp_staple_file, &ocsp_staple, &ocsp_staple_len); 98 99 if ((kp = tls_keypair_new()) == NULL) { 100 fprintf(stderr, "FAIL: failed to create keypair\n"); 101 goto done; 102 } 103 104 if (tls_keypair_set_cert_file(kp, &err, cert_file) == -1) { 105 fprintf(stderr, "FAIL: failed to load cert file: %s\n", 106 err.msg); 107 goto done; 108 } 109 if (tls_keypair_set_key_file(kp, &err, key_file) == -1) { 110 fprintf(stderr, "FAIL: failed to load key file: %s\n", err.msg); 111 goto done; 112 } 113 if (tls_keypair_set_ocsp_staple_file(kp, &err, ocsp_staple_file) == -1) { 114 fprintf(stderr, "FAIL: failed to load ocsp staple file: %s\n", 115 err.msg); 116 goto done; 117 } 118 119 if (compare_mem("certificate", cert, cert_len, kp->cert_mem, 120 kp->cert_len) == -1) 121 goto done; 122 if (compare_mem("key", key, key_len, kp->key_mem, kp->cert_len) == -1) 123 goto done; 124 if (compare_mem("ocsp staple", ocsp_staple, ocsp_staple_len, 125 kp->ocsp_staple, kp->ocsp_staple_len) == -1) 126 goto done; 127 if (strcmp(kp->pubkey_hash, PUBKEY_HASH) != 0) { 128 fprintf(stderr, "FAIL: got pubkey hash '%s', want '%s'", 129 hash, PUBKEY_HASH); 130 goto done; 131 } 132 133 tls_keypair_clear_key(kp); 134 135 if (kp->key_mem != NULL || kp->key_len != 0) { 136 fprintf(stderr, "FAIL: key not cleared (mem %p, len %zu)", 137 kp->key_mem, kp->key_len); 138 goto done; 139 } 140 141 if (tls_keypair_set_cert_mem(kp, &err, cert, cert_len) == -1) { 142 fprintf(stderr, "FAIL: failed to load cert: %s\n", err.msg); 143 goto done; 144 } 145 if (tls_keypair_set_key_mem(kp, &err, key, key_len) == -1) { 146 fprintf(stderr, "FAIL: failed to load key: %s\n", err.msg); 147 goto done; 148 } 149 if (tls_keypair_set_ocsp_staple_mem(kp, &err, ocsp_staple, 150 ocsp_staple_len) == -1) { 151 fprintf(stderr, "FAIL: failed to load ocsp staple: %s\n", err.msg); 152 goto done; 153 } 154 if (compare_mem("certificate", cert, cert_len, kp->cert_mem, 155 kp->cert_len) == -1) 156 goto done; 157 if (compare_mem("key", key, key_len, kp->key_mem, kp->cert_len) == -1) 158 goto done; 159 if (compare_mem("ocsp staple", ocsp_staple, ocsp_staple_len, 160 kp->ocsp_staple, kp->ocsp_staple_len) == -1) 161 goto done; 162 if (strcmp(kp->pubkey_hash, PUBKEY_HASH) != 0) { 163 fprintf(stderr, "FAIL: got pubkey hash '%s', want '%s'", 164 hash, PUBKEY_HASH); 165 goto done; 166 } 167 168 if (tls_keypair_load_cert(kp, &err, &x509_cert) == -1) { 169 fprintf(stderr, "FAIL: failed to load X509 certificate: %s\n", 170 err.msg); 171 goto done; 172 } 173 174 tls_keypair_clear_key(kp); 175 176 if (kp->key_mem != NULL || kp->key_len != 0) { 177 fprintf(stderr, "FAIL: key not cleared (mem %p, len %zu)", 178 kp->key_mem, kp->key_len); 179 goto done; 180 } 181 182 tls_keypair_free(kp); 183 184 failed = 0; 185 186 done: 187 X509_free(x509_cert); 188 free(hash); 189 190 return (failed); 191 } 192 193 int 194 main(int argc, char **argv) 195 { 196 int failure = 0; 197 198 if (argc != 4) { 199 fprintf(stderr, "usage: %s ocspstaplefile certfile keyfile\n", 200 argv[0]); 201 return (1); 202 } 203 204 ocsp_staple_file = argv[1]; 205 cert_file = argv[2]; 206 key_file = argv[3]; 207 208 failure |= do_keypair_tests(); 209 210 return (failure); 211 } 212