1286425Sdim/*	$NetBSD: asn1_gen.c,v 1.2 2017/01/28 21:31:45 christos Exp $	*/
2286425Sdim
3286425Sdim/*
4286425Sdim * Copyright (c) 2005 Kungliga Tekniska H��gskolan
5286425Sdim * (Royal Institute of Technology, Stockholm, Sweden).
6286425Sdim * All rights reserved.
7286425Sdim *
8286425Sdim * Redistribution and use in source and binary forms, with or without
9286425Sdim * modification, are permitted provided that the following conditions
10286425Sdim * are met:
11286425Sdim *
12286425Sdim * 1. Redistributions of source code must retain the above copyright
13286425Sdim *    notice, this list of conditions and the following disclaimer.
14286425Sdim *
15286425Sdim * 2. Redistributions in binary form must reproduce the above copyright
16286425Sdim *    notice, this list of conditions and the following disclaimer in the
17286425Sdim *    documentation and/or other materials provided with the distribution.
18286425Sdim *
19286425Sdim * 3. Neither the name of the Institute nor the names of its contributors
20286425Sdim *    may be used to endorse or promote products derived from this software
21286425Sdim *    without specific prior written permission.
22286425Sdim *
23286425Sdim * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24286425Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25286425Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26286425Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27286425Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28286425Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29286425Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30286425Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31286425Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32286425Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33286425Sdim * SUCH DAMAGE.
34286425Sdim */
35286425Sdim
36286425Sdim#include "der_locl.h"
37286425Sdim#include <krb5/com_err.h>
38286425Sdim#include <sys/types.h>
39296417Sdim#include <sys/stat.h>
40286425Sdim#include <ctype.h>
41286425Sdim#include <krb5/getarg.h>
42286425Sdim#include <krb5/hex.h>
43286425Sdim#include <err.h>
44286425Sdim
45286425Sdim__RCSID("$NetBSD: asn1_gen.c,v 1.2 2017/01/28 21:31:45 christos Exp $");
46286425Sdim
47286425Sdimstatic int
48286425Sdimdoit(const char *fn)
49286425Sdim{
50286425Sdim    char buf[2048];
51286425Sdim    char *fnout = NULL;
52286425Sdim    const char *bname;
53286425Sdim    unsigned long line = 0;
54286425Sdim    FILE *f, *fout;
55286425Sdim    size_t offset = 0;
56286425Sdim
57286425Sdim    f = fopen(fn, "r");
58286425Sdim    if (f == NULL)
59286425Sdim	err(1, "fopen");
60286425Sdim
61286425Sdim    bname = strrchr(fn, '/');
62286425Sdim    if (bname)
63286425Sdim	bname++;
64286425Sdim    else
65286425Sdim	bname = fn;
66286425Sdim
67286425Sdim    if (asprintf(&fnout, "%s.out", bname) < 0 || fnout == NULL)
68286425Sdim	errx(1, "malloc");
69286425Sdim
70286425Sdim    fout = fopen(fnout, "w");
71286425Sdim    if (fout == NULL)
72286425Sdim	err(1, "fopen: output file");
73286425Sdim
74286425Sdim    while (fgets(buf, sizeof(buf), f) != NULL) {
75286425Sdim	char *ptr, *class, *type, *tag, *length, *data, *foo;
76286425Sdim	int ret, l, c, ty, ta;
77286425Sdim	unsigned char p[6], *pdata;
78286425Sdim	size_t sz;
79286425Sdim
80286425Sdim	line++;
81286425Sdim
82286425Sdim	buf[strcspn(buf, "\r\n")] = '\0';
83286425Sdim	if (buf[0] == '#' || buf[0] == '\0')
84286425Sdim	    continue;
85286425Sdim
86286425Sdim	ptr = buf;
87286425Sdim	while (isspace((unsigned char)*ptr))
88286425Sdim	       ptr++;
89286425Sdim
90286425Sdim	class = strtok_r(ptr, " \t\n", &foo);
91286425Sdim	if (class == NULL) errx(1, "class missing on line %lu", line);
92286425Sdim	type = strtok_r(NULL, " \t\n", &foo);
93286425Sdim	if (type == NULL) errx(1, "type missing on line %lu", line);
94286425Sdim	tag = strtok_r(NULL, " \t\n", &foo);
95286425Sdim	if (tag == NULL) errx(1, "tag missing on line %lu", line);
96286425Sdim	length = strtok_r(NULL, " \t\n", &foo);
97286425Sdim	if (length == NULL) errx(1, "length missing on line %lu", line);
98286425Sdim	data = strtok_r(NULL, " \t\n", &foo);
99286425Sdim
100286425Sdim	c = der_get_class_num(class);
101286425Sdim	if (c == -1) errx(1, "no valid class on line %lu", line);
102286425Sdim	ty = der_get_type_num(type);
103286425Sdim	if (ty == -1) errx(1, "no valid type on line %lu", line);
104286425Sdim	ta = der_get_tag_num(tag);
105286425Sdim	if (ta == -1)
106286425Sdim	    ta = atoi(tag);
107286425Sdim
108286425Sdim	l = atoi(length);
109286425Sdim
110286425Sdim	printf("line: %3lu offset: %3lu class: %d type: %d "
111286425Sdim	       "tag: %3d length: %3d %s\n",
112286425Sdim	       line, (unsigned long)offset, c, ty, ta, l,
113286425Sdim	       data ? "<have data>" : "<no data>");
114286425Sdim
115286425Sdim	ret = der_put_length_and_tag(p + sizeof(p) - 1, sizeof(p),
116286425Sdim				     l,
117286425Sdim				     c,
118286425Sdim				     ty,
119286425Sdim				     ta,
120286425Sdim				     &sz);
121286425Sdim	if (ret)
122286425Sdim	    errx(1, "der_put_length_and_tag: %d", ret);
123286425Sdim
124286425Sdim	if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
125286425Sdim	    err(1, "fwrite length/tag failed");
126286425Sdim	offset += sz;
127286425Sdim
128286425Sdim	if (data) {
129286425Sdim	    size_t datalen;
130286425Sdim
131286425Sdim	    datalen = strlen(data) / 2;
132286425Sdim	    pdata = emalloc(sz);
133286425Sdim
134286425Sdim	    if (hex_decode(data, pdata, datalen) != datalen)
135286425Sdim		errx(1, "failed to decode data");
136286425Sdim
137286425Sdim	    if (fwrite(pdata, datalen, 1, fout) != 1)
138286425Sdim		err(1, "fwrite data failed");
139286425Sdim	    offset += datalen;
140286425Sdim
141286425Sdim	    free(pdata);
142286425Sdim	}
143286425Sdim    }
144286425Sdim    printf("line: eof offset: %lu\n", (unsigned long)offset);
145286425Sdim
146286425Sdim    fclose(fout);
147286425Sdim    fclose(f);
148286425Sdim    return 0;
149286425Sdim}
150286425Sdim
151286425Sdim
152286425Sdimstatic int version_flag;
153286425Sdimstatic int help_flag;
154286425Sdimstruct getargs args[] = {
155286425Sdim    { "version", 0, arg_flag, &version_flag, NULL, NULL },
156286425Sdim    { "help", 0, arg_flag, &help_flag, NULL, NULL }
157286425Sdim};
158286425Sdimint num_args = sizeof(args) / sizeof(args[0]);
159286425Sdim
160286425Sdimstatic void
161286425Sdimusage(int code)
162286425Sdim{
163286425Sdim    arg_printusage(args, num_args, NULL, "parse-file");
164286425Sdim    exit(code);
165286425Sdim}
166286425Sdim
167286425Sdimint
168286425Sdimmain(int argc, char **argv)
169286425Sdim{
170286425Sdim    int optidx = 0;
171286425Sdim
172286425Sdim    setprogname (argv[0]);
173286425Sdim
174286425Sdim    if(getarg(args, num_args, argc, argv, &optidx))
175286425Sdim	usage(1);
176286425Sdim    if(help_flag)
177286425Sdim	usage(0);
178286425Sdim    if(version_flag) {
179286425Sdim	print_version(NULL);
180286425Sdim	exit(0);
181286425Sdim    }
182286425Sdim    argv += optidx;
183286425Sdim    argc -= optidx;
184286425Sdim    if (argc != 1)
185286425Sdim	usage (1);
186286425Sdim
187286425Sdim    return doit (argv[0]);
188286425Sdim}
189286425Sdim