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
);