1*b0100c00Stb /* $OpenBSD: asn1pars.c,v 1.17 2025/01/02 12:31:44 tb Exp $ */ 2dab3f910Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3dab3f910Sjsing * All rights reserved. 4dab3f910Sjsing * 5dab3f910Sjsing * This package is an SSL implementation written 6dab3f910Sjsing * by Eric Young (eay@cryptsoft.com). 7dab3f910Sjsing * The implementation was written so as to conform with Netscapes SSL. 8dab3f910Sjsing * 9dab3f910Sjsing * This library is free for commercial and non-commercial use as long as 10dab3f910Sjsing * the following conditions are aheared to. The following conditions 11dab3f910Sjsing * apply to all code found in this distribution, be it the RC4, RSA, 12dab3f910Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13dab3f910Sjsing * included with this distribution is covered by the same copyright terms 14dab3f910Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15dab3f910Sjsing * 16dab3f910Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in 17dab3f910Sjsing * the code are not to be removed. 18dab3f910Sjsing * If this package is used in a product, Eric Young should be given attribution 19dab3f910Sjsing * as the author of the parts of the library used. 20dab3f910Sjsing * This can be in the form of a textual message at program startup or 21dab3f910Sjsing * in documentation (online or textual) provided with the package. 22dab3f910Sjsing * 23dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 24dab3f910Sjsing * modification, are permitted provided that the following conditions 25dab3f910Sjsing * are met: 26dab3f910Sjsing * 1. Redistributions of source code must retain the copyright 27dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 28dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 29dab3f910Sjsing * notice, this list of conditions and the following disclaimer in the 30dab3f910Sjsing * documentation and/or other materials provided with the distribution. 31dab3f910Sjsing * 3. All advertising materials mentioning features or use of this software 32dab3f910Sjsing * must display the following acknowledgement: 33dab3f910Sjsing * "This product includes cryptographic software written by 34dab3f910Sjsing * Eric Young (eay@cryptsoft.com)" 35dab3f910Sjsing * The word 'cryptographic' can be left out if the rouines from the library 36dab3f910Sjsing * being used are not cryptographic related :-). 37dab3f910Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from 38dab3f910Sjsing * the apps directory (application code) you must include an acknowledgement: 39dab3f910Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40dab3f910Sjsing * 41dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42dab3f910Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44dab3f910Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45dab3f910Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46dab3f910Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47dab3f910Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49dab3f910Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50dab3f910Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51dab3f910Sjsing * SUCH DAMAGE. 52dab3f910Sjsing * 53dab3f910Sjsing * The licence and distribution terms for any publically available version or 54dab3f910Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 55dab3f910Sjsing * copied and put under another distribution licence 56dab3f910Sjsing * [including the GNU Public Licence.] 57dab3f910Sjsing */ 58dab3f910Sjsing 59dab3f910Sjsing /* A nice addition from Dr Stephen Henson <steve@openssl.org> to 60dab3f910Sjsing * add the -strparse option which parses nested binary structures 61dab3f910Sjsing */ 62dab3f910Sjsing 63dab3f910Sjsing #include <stdio.h> 64dab3f910Sjsing #include <stdlib.h> 65dab3f910Sjsing #include <limits.h> 66dab3f910Sjsing #include <string.h> 67dab3f910Sjsing 68dab3f910Sjsing #include "apps.h" 69dab3f910Sjsing 70dab3f910Sjsing #include <openssl/err.h> 71dab3f910Sjsing #include <openssl/evp.h> 72dab3f910Sjsing #include <openssl/pem.h> 73dab3f910Sjsing #include <openssl/x509.h> 74dab3f910Sjsing 751c048bb9Sdoug static struct { 761c048bb9Sdoug char *derfile; 771c048bb9Sdoug int dump; 781c048bb9Sdoug char *genconf; 791c048bb9Sdoug char *genstr; 801c048bb9Sdoug int indent; 811c048bb9Sdoug char *infile; 821c048bb9Sdoug int informat; 831c048bb9Sdoug unsigned int length; 841c048bb9Sdoug int noout; 851c048bb9Sdoug int offset; 861c048bb9Sdoug char *oidfile; 871c048bb9Sdoug STACK_OF(OPENSSL_STRING) *osk; 88e7718adaStb } cfg; 89dab3f910Sjsing 901c048bb9Sdoug static int 911c048bb9Sdoug asn1pars_opt_dlimit(char *arg) 921c048bb9Sdoug { 931c048bb9Sdoug const char *errstr; 941c048bb9Sdoug 95e7718adaStb cfg.dump = strtonum(arg, 1, INT_MAX, &errstr); 961c048bb9Sdoug if (errstr) { 971c048bb9Sdoug fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n", 981c048bb9Sdoug errstr); 991c048bb9Sdoug return (-1); 1001c048bb9Sdoug } 1011c048bb9Sdoug return (0); 1021c048bb9Sdoug } 1031c048bb9Sdoug 1041c048bb9Sdoug static int 1051c048bb9Sdoug asn1pars_opt_length(char *arg) 1061c048bb9Sdoug { 1071c048bb9Sdoug const char *errstr; 1081c048bb9Sdoug 109e7718adaStb cfg.length = strtonum(arg, 1, UINT_MAX, &errstr); 1101c048bb9Sdoug if (errstr) { 1111c048bb9Sdoug fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n", 1121c048bb9Sdoug errstr); 1131c048bb9Sdoug return (-1); 1141c048bb9Sdoug } 1151c048bb9Sdoug return (0); 1161c048bb9Sdoug } 1171c048bb9Sdoug 1181c048bb9Sdoug static int 1191c048bb9Sdoug asn1pars_opt_strparse(char *arg) 1201c048bb9Sdoug { 121e7718adaStb if (sk_OPENSSL_STRING_push(cfg.osk, arg) == 0) { 1221c048bb9Sdoug fprintf(stderr, "-strparse cannot add argument\n"); 1231c048bb9Sdoug return (-1); 1241c048bb9Sdoug } 1251c048bb9Sdoug return (0); 1261c048bb9Sdoug } 1271c048bb9Sdoug 128ea149709Sguenther static const struct option asn1pars_options[] = { 1291c048bb9Sdoug { 1301c048bb9Sdoug .name = "dump", 1311c048bb9Sdoug .desc = "Dump unknown data in hex form", 1321c048bb9Sdoug .type = OPTION_VALUE, 1331c048bb9Sdoug .value = -1, 134e7718adaStb .opt.value = &cfg.dump, 1351c048bb9Sdoug }, 1361c048bb9Sdoug { 1371c048bb9Sdoug .name = "dlimit", 1381c048bb9Sdoug .argname = "num", 1391c048bb9Sdoug .desc = "Dump the first num bytes of unknown data in hex form", 1401c048bb9Sdoug .type = OPTION_ARG_FUNC, 1411c048bb9Sdoug .opt.argfunc = asn1pars_opt_dlimit, 1421c048bb9Sdoug }, 1431c048bb9Sdoug { 1441c048bb9Sdoug .name = "genconf", 1451c048bb9Sdoug .argname = "file", 1461c048bb9Sdoug .desc = "File to generate ASN.1 structure from", 1471c048bb9Sdoug .type = OPTION_ARG, 148e7718adaStb .opt.arg = &cfg.genconf, 1491c048bb9Sdoug }, 1501c048bb9Sdoug { 1511c048bb9Sdoug .name = "genstr", 1521c048bb9Sdoug .argname = "string", 1531c048bb9Sdoug .desc = "String to generate ASN.1 structure from", 1541c048bb9Sdoug .type = OPTION_ARG, 155e7718adaStb .opt.arg = &cfg.genstr, 1561c048bb9Sdoug }, 1571c048bb9Sdoug { 1581c048bb9Sdoug .name = "i", 1591c048bb9Sdoug .desc = "Indent output according to depth of structures", 1601c048bb9Sdoug .type = OPTION_FLAG, 161e7718adaStb .opt.flag = &cfg.indent, 1621c048bb9Sdoug }, 1631c048bb9Sdoug { 1641c048bb9Sdoug .name = "in", 1651c048bb9Sdoug .argname = "file", 1661c048bb9Sdoug .desc = "The input file (default stdin)", 1671c048bb9Sdoug .type = OPTION_ARG, 168e7718adaStb .opt.arg = &cfg.infile, 1691c048bb9Sdoug }, 1701c048bb9Sdoug { 1711c048bb9Sdoug .name = "inform", 1721c048bb9Sdoug .argname = "fmt", 1731c048bb9Sdoug .desc = "Input format (DER, TXT or PEM (default))", 1741c048bb9Sdoug .type = OPTION_ARG_FORMAT, 175e7718adaStb .opt.value = &cfg.informat, 1761c048bb9Sdoug }, 1771c048bb9Sdoug { 1781c048bb9Sdoug .name = "length", 1791c048bb9Sdoug .argname = "num", 1801c048bb9Sdoug .desc = "Number of bytes to parse (default until EOF)", 1811c048bb9Sdoug .type = OPTION_ARG_FUNC, 1821c048bb9Sdoug .opt.argfunc = asn1pars_opt_length, 1831c048bb9Sdoug }, 1841c048bb9Sdoug { 1851c048bb9Sdoug .name = "noout", 1861c048bb9Sdoug .desc = "Do not produce any output", 1871c048bb9Sdoug .type = OPTION_FLAG, 188e7718adaStb .opt.flag = &cfg.noout, 1891c048bb9Sdoug }, 1901c048bb9Sdoug { 1911c048bb9Sdoug .name = "offset", 1921c048bb9Sdoug .argname = "num", 1931c048bb9Sdoug .desc = "Offset to begin parsing", 1941c048bb9Sdoug .type = OPTION_ARG_INT, 195e7718adaStb .opt.value = &cfg.offset, 1961c048bb9Sdoug }, 1971c048bb9Sdoug { 1981c048bb9Sdoug .name = "oid", 1991c048bb9Sdoug .argname = "file", 2001c048bb9Sdoug .desc = "File containing additional object identifiers (OIDs)", 2011c048bb9Sdoug .type = OPTION_ARG, 202e7718adaStb .opt.arg = &cfg.oidfile, 2031c048bb9Sdoug }, 2041c048bb9Sdoug { 2051c048bb9Sdoug .name = "out", 2061c048bb9Sdoug .argname = "file", 2071c048bb9Sdoug .desc = "Output file in DER format", 2081c048bb9Sdoug .type = OPTION_ARG, 209e7718adaStb .opt.arg = &cfg.derfile, 2101c048bb9Sdoug }, 2111c048bb9Sdoug { 2121c048bb9Sdoug .name = "strparse", 2131c048bb9Sdoug .argname = "offset", 2141c048bb9Sdoug .desc = "Parse the content octets of ASN.1 object starting at" 2151c048bb9Sdoug " offset", 2161c048bb9Sdoug .type = OPTION_ARG_FUNC, 2171c048bb9Sdoug .opt.argfunc = asn1pars_opt_strparse, 2181c048bb9Sdoug }, 2191c048bb9Sdoug { NULL }, 2201c048bb9Sdoug }; 2211c048bb9Sdoug 2221c048bb9Sdoug static void 223440d1414Stb asn1pars_usage(void) 2241c048bb9Sdoug { 2251c048bb9Sdoug fprintf(stderr, 2261c048bb9Sdoug "usage: asn1parse [-i] [-dlimit num] [-dump] [-genconf file] " 2271c048bb9Sdoug "[-genstr string]\n" 2281c048bb9Sdoug " [-in file] [-inform fmt] [-length num] [-noout] [-offset num] " 2291c048bb9Sdoug "[-oid file]\n" 2301c048bb9Sdoug " [-out file] [-strparse offset]\n\n"); 2311c048bb9Sdoug options_usage(asn1pars_options); 2321c048bb9Sdoug } 233dab3f910Sjsing 234dab3f910Sjsing static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf); 235dab3f910Sjsing 236dab3f910Sjsing int 237dab3f910Sjsing asn1parse_main(int argc, char **argv) 238dab3f910Sjsing { 2391c048bb9Sdoug int i, j, ret = 1; 240dab3f910Sjsing long num, tmplen; 241dab3f910Sjsing BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL; 2421c048bb9Sdoug char *str = NULL; 243dab3f910Sjsing const char *errstr = NULL; 244dab3f910Sjsing unsigned char *tmpbuf; 245dab3f910Sjsing const unsigned char *ctmpbuf; 246dab3f910Sjsing BUF_MEM *buf = NULL; 247dab3f910Sjsing ASN1_TYPE *at = NULL; 248dab3f910Sjsing 24951811eadSderaadt if (pledge("stdio cpath wpath rpath", NULL) == -1) { 2509bc487adSdoug perror("pledge"); 251e370f0eeSdoug exit(1); 252e370f0eeSdoug } 2539bc487adSdoug 254e7718adaStb memset(&cfg, 0, sizeof(cfg)); 255dab3f910Sjsing 256e7718adaStb cfg.informat = FORMAT_PEM; 257e7718adaStb if ((cfg.osk = sk_OPENSSL_STRING_new_null()) == NULL) { 258dab3f910Sjsing BIO_printf(bio_err, "Memory allocation failure\n"); 259dab3f910Sjsing goto end; 260dab3f910Sjsing } 261dab3f910Sjsing 2621c048bb9Sdoug if (options_parse(argc, argv, asn1pars_options, NULL, NULL) != 0) { 2631c048bb9Sdoug asn1pars_usage(); 2641c048bb9Sdoug return (1); 265dab3f910Sjsing } 266dab3f910Sjsing 267dab3f910Sjsing in = BIO_new(BIO_s_file()); 268dab3f910Sjsing out = BIO_new(BIO_s_file()); 26957afdfddStb if (in == NULL || out == NULL) { 270dab3f910Sjsing ERR_print_errors(bio_err); 271dab3f910Sjsing goto end; 272dab3f910Sjsing } 273dab3f910Sjsing BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); 274dab3f910Sjsing 275e7718adaStb if (cfg.oidfile != NULL) { 276e7718adaStb if (BIO_read_filename(in, cfg.oidfile) <= 0) { 2771c048bb9Sdoug BIO_printf(bio_err, "problems opening %s\n", 278e7718adaStb cfg.oidfile); 279dab3f910Sjsing ERR_print_errors(bio_err); 280dab3f910Sjsing goto end; 281dab3f910Sjsing } 282dab3f910Sjsing OBJ_create_objects(in); 283dab3f910Sjsing } 284e7718adaStb if (cfg.infile == NULL) 285dab3f910Sjsing BIO_set_fp(in, stdin, BIO_NOCLOSE); 286dab3f910Sjsing else { 287e7718adaStb if (BIO_read_filename(in, cfg.infile) <= 0) { 288e7718adaStb perror(cfg.infile); 289dab3f910Sjsing goto end; 290dab3f910Sjsing } 291dab3f910Sjsing } 292dab3f910Sjsing 29357afdfddStb if (cfg.derfile != NULL) { 29457afdfddStb if ((derout = BIO_new_file(cfg.derfile, "wb")) == NULL) { 2951c048bb9Sdoug BIO_printf(bio_err, "problems opening %s\n", 296e7718adaStb cfg.derfile); 297dab3f910Sjsing ERR_print_errors(bio_err); 298dab3f910Sjsing goto end; 299dab3f910Sjsing } 300dab3f910Sjsing } 301dab3f910Sjsing if ((buf = BUF_MEM_new()) == NULL) 302dab3f910Sjsing goto end; 303dab3f910Sjsing if (!BUF_MEM_grow(buf, BUFSIZ * 8)) 30457afdfddStb goto end; 305dab3f910Sjsing 30657afdfddStb if (cfg.genstr != NULL || cfg.genconf) { 30757afdfddStb num = do_generate(bio_err, cfg.genstr, cfg.genconf, buf); 308dab3f910Sjsing if (num < 0) { 309dab3f910Sjsing ERR_print_errors(bio_err); 310dab3f910Sjsing goto end; 311dab3f910Sjsing } 312dab3f910Sjsing } else { 313e7718adaStb if (cfg.informat == FORMAT_PEM) { 314dab3f910Sjsing BIO *tmp; 315dab3f910Sjsing 316dab3f910Sjsing if ((b64 = BIO_new(BIO_f_base64())) == NULL) 317dab3f910Sjsing goto end; 318dab3f910Sjsing BIO_push(b64, in); 319dab3f910Sjsing tmp = in; 320dab3f910Sjsing in = b64; 321dab3f910Sjsing b64 = tmp; 322dab3f910Sjsing } 323dab3f910Sjsing num = 0; 324dab3f910Sjsing for (;;) { 325dab3f910Sjsing if (!BUF_MEM_grow(buf, (int) num + BUFSIZ)) 326dab3f910Sjsing goto end; 327dab3f910Sjsing i = BIO_read(in, &(buf->data[num]), BUFSIZ); 328dab3f910Sjsing if (i <= 0) 329dab3f910Sjsing break; 330dab3f910Sjsing num += i; 331dab3f910Sjsing } 332dab3f910Sjsing } 333dab3f910Sjsing str = buf->data; 334dab3f910Sjsing 335dab3f910Sjsing /* If any structs to parse go through in sequence */ 336dab3f910Sjsing 33757afdfddStb if (sk_OPENSSL_STRING_num(cfg.osk) > 0) { 338dab3f910Sjsing tmpbuf = (unsigned char *) str; 339dab3f910Sjsing tmplen = num; 34057afdfddStb for (i = 0; i < sk_OPENSSL_STRING_num(cfg.osk); i++) { 341dab3f910Sjsing ASN1_TYPE *atmp; 342dab3f910Sjsing int typ; 34357afdfddStb j = strtonum(sk_OPENSSL_STRING_value(cfg.osk, i), 344dab3f910Sjsing 1, INT_MAX, &errstr); 345dab3f910Sjsing if (errstr) { 346dab3f910Sjsing BIO_printf(bio_err, 347dab3f910Sjsing "'%s' is an invalid number: %s\n", 34857afdfddStb sk_OPENSSL_STRING_value(cfg.osk, i), errstr); 349dab3f910Sjsing continue; 350dab3f910Sjsing } 351dab3f910Sjsing tmpbuf += j; 352dab3f910Sjsing tmplen -= j; 353dab3f910Sjsing atmp = at; 354dab3f910Sjsing ctmpbuf = tmpbuf; 355dab3f910Sjsing at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen); 356dab3f910Sjsing ASN1_TYPE_free(atmp); 357dab3f910Sjsing if (!at) { 358dab3f910Sjsing BIO_printf(bio_err, "Error parsing structure\n"); 359dab3f910Sjsing ERR_print_errors(bio_err); 360dab3f910Sjsing goto end; 361dab3f910Sjsing } 362dab3f910Sjsing typ = ASN1_TYPE_get(at); 363580d1070Stb if (typ == V_ASN1_BOOLEAN || typ == V_ASN1_NULL || 364580d1070Stb typ == V_ASN1_OBJECT) { 365dab3f910Sjsing BIO_printf(bio_err, "Can't parse %s type\n", 366580d1070Stb ASN1_tag2str(typ)); 367dab3f910Sjsing ERR_print_errors(bio_err); 368dab3f910Sjsing goto end; 369dab3f910Sjsing } 370dab3f910Sjsing /* hmm... this is a little evil but it works */ 371dab3f910Sjsing tmpbuf = at->value.asn1_string->data; 372dab3f910Sjsing tmplen = at->value.asn1_string->length; 373dab3f910Sjsing } 374dab3f910Sjsing str = (char *) tmpbuf; 375dab3f910Sjsing num = tmplen; 376dab3f910Sjsing } 377e7718adaStb if (cfg.offset >= num) { 378dab3f910Sjsing BIO_printf(bio_err, "Error: offset too large\n"); 379dab3f910Sjsing goto end; 380dab3f910Sjsing } 381e7718adaStb num -= cfg.offset; 382dab3f910Sjsing 38357afdfddStb if (cfg.length == 0 || (long)cfg.length > num) 384e7718adaStb cfg.length = (unsigned int) num; 38557afdfddStb if (derout != NULL) { 386e7718adaStb if (BIO_write(derout, str + cfg.offset, 387e7718adaStb cfg.length) != (int)cfg.length) { 388dab3f910Sjsing BIO_printf(bio_err, "Error writing output\n"); 389dab3f910Sjsing ERR_print_errors(bio_err); 390dab3f910Sjsing goto end; 391dab3f910Sjsing } 392dab3f910Sjsing } 39357afdfddStb if (!cfg.noout && !ASN1_parse_dump(out, 39457afdfddStb (unsigned char *)&str[cfg.offset], cfg.length, cfg.indent, cfg.dump)) { 395dab3f910Sjsing ERR_print_errors(bio_err); 396dab3f910Sjsing goto end; 397dab3f910Sjsing } 398dab3f910Sjsing ret = 0; 399dab3f910Sjsing end: 400dab3f910Sjsing BIO_free(derout); 401dab3f910Sjsing BIO_free(in); 402dab3f910Sjsing BIO_free_all(out); 403dab3f910Sjsing BIO_free(b64); 404dab3f910Sjsing if (ret != 0) 405dab3f910Sjsing ERR_print_errors(bio_err); 406dab3f910Sjsing BUF_MEM_free(buf); 407dab3f910Sjsing ASN1_TYPE_free(at); 408e7718adaStb sk_OPENSSL_STRING_free(cfg.osk); 409dab3f910Sjsing OBJ_cleanup(); 410dab3f910Sjsing 411dab3f910Sjsing return (ret); 412dab3f910Sjsing } 413dab3f910Sjsing 414dab3f910Sjsing static int 415dab3f910Sjsing do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf) 416dab3f910Sjsing { 417dab3f910Sjsing CONF *cnf = NULL; 418dab3f910Sjsing int len; 419dab3f910Sjsing long errline; 420dab3f910Sjsing unsigned char *p; 421dab3f910Sjsing ASN1_TYPE *atyp = NULL; 422dab3f910Sjsing 423dab3f910Sjsing if (genconf) { 424dab3f910Sjsing cnf = NCONF_new(NULL); 425dab3f910Sjsing if (!NCONF_load(cnf, genconf, &errline)) 426dab3f910Sjsing goto conferr; 427dab3f910Sjsing if (!genstr) 428dab3f910Sjsing genstr = NCONF_get_string(cnf, "default", "asn1"); 429dab3f910Sjsing if (!genstr) { 430dab3f910Sjsing BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf); 431dab3f910Sjsing goto err; 432dab3f910Sjsing } 433dab3f910Sjsing } 434dab3f910Sjsing atyp = ASN1_generate_nconf(genstr, cnf); 435dab3f910Sjsing NCONF_free(cnf); 436dab3f910Sjsing cnf = NULL; 437dab3f910Sjsing 438dab3f910Sjsing if (!atyp) 439dab3f910Sjsing return -1; 440dab3f910Sjsing 441dab3f910Sjsing len = i2d_ASN1_TYPE(atyp, NULL); 442dab3f910Sjsing if (len <= 0) 443dab3f910Sjsing goto err; 444dab3f910Sjsing 445dab3f910Sjsing if (!BUF_MEM_grow(buf, len)) 446dab3f910Sjsing goto err; 447dab3f910Sjsing 448dab3f910Sjsing p = (unsigned char *) buf->data; 449dab3f910Sjsing 450dab3f910Sjsing i2d_ASN1_TYPE(atyp, &p); 451dab3f910Sjsing 452dab3f910Sjsing ASN1_TYPE_free(atyp); 453dab3f910Sjsing return len; 454dab3f910Sjsing 455dab3f910Sjsing conferr: 456dab3f910Sjsing 457dab3f910Sjsing if (errline > 0) 458dab3f910Sjsing BIO_printf(bio, "Error on line %ld of config file '%s'\n", 459dab3f910Sjsing errline, genconf); 460dab3f910Sjsing else 461dab3f910Sjsing BIO_printf(bio, "Error loading config file '%s'\n", genconf); 462dab3f910Sjsing 463dab3f910Sjsing err: 464dab3f910Sjsing NCONF_free(cnf); 465dab3f910Sjsing ASN1_TYPE_free(atyp); 466dab3f910Sjsing 467dab3f910Sjsing return -1; 468dab3f910Sjsing 469dab3f910Sjsing } 470