2 * px5g - Embedded x509 key and certificate generator based on PolarSSL
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
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.
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.
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,
26 #include "polarssl/havege.h"
27 #include "polarssl/bignum.h"
28 #include "polarssl/x509.h"
29 #include "polarssl/rsa.h"
31 #define PX5G_VERSION "0.1"
32 #define PX5G_COPY "Copyright (c) 2009 Steven Barth <steven@midlink.org>"
33 #define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1"
35 int rsakey(char **arg) {
39 unsigned int ksize = 512;
42 int flag = X509_OUTPUT_PEM;
44 while (*arg && **arg == '-') {
45 if (!strcmp(*arg, "-out") && arg[1]) {
48 } else if (!strcmp(*arg, "-3")) {
50 } else if (!strcmp(*arg, "-der")) {
51 flag = X509_OUTPUT_DER;
57 ksize = (unsigned int)atoi(*arg);
61 rsa_init(&rsa, RSA_PKCS_V15, 0, havege_rand, &hs);
63 fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
64 if (rsa_gen_key(&rsa, ksize, exp)) {
65 fprintf(stderr, "error: key generation failed\n");
69 if (x509write_keyfile(&rsa, path, flag)) {
70 fprintf(stderr, "error: I/O error\n");
78 int selfsigned(char **arg) {
84 unsigned int ksize = 512;
86 unsigned int days = 30;
87 char *keypath = NULL, *certpath = NULL;
88 int flag = X509_OUTPUT_PEM;
89 time_t from = time(NULL), to;
90 char fstr[20], tstr[20];
92 while (*arg && **arg == '-') {
93 if (!strcmp(*arg, "-der")) {
94 flag = X509_OUTPUT_DER;
95 } else if (!strcmp(*arg, "-newkey") && arg[1]) {
96 if (strncmp(arg[1], "rsa:", 4)) {
97 fprintf(stderr, "error: invalid algorithm");
100 ksize = (unsigned int)atoi(arg[1] + 4);
102 } else if (!strcmp(*arg, "-days") && arg[1]) {
103 days = (unsigned int)atoi(arg[1]);
105 } else if (!strcmp(*arg, "-keyout") && arg[1]) {
108 } else if (!strcmp(*arg, "-out") && arg[1]) {
111 } else if (!strcmp(*arg, "-subj") && arg[1]) {
112 if (arg[1][0] != '/' || strchr(arg[1], ';')) {
113 fprintf(stderr, "error: invalid subject");
116 subject = calloc(strlen(arg[1]) + 1, 1);
117 char *oldc = arg[1] + 1, *newc = subject, *delim;
119 delim = strchr(oldc, '=');
121 fprintf(stderr, "error: invalid subject");
124 memcpy(newc, oldc, delim - oldc + 1);
125 newc += delim - oldc + 1;
128 delim = strchr(oldc, '/');
130 delim = arg[1] + strlen(arg[1]);
132 memcpy(newc, oldc, delim - oldc);
133 newc += delim - oldc;
143 rsa_init(&rsa, RSA_PKCS_V15, 0, havege_rand, &hs);
144 x509write_init_node(&node);
145 fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
146 if (rsa_gen_key(&rsa, ksize, exp)) {
147 fprintf(stderr, "error: key generation failed\n");
152 if (x509write_keyfile(&rsa, keypath, flag)) {
153 fprintf(stderr, "error: I/O error\n");
158 from = (from < 1000000000) ? 1000000000 : from;
159 strftime(fstr, sizeof(fstr), "%F %H:%M:%S", gmtime(&from));
160 to = from + 60 * 60 * 24 * days;
163 strftime(tstr, sizeof(tstr), "%F %H:%M:%S", gmtime(&to));
166 x509write_init_raw(&cert);
167 x509write_add_pubkey(&cert, &rsa);
168 x509write_add_subject(&cert, (unsigned char*)subject);
169 x509write_add_validity(&cert, (unsigned char*)fstr, (unsigned char*)tstr);
170 fprintf(stderr, "Generating selfsigned certificate with subject '%s'"
171 " and validity %s-%s\n", subject, fstr, tstr);
172 if (x509write_create_selfsign(&cert, &rsa)) {
173 fprintf(stderr, "error: certificate generation failed\n");
176 if (x509write_crtfile(&cert, (unsigned char*)certpath, flag)) {
177 fprintf(stderr, "error: I/O error\n");
181 x509write_free_raw(&cert);
186 int main(int argc, char *argv[]) {
189 } else if (!strcmp(argv[1], "rsakey")) {
190 return rsakey(argv+2);
191 } else if (!strcmp(argv[1], "selfsigned")) {
192 return selfsigned(argv+2);
196 "PX5G X.509 Certificate Generator Utility v" PX5G_VERSION "\n" PX5G_COPY
197 "\nbased on PolarSSL by Christophe Devine and Paul Bakker\n\n");
198 fprintf(stderr, "Usage: %s [rsakey|selfsigned]\n", *argv);