- if (oidfile != NULL)
- {
- if (BIO_read_filename(in,oidfile) <= 0)
- {
- BIO_printf(bio_err,"problems opening %s\n",oidfile);
- ERR_print_errors(bio_err);
- goto end;
- }
- OBJ_create_objects(in);
- }
-
- if (infile == NULL)
- BIO_set_fp(in,stdin,BIO_NOCLOSE);
- else
- {
- if (BIO_read_filename(in,infile) <= 0)
- {
- perror(infile);
- goto end;
- }
- }
-
- if (derfile) {
- if(!(derout = BIO_new_file(derfile, "wb"))) {
- BIO_printf(bio_err,"problems opening %s\n",derfile);
- ERR_print_errors(bio_err);
- goto end;
- }
- }
-
- if ((buf=BUF_MEM_new()) == NULL) goto end;
- if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */
-
- 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;
-
- /* If any structs to parse go through in sequence */
-
- if (sk_num(osk))
- {
- tmpbuf=(unsigned char *)str;
- tmplen=num;
- for (i=0; i<sk_num(osk); i++)
- {
- ASN1_TYPE *atmp;
- j=atoi(sk_value(osk,i));
- if (j == 0)
- {
- BIO_printf(bio_err,"'%s' is an invalid number\n",sk_value(osk,i));
- continue;
- }
- tmpbuf+=j;
- tmplen-=j;
- atmp = at;
- at = d2i_ASN1_TYPE(NULL,&tmpbuf,tmplen);
- ASN1_TYPE_free(atmp);
- if(!at)
- {
- BIO_printf(bio_err,"Error parsing structure\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- /* hmm... this is a little evil but it works */
- tmpbuf=at->value.asn1_string->data;
- tmplen=at->value.asn1_string->length;
- }
- str=(char *)tmpbuf;
- num=tmplen;
- }
-
- if (length == 0) length=(unsigned int)num;
- if(derout) {
- if(BIO_write(derout, str + offset, length) != (int)length) {
- BIO_printf(bio_err, "Error writing output\n");
- ERR_print_errors(bio_err);
- goto end;
- }
- }
- if (!noout &&
- !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
- indent,dump))
- {
- ERR_print_errors(bio_err);
- goto end;
- }
- ret=0;
-end:
- BIO_free(derout);
- if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free_all(out);
- if (b64 != NULL) BIO_free(b64);
- if (ret != 0)
- ERR_print_errors(bio_err);
- if (buf != NULL) BUF_MEM_free(buf);
- if (at != NULL) ASN1_TYPE_free(at);
- if (osk != NULL) sk_free(osk);
- OBJ_cleanup();
- apps_shutdown();
- EXIT(ret);
- }
+ if (oidfile != NULL) {
+ if (BIO_read_filename(in, oidfile) <= 0) {
+ BIO_printf(bio_err, "problems opening %s\n", oidfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ OBJ_create_objects(in);
+ }
+
+ if (infile == NULL)
+ BIO_set_fp(in, stdin, BIO_NOCLOSE);
+ else {
+ if (BIO_read_filename(in, infile) <= 0) {
+ perror(infile);
+ goto end;
+ }
+ }
+
+ if (derfile) {
+ if (!(derout = BIO_new_file(derfile, "wb"))) {
+ BIO_printf(bio_err, "problems opening %s\n", derfile);
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (strictpem) {
+ if (PEM_read_bio(in, &name, &header, (unsigned char **)&str, &num) !=
+ 1) {
+ BIO_printf(bio_err, "Error reading PEM file\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ } else {
+
+ if ((buf = BUF_MEM_new()) == NULL)
+ goto end;
+ if (!BUF_MEM_grow(buf, BUFSIZ * 8))
+ goto end; /* Pre-allocate :-) */
+
+ if (genstr || genconf) {
+ num = do_generate(bio_err, genstr, genconf, buf);
+ if (num < 0) {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ else {
+
+ 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;
+
+ }
+
+ /* If any structs to parse go through in sequence */
+
+ if (sk_OPENSSL_STRING_num(osk)) {
+ tmpbuf = (unsigned char *)str;
+ tmplen = num;
+ for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
+ ASN1_TYPE *atmp;
+ int typ;
+ j = atoi(sk_OPENSSL_STRING_value(osk, i));
+ if (j == 0) {
+ BIO_printf(bio_err, "'%s' is an invalid number\n",
+ sk_OPENSSL_STRING_value(osk, i));
+ continue;
+ }
+ tmpbuf += j;
+ tmplen -= j;
+ atmp = at;
+ ctmpbuf = tmpbuf;
+ at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
+ ASN1_TYPE_free(atmp);
+ if (!at) {
+ BIO_printf(bio_err, "Error parsing structure\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ typ = ASN1_TYPE_get(at);
+ if ((typ == V_ASN1_OBJECT)
+ || (typ == V_ASN1_NULL)) {
+ BIO_printf(bio_err, "Can't parse %s type\n",
+ typ == V_ASN1_NULL ? "NULL" : "OBJECT");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ /* hmm... this is a little evil but it works */
+ tmpbuf = at->value.asn1_string->data;
+ tmplen = at->value.asn1_string->length;
+ }
+ str = (char *)tmpbuf;
+ num = tmplen;
+ }
+
+ 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");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ if (!noout &&
+ !ASN1_parse_dump(out, (unsigned char *)&(str[offset]), length,
+ indent, dump)) {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ ret = 0;
+ end:
+ BIO_free(derout);
+ BIO_free(in);
+ BIO_free_all(out);
+ BIO_free(b64);
+ if (ret != 0)
+ ERR_print_errors(bio_err);
+ if (buf != NULL)
+ BUF_MEM_free(buf);
+ if (name != NULL)
+ OPENSSL_free(name);
+ if (header != NULL)
+ OPENSSL_free(header);
+ if (strictpem && str != NULL)
+ OPENSSL_free(str);
+ if (at != NULL)
+ ASN1_TYPE_free(at);
+ if (osk != NULL)
+ sk_OPENSSL_STRING_free(osk);
+ OBJ_cleanup();
+ 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);
+ cnf = NULL;
+
+ 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;