verifytest.c revision 1.1
1/* $OpenBSD: verifytest.c,v 1.1 2014/11/01 11:55:27 jsing Exp $ */ 2/* 3 * Copyright (c) 2014 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 <err.h> 19#include <stdio.h> 20#include <stdlib.h> 21 22#include <openssl/x509v3.h> 23 24extern int tls_check_hostname(X509 *cert, const char *host); 25 26struct verify_test { 27 const char common_name[128]; 28 const char alt_name[128]; 29 int alt_name_len; 30 int alt_name_type; 31 const char hostname[128]; 32 int want; 33}; 34 35struct verify_test verify_tests[] = { 36 { 37 .common_name = "www.openbsd.org", 38 .hostname = "www.openbsd.org", 39 .want = 0, 40 }, 41 { 42 .common_name = "www.openbsd.org", 43 .hostname = "", 44 .want = -1, 45 }, 46 { 47 .common_name = "*.openbsd.org", 48 .hostname = "www.openbsd.org", 49 .want = 0, 50 }, 51 { 52 .common_name = "www.openbsdfoundation.org", 53 .hostname = "www.openbsd.org", 54 .want = -1, 55 }, 56 { 57 .common_name = "w*.openbsd.org", 58 .hostname = "www.openbsd.org", 59 .want = -1, 60 }, 61 { 62 .common_name = "www.*.org", 63 .hostname = "www.openbsd.org", 64 .want = -1, 65 }, 66 { 67 .common_name = "www.openbsd.*", 68 .hostname = "www.openbsd.org", 69 .want = -1, 70 }, 71 { 72 .common_name = "*", 73 .hostname = "www.openbsd.org", 74 .want = -1, 75 }, 76 { 77 .common_name = "*.org", 78 .hostname = "www.openbsd.org", 79 .want = -1, 80 }, 81 { 82 .common_name = "*.org", 83 .hostname = "openbsd.org", 84 .want = -1, 85 }, 86 { 87 .common_name = "1.2.3.4", 88 .hostname = "1.2.3.4", 89 .want = 0, 90 }, 91 { 92 .common_name = "*.2.3.4", 93 .hostname = "1.2.3.4", 94 .want = -1, 95 }, 96 { 97 .common_name = "cafe::beef", 98 .hostname = "cafe::beef", 99 .want = 0, 100 }, 101 { 102 .common_name = "www.openbsd.org", 103 .alt_name = "ftp.openbsd.org", 104 .alt_name_len = -1, 105 .alt_name_type = GEN_DNS, 106 .hostname = "ftp.openbsd.org", 107 .want = 0, 108 }, 109 { 110 .common_name = "www.openbsdfoundation.org", 111 .alt_name = "*.openbsd.org", 112 .alt_name_len = -1, 113 .alt_name_type = GEN_DNS, 114 .hostname = "www.openbsd.org", 115 .want = 0, 116 }, 117 { 118 .common_name = "www.openbsdfoundation.org", 119 .alt_name = "*.org", 120 .alt_name_len = -1, 121 .alt_name_type = GEN_DNS, 122 .hostname = "www.openbsd.org", 123 .want = -1, 124 }, 125 { 126 .common_name = "www.openbsd.org", 127 .alt_name = "1.2.3.4", 128 .alt_name_len = -1, 129 .alt_name_type = GEN_DNS, 130 .hostname = "1.2.3.4", 131 .want = -1, 132 }, 133 { 134 .common_name = "www.openbsd.org", 135 .alt_name = {0x1, 0x2, 0x3, 0x4}, 136 .alt_name_len = 4, 137 .alt_name_type = GEN_IPADD, 138 .hostname = "1.2.3.4", 139 .want = 0, 140 }, 141 { 142 .common_name = "www.openbsd.org", 143 .alt_name = { 144 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xef, 146 }, 147 .alt_name_len = 16, 148 .alt_name_type = GEN_IPADD, 149 .hostname = "cafe::beef", 150 .want = 0, 151 }, 152}; 153 154#define N_VERIFY_TESTS \ 155 (sizeof(verify_tests) / sizeof(*verify_tests)) 156 157static int 158do_verify_test(int test_no, struct verify_test *vt) 159{ 160 STACK_OF(GENERAL_NAME) *alt_name_stack = NULL; 161 ASN1_STRING *alt_name_str; 162 GENERAL_NAME *alt_name; 163 X509_NAME *name; 164 X509 *cert; 165 166 /* Build certificate structure. */ 167 if ((cert = X509_new()) == NULL) 168 errx(1, "failed to malloc X509"); 169 if ((name = X509_NAME_new()) == NULL) 170 errx(1, "failed to malloc X509_NAME"); 171 if (X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC, 172 (unsigned char *)vt->common_name, -1, -1, 0) == 0) 173 errx(1, "failed to add name entry"); 174 if (X509_set_subject_name(cert, name) == 0) 175 errx(1, "failed to set subject name"); 176 X509_NAME_free(name); 177 178 if (vt->alt_name_type != 0) { 179 if ((alt_name_stack = sk_GENERAL_NAME_new_null()) == NULL) 180 errx(1, "failed to malloc sk_GENERAL_NAME"); 181 if ((alt_name = GENERAL_NAME_new()) == NULL) 182 errx(1, "failed to malloc GENERAL_NAME"); 183 alt_name->type = vt->alt_name_type; 184 185 if ((alt_name_str = ASN1_STRING_new()) == NULL) 186 errx(1, "failed to malloc alt name"); 187 if (ASN1_STRING_set(alt_name_str, vt->alt_name, 188 vt->alt_name_len) == 0) 189 errx(1, "failed to set alt name"); 190 191 switch (alt_name->type) { 192 case GEN_DNS: 193 alt_name->d.dNSName = alt_name_str; 194 break; 195 196 case GEN_IPADD: 197 alt_name->d.iPAddress = alt_name_str; 198 break; 199 200 default: 201 errx(1, "unknown alt name type (%i)", alt_name->type); 202 } 203 204 if (sk_GENERAL_NAME_push(alt_name_stack, alt_name) == 0) 205 errx(1, "failed to push alt_name"); 206 if (X509_add1_ext_i2d(cert, NID_subject_alt_name, 207 alt_name_stack, 0, 0) == 0) 208 errx(1, "failed to set subject alt name"); 209 sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free); 210 } 211 212 if (tls_check_hostname(cert, vt->hostname) != vt->want) { 213 fprintf(stderr, "FAIL: test %i failed with common name " 214 "'%s', alt name '%s' and hostname '%s'\n", test_no, 215 vt->common_name, vt->alt_name, vt->hostname); 216 return (1); 217 } 218 219 X509_free(cert); 220 221 return (0); 222} 223 224int 225main(int argc, char **argv) 226{ 227 int failed = 0; 228 size_t i; 229 230 for (i = 0; i < N_VERIFY_TESTS; i++) 231 failed += do_verify_test(i, &verify_tests[i]); 232 233 return (failed); 234} 235