1 /* $OpenBSD: x509req_ext.c,v 1.1 2021/11/03 13:08:57 schwarze Exp $ */ 2 /* 3 * Copyright (c) 2020, 2021 Ingo Schwarze <schwarze@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 <errno.h> 19 #include <stdio.h> 20 #include <string.h> 21 22 #include <openssl/asn1.h> 23 #include <openssl/err.h> 24 #include <openssl/x509.h> 25 26 void fail_head(const char *); 27 void fail_tail(void); 28 void fail_str(const char *, const char *); 29 void fail_int(const char *, int); 30 void fail_ptr(const char *, const void *); 31 32 static const char *testname; 33 static int errcount; 34 35 void 36 fail_head(const char *stepname) 37 { 38 fprintf(stderr, "failure#%d testname=%s stepname=%s ", 39 ++errcount, testname, stepname); 40 } 41 42 void 43 fail_tail(void) 44 { 45 unsigned long errnum; 46 47 if ((errnum = ERR_get_error())) 48 fprintf(stderr, "OpenSSL says: %s\n", 49 ERR_error_string(errnum, NULL)); 50 if (errno) 51 fprintf(stderr, "libc says: %s\n", strerror(errno)); 52 } 53 54 void 55 fail_str(const char *stepname, const char *result) 56 { 57 fail_head(stepname); 58 fprintf(stderr, "wrong result=%s\n", result); 59 fail_tail(); 60 } 61 62 void 63 fail_int(const char *stepname, int result) 64 { 65 fail_head(stepname); 66 fprintf(stderr, "wrong result=%d\n", result); 67 fail_tail(); 68 } 69 70 void 71 fail_ptr(const char *stepname, const void *result) 72 { 73 fail_head(stepname); 74 fprintf(stderr, "wrong result=%p\n", result); 75 fail_tail(); 76 } 77 78 int 79 main(void) 80 { 81 X509_REQ *req; 82 X509_EXTENSIONS *exts; 83 X509_ATTRIBUTE *attr; 84 ASN1_TYPE *aval; 85 int irc; 86 87 testname = "exts=NULL"; 88 if ((req = X509_REQ_new()) == NULL) { 89 fail_str("X509_REQ_new", "NULL"); 90 return 1; 91 } 92 if ((irc = X509_REQ_add_extensions(req, NULL)) != 0) 93 fail_int("X509_REQ_add_extensions", irc); 94 if ((irc = X509_REQ_get_attr_count(req)) != 0) 95 fail_int("X509_REQ_get_attr_count", irc); 96 if ((attr = X509_REQ_get_attr(req, 0)) != NULL) 97 fail_ptr("X509_REQ_get_attr", attr); 98 X509_REQ_free(req); 99 100 testname = "nid=-1"; 101 if ((req = X509_REQ_new()) == NULL) { 102 fail_str("X509_REQ_new", "NULL"); 103 return 1; 104 } 105 if ((exts = sk_X509_EXTENSION_new_null()) == NULL) { 106 fail_str("sk_X509_EXTENSION_new_null", "NULL"); 107 return 1; 108 } 109 if ((irc = X509_REQ_add_extensions_nid(req, exts, -1)) != 0) 110 fail_int("X509_REQ_add_extensions", irc); 111 if ((irc = X509_REQ_get_attr_count(req)) != 0) 112 fail_int("X509_REQ_get_attr_count", irc); 113 if ((attr = X509_REQ_get_attr(req, 0)) != NULL) 114 fail_ptr("X509_REQ_get_attr", attr); 115 X509_REQ_free(req); 116 117 testname = "valid"; 118 if ((req = X509_REQ_new()) == NULL) { 119 fail_str("X509_REQ_new", "NULL"); 120 return 1; 121 } 122 if ((irc = X509_REQ_add_extensions(req, exts)) != 1) 123 fail_int("X509_REQ_add_extensions", irc); 124 sk_X509_EXTENSION_free(exts); 125 if ((irc = X509_REQ_get_attr_count(req)) != 1) 126 fail_int("X509_REQ_get_attr_count", irc); 127 if ((attr = X509_REQ_get_attr(req, 0)) == NULL) { 128 fail_str("X509_REQ_get_attr", "NULL"); 129 goto end_valid; 130 } 131 if ((irc = X509_ATTRIBUTE_count(attr)) != 1) 132 fail_int("X509_ATTRIBUTE_count", irc); 133 if ((aval = X509_ATTRIBUTE_get0_type(attr, 0)) == NULL) { 134 fail_str("X509_ATTRIBUTE_get0_type", "NULL"); 135 goto end_valid; 136 } 137 if ((irc = ASN1_TYPE_get(aval)) != V_ASN1_SEQUENCE) 138 fail_int("ASN1_TYPE_get", irc); 139 exts = ASN1_item_unpack(aval->value.sequence, &X509_EXTENSIONS_it); 140 if (exts == NULL) { 141 fail_str("ASN1_item_unpack", "NULL"); 142 goto end_valid; 143 } 144 if ((irc = sk_X509_EXTENSION_num(exts)) != 0) 145 fail_int("sk_X509_EXTENSION_num", irc); 146 sk_X509_EXTENSION_free(exts); 147 148 end_valid: 149 testname = "getext"; 150 if ((exts = X509_REQ_get_extensions(req)) == NULL) { 151 fail_str("X509_REQ_get_extensions", "NULL"); 152 goto end_getext; 153 } 154 if ((irc = sk_X509_EXTENSION_num(exts)) != 0) 155 fail_int("sk_X509_EXTENSION_num", irc); 156 sk_X509_EXTENSION_free(exts); 157 158 end_getext: 159 X509_REQ_free(req); 160 return errcount != 0; 161 } 162