X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fasn1pars.c;h=f1d8bc8b98b846936b47d0d2d0ef9bceaba5f90d;hp=f104ebc1f08ae27078c4a98b501dcfefd6b7e239;hb=e39c2548f522a9293376a19fdbe466514a882d16;hpb=667ac4ec6a9afb23a07dc7c695dbc5be0f2c83cd diff --git a/apps/asn1pars.c b/apps/asn1pars.c index f104ebc1f0..f1d8bc8b98 100644 --- a/apps/asn1pars.c +++ b/apps/asn1pars.c @@ -82,15 +82,19 @@ int MAIN(int, char **); +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf); + int MAIN(int argc, char **argv) { int i,badops=0,offset=0,ret=1,j; unsigned int length=0; long num,tmplen; BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL; - int informat,indent=0, noout = 0; + int informat,indent=0, noout = 0, dump = 0; char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL; + char *genstr=NULL, *genconf=NULL; unsigned char *tmpbuf; + const unsigned char *ctmpbuf; BUF_MEM *buf=NULL; STACK *osk=NULL; ASN1_TYPE *at=NULL; @@ -103,12 +107,15 @@ int MAIN(int argc, char **argv) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); + if (!load_config(bio_err, NULL)) + goto end; + prog=argv[0]; argc--; argv++; if ((osk=sk_new_null()) == NULL) { - BIO_printf(bio_err,"Malloc failure\n"); + BIO_printf(bio_err,"Memory allocation failure\n"); goto end; } while (argc >= 1) @@ -149,11 +156,31 @@ int MAIN(int argc, char **argv) length= atoi(*(++argv)); if (length == 0) goto bad; } + else if (strcmp(*argv,"-dump") == 0) + { + dump= -1; + } + else if (strcmp(*argv,"-dlimit") == 0) + { + if (--argc < 1) goto bad; + dump= atoi(*(++argv)); + if (dump <= 0) goto bad; + } else if (strcmp(*argv,"-strparse") == 0) { if (--argc < 1) goto bad; sk_push(osk,*(++argv)); } + else if (strcmp(*argv,"-genstr") == 0) + { + if (--argc < 1) goto bad; + genstr= *(++argv); + } + else if (strcmp(*argv,"-genconf") == 0) + { + if (--argc < 1) goto bad; + genconf= *(++argv); + } else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -171,16 +198,19 @@ bad: BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - one of DER TXT PEM\n"); BIO_printf(bio_err," -in arg input file\n"); - BIO_printf(bio_err," -out arg output file\n"); + BIO_printf(bio_err," -out arg output file (output format is always DER\n"); BIO_printf(bio_err," -noout arg don't produce any output\n"); BIO_printf(bio_err," -offset arg offset into file\n"); BIO_printf(bio_err," -length arg length of section in file\n"); BIO_printf(bio_err," -i indent entries\n"); + BIO_printf(bio_err," -dump dump unknown data in hex form\n"); + BIO_printf(bio_err," -dlimit arg dump the first arg bytes of unknown data in hex form\n"); BIO_printf(bio_err," -oid file file of extra oid definitions\n"); BIO_printf(bio_err," -strparse offset\n"); BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n"); BIO_printf(bio_err," ASN1 blob wrappings\n"); - BIO_printf(bio_err," -out filename output DER encoding to file\n"); + BIO_printf(bio_err," -genstr str string to generate ASN1 structure from\n"); + BIO_printf(bio_err," -genconf file file to generate ASN1 structure from\n"); goto end; } @@ -194,6 +224,12 @@ bad: goto end; } BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif if (oidfile != NULL) { @@ -228,25 +264,39 @@ bad: if ((buf=BUF_MEM_new()) == NULL) goto end; if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */ - if (informat == FORMAT_PEM) + if (genstr || genconf) { - BIO *tmp; - - if ((b64=BIO_new(BIO_f_base64())) == NULL) + num = do_generate(bio_err, genstr, genconf, buf); + if (num < 0) + { + ERR_print_errors(bio_err); goto end; - BIO_push(b64,in); - tmp=in; - in=b64; - b64=tmp; + } } - num=0; - for (;;) + else { - if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end; - i=BIO_read(in,&(buf->data[num]),BUFSIZ); - if (i <= 0) break; - num+=i; + + if (informat == FORMAT_PEM) + { + BIO *tmp; + + if ((b64=BIO_new(BIO_f_base64())) == NULL) + goto end; + BIO_push(b64,in); + tmp=in; + in=b64; + b64=tmp; + } + + num=0; + for (;;) + { + if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end; + i=BIO_read(in,&(buf->data[num]),BUFSIZ); + if (i <= 0) break; + num+=i; + } } str=buf->data; @@ -259,6 +309,7 @@ bad: for (i=0; ivalue.asn1_string->data; tmplen=at->value.asn1_string->length; @@ -284,7 +345,15 @@ bad: num=tmplen; } - if (length == 0) length=(unsigned int)num; + if (offset >= num) + { + BIO_printf(bio_err, "Error: offset too large\n"); + goto end; + } + + num -= offset; + + if ((length == 0) || ((long)length > num)) length=(unsigned int)num; if(derout) { if(BIO_write(derout, str + offset, length) != (int)length) { BIO_printf(bio_err, "Error writing output\n"); @@ -293,7 +362,8 @@ bad: } } if (!noout && - !ASN1_parse(out,(unsigned char *)&(str[offset]),length,indent)) + !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length, + indent,dump)) { ERR_print_errors(bio_err); goto end; @@ -302,7 +372,7 @@ bad: end: BIO_free(derout); if (in != NULL) BIO_free(in); - if (out != NULL) BIO_free(out); + if (out != NULL) BIO_free_all(out); if (b64 != NULL) BIO_free(b64); if (ret != 0) ERR_print_errors(bio_err); @@ -310,6 +380,65 @@ end: if (at != NULL) ASN1_TYPE_free(at); if (osk != NULL) sk_free(osk); OBJ_cleanup(); - EXIT(ret); + apps_shutdown(); + OPENSSL_EXIT(ret); } +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf) + { + CONF *cnf = NULL; + int len; + long errline; + unsigned char *p; + ASN1_TYPE *atyp = NULL; + + if (genconf) + { + cnf = NCONF_new(NULL); + if (!NCONF_load(cnf, genconf, &errline)) + goto conferr; + if (!genstr) + genstr = NCONF_get_string(cnf, "default", "asn1"); + if (!genstr) + { + BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf); + goto err; + } + } + + atyp = ASN1_generate_nconf(genstr, cnf); + NCONF_free(cnf); + + if (!atyp) + return -1; + + len = i2d_ASN1_TYPE(atyp, NULL); + + if (len <= 0) + goto err; + + if (!BUF_MEM_grow(buf,len)) + goto err; + + p=(unsigned char *)buf->data; + + i2d_ASN1_TYPE(atyp, &p); + + ASN1_TYPE_free(atyp); + return len; + + conferr: + + if (errline > 0) + BIO_printf(bio, "Error on line %ld of config file '%s'\n", + errline, genconf); + else + BIO_printf(bio, "Error loading config file '%s'\n", genconf); + + err: + NCONF_free(cnf); + ASN1_TYPE_free(atyp); + + return -1; + + }