[tools] mm-macros: update to 0.9.5
[openwrt.git] / package / px5g / src / px5g.c
1 /*
2 * px5g - Embedded x509 key and certificate generator based on PolarSSL
3 *
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License, version 2.1 as published by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301 USA
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 #include "polarssl/havege.h"
26 #include "polarssl/bignum.h"
27 #include "polarssl/x509.h"
28 #include "polarssl/rsa.h"
29
30 #define PX5G_VERSION "0.1"
31 #define PX5G_COPY "Copyright (c) 2009 Steven Barth <steven@midlink.org>"
32 #define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1"
33
34 int rsakey(char **arg) {
35 havege_state hs;
36 rsa_context rsa;
37
38 unsigned int ksize = 512;
39 int exp = 65537;
40 char *path = NULL;
41 int flag = X509_OUTPUT_PEM;
42
43 while (*arg && **arg == '-') {
44 if (!strcmp(*arg, "-out") && arg[1]) {
45 path = arg[1];
46 arg++;
47 } else if (!strcmp(*arg, "-3")) {
48 exp = 3;
49 } else if (!strcmp(*arg, "-der")) {
50 flag = X509_OUTPUT_DER;
51 }
52 arg++;
53 }
54
55 if (*arg) {
56 ksize = (unsigned int)atoi(*arg);
57 }
58
59 havege_init(&hs);
60 rsa_init(&rsa, RSA_PKCS_V15, 0, havege_rand, &hs);
61
62 fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
63 if (rsa_gen_key(&rsa, ksize, exp)) {
64 fprintf(stderr, "error: key generation failed\n");
65 return 1;
66 }
67
68 if (x509write_keyfile(&rsa, path, flag)) {
69 fprintf(stderr, "error: I/O error\n");
70 return 1;
71 }
72
73 rsa_free(&rsa);
74 return 0;
75 }
76
77 int selfsigned(char **arg) {
78 havege_state hs;
79 rsa_context rsa;
80 x509_node node;
81
82 char *subject = "";
83 unsigned int ksize = 512;
84 int exp = 65537;
85 unsigned int days = 30;
86 char *keypath = NULL, *certpath = NULL;
87 int flag = X509_OUTPUT_PEM;
88 time_t from = time(NULL), to;
89 char fstr[20], tstr[20];
90
91 while (*arg && **arg == '-') {
92 if (!strcmp(*arg, "-der")) {
93 flag = X509_OUTPUT_DER;
94 } else if (!strcmp(*arg, "-newkey") && arg[1]) {
95 if (strncmp(arg[1], "rsa:", 4)) {
96 fprintf(stderr, "error: invalid algorithm");
97 return 1;
98 }
99 ksize = (unsigned int)atoi(arg[1] + 4);
100 arg++;
101 } else if (!strcmp(*arg, "-days") && arg[1]) {
102 days = (unsigned int)atoi(arg[1]);
103 arg++;
104 } else if (!strcmp(*arg, "-keyout") && arg[1]) {
105 keypath = arg[1];
106 arg++;
107 } else if (!strcmp(*arg, "-out") && arg[1]) {
108 certpath = arg[1];
109 arg++;
110 } else if (!strcmp(*arg, "-subj") && arg[1]) {
111 if (arg[1][0] != '/' || strchr(arg[1], ';')) {
112 fprintf(stderr, "error: invalid subject");
113 return 1;
114 }
115 subject = calloc(strlen(arg[1]) + 1, 1);
116 char *oldc = arg[1] + 1, *newc = subject, *delim;
117 do {
118 delim = strchr(oldc, '=');
119 if (!delim) {
120 fprintf(stderr, "error: invalid subject");
121 return 1;
122 }
123 memcpy(newc, oldc, delim - oldc + 1);
124 newc += delim - oldc + 1;
125 oldc = delim + 1;
126
127 delim = strchr(oldc, '/');
128 if (!delim) {
129 delim = arg[1] + strlen(arg[1]);
130 }
131 memcpy(newc, oldc, delim - oldc);
132 newc += delim - oldc;
133 *newc++ = ';';
134 oldc = delim + 1;
135 } while(*delim);
136 arg++;
137 }
138 arg++;
139 }
140
141 havege_init(&hs);
142 rsa_init(&rsa, RSA_PKCS_V15, 0, havege_rand, &hs);
143 x509write_init_node(&node);
144 fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
145 if (rsa_gen_key(&rsa, ksize, exp)) {
146 fprintf(stderr, "error: key generation failed\n");
147 return 1;
148 }
149
150 if (keypath) {
151 if (x509write_keyfile(&rsa, keypath, flag)) {
152 fprintf(stderr, "error: I/O error\n");
153 return 1;
154 }
155 }
156
157 from = (from < 1000000000) ? 1000000000 : from;
158 strftime(fstr, sizeof(fstr), "%F %H:%M:%S", gmtime(&from));
159 to = from + 60 * 60 * 24 * days;
160 strftime(tstr, sizeof(tstr), "%F %H:%M:%S", gmtime(&to));
161
162 x509_raw cert;
163 x509write_init_raw(&cert);
164 x509write_add_pubkey(&cert, &rsa);
165 x509write_add_subject(&cert, (unsigned char*)subject);
166 x509write_add_validity(&cert, (unsigned char*)fstr, (unsigned char*)tstr);
167 fprintf(stderr, "Generating selfsigned certificate with subject '%s'"
168 " and validity %s-%s\n", subject, fstr, tstr);
169 if (x509write_create_selfsign(&cert, &rsa)) {
170 fprintf(stderr, "error: certificate generation failed\n");
171 }
172
173 if (x509write_crtfile(&cert, (unsigned char*)certpath, flag)) {
174 fprintf(stderr, "error: I/O error\n");
175 return 1;
176 }
177
178 x509write_free_raw(&cert);
179 rsa_free(&rsa);
180 return 0;
181 }
182
183 int main(int argc, char *argv[]) {
184 if (!argv[1]) {
185 //Usage
186 } else if (!strcmp(argv[1], "rsakey")) {
187 return rsakey(argv+2);
188 } else if (!strcmp(argv[1], "selfsigned")) {
189 return selfsigned(argv+2);
190 }
191
192 fprintf(stderr,
193 "PX5G X.509 Certificate Generator Utility v" PX5G_VERSION "\n" PX5G_COPY
194 "\nbased on PolarSSL by Christophe Devine and Paul Bakker\n\n");
195 fprintf(stderr, "Usage: %s [rsakey|selfsigned]\n", *argv);
196 return 1;
197 }
This page took 0.059429 seconds and 5 git commands to generate.