01261422ecc146c3a301dd98fd2ac76694832491
[strongswan.git] / scripts / extract-dn.c
1 /*
2 * Copyright (C) 2015 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <errno.h>
21 #include <getopt.h>
22
23 #include <library.h>
24
25 static void usage(FILE *out, char *name)
26 {
27 fprintf(out, "Extract the ASN.1 subject DN from a certificate\n\n");
28 fprintf(out, "%s [OPTIONS]\n\n", name);
29 fprintf(out, "Options:\n");
30 fprintf(out, " -h, --help print this help.\n");
31 fprintf(out, " -i, --in=FILE certificate file (default STDIN).\n");
32 fprintf(out, " -f, --format=FORMAT output format (config, hex, base64, binary).\n");
33 fprintf(out, "\n");
34 }
35
36 /**
37 * Extract the binary ASN.1 subject DN from a certificate
38 */
39 int main(int argc, char *argv[])
40 {
41 identification_t *id;
42 certificate_t *cert;
43 chunk_t chunk;
44 enum {
45 FORMAT_CONFIG,
46 FORMAT_HEX,
47 FORMAT_BASE64,
48 FORMAT_BINARY,
49 } format = FORMAT_CONFIG;
50 int fd = 0;
51 char *fmt;
52
53 library_init(NULL, "extract-dn");
54 atexit(library_deinit);
55
56 while (true)
57 {
58 struct option long_opts[] = {
59 {"help", no_argument, NULL, 'h' },
60 {"in", required_argument, NULL, 'i' },
61 {"format", required_argument, NULL, 'f' },
62 {0,0,0,0 },
63 };
64 switch (getopt_long(argc, argv, "hi:f:", long_opts, NULL))
65 {
66 case EOF:
67 break;
68 case 'h':
69 usage(stdout, argv[0]);
70 return 0;
71 case 'i':
72 fd = open(optarg, O_RDONLY);
73 if (fd == -1)
74 {
75 fprintf(stderr, "failed to open '%s': %s\n", optarg,
76 strerror(errno));
77 usage(stderr, argv[0]);
78 return 1;
79 }
80 continue;
81 case 'f':
82 if (streq(optarg, "hex"))
83 {
84 format = FORMAT_HEX;
85 }
86 else if (streq(optarg, "base64"))
87 {
88 format = FORMAT_BASE64;
89 }
90 else if (streq(optarg, "bin"))
91 {
92 format = FORMAT_BINARY;
93 }
94 continue;
95 default:
96 usage(stderr, argv[0]);
97 return 1;
98 }
99 break;
100 }
101 /* TODO: maybe make plugins configurable */
102 lib->plugins->load(lib->plugins, PLUGINS);
103
104 if (!chunk_from_fd(fd, &chunk))
105 {
106 fprintf(stderr, "reading input failed: %s\n", strerror(errno));
107 return 1;
108 }
109 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
110 BUILD_BLOB, chunk, BUILD_END);
111 chunk_free(&chunk);
112 if (fd != 0)
113 {
114 close(fd);
115 }
116
117 if (!cert)
118 {
119 fprintf(stderr, "failed to read certificate\n");
120 return 1;
121 }
122 id = cert->get_subject(cert);
123 if (!id)
124 {
125 fprintf(stderr, "failed to get certificate's subject DN\n");
126 cert->destroy(cert);
127 return 1;
128 }
129 fmt = "%.*s\n";
130 switch (format)
131 {
132 case FORMAT_CONFIG:
133 fmt = "\"asn1dn:#%.*s\"\n";
134 /* fall-through */
135 case FORMAT_HEX:
136 chunk = chunk_to_hex(id->get_encoding(id), NULL, FALSE);
137 printf(fmt, (int)chunk.len, chunk.ptr);
138 chunk_free(&chunk);
139 break;
140 case FORMAT_BASE64:
141 chunk = chunk_to_base64(id->get_encoding(id), NULL);
142 printf(fmt, (int)chunk.len, chunk.ptr);
143 chunk_free(&chunk);
144 break;
145 case FORMAT_BINARY:
146 chunk = id->get_encoding(id);
147 if (fwrite(chunk.ptr, chunk.len, 1, stdout) != 1)
148 {
149 fprintf(stderr, "writing subject DN failed\n");
150 }
151 break;
152 }
153 cert->destroy(cert);
154 return 0;
155 }