2 * Copyright (C) 2009 Martin Willi
3 * Copyright (C) 2009 Andreas Steffen
5 * HSR Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include <utils/linked_list.h>
23 #include <credentials/certificates/certificate.h>
26 * Create a self-signed PKCS#10 certificate requesst.
30 key_type_t type
= KEY_RSA
;
31 hash_algorithm_t digest
= HASH_SHA1
;
32 certificate_t
*cert
= NULL
;
33 private_key_t
*private = NULL
;
34 char *file
= NULL
, *dn
= NULL
, *error
= NULL
;
35 identification_t
*id
= NULL
;
37 chunk_t encoding
= chunk_empty
;
38 chunk_t challenge_password
= chunk_empty
;
41 san
= linked_list_create();
45 switch (command_getopt(&arg
))
50 dbg_level
= atoi(arg
);
53 if (streq(arg
, "rsa"))
57 else if (streq(arg
, "ecdsa"))
63 error
= "invalid input type";
68 digest
= get_digest(arg
);
69 if (digest
== HASH_UNKNOWN
)
71 error
= "invalid --digest type";
82 san
->insert_last(san
, identification_create_from_string(arg
));
85 challenge_password
= chunk_create(arg
, strlen(arg
));
90 error
= "invalid --req option";
98 error
= "--dn is required";
101 id
= identification_create_from_string(dn
);
102 if (id
->get_type(id
) != ID_DER_ASN1_DN
)
104 error
= "supplied --dn is not a distinguished name";
109 private = lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, type
,
110 BUILD_FROM_FILE
, file
, BUILD_END
);
114 private = lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
, type
,
115 BUILD_FROM_FD
, 0, BUILD_END
);
119 error
= "parsing private key failed";
122 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_PKCS10_REQUEST
,
123 BUILD_SIGNING_KEY
, private,
125 BUILD_SUBJECT_ALTNAMES
, san
,
126 BUILD_PASSPHRASE
, challenge_password
,
127 BUILD_DIGEST_ALG
, digest
,
131 error
= "generating certificate request failed";
134 encoding
= cert
->get_encoding(cert
);
137 error
= "encoding certificate request failed";
140 if (fwrite(encoding
.ptr
, encoding
.len
, 1, stdout
) != 1)
142 error
= "writing certificate request failed";
150 san
->destroy_offset(san
, offsetof(identification_t
, destroy
));
155 fprintf(stderr
, "%s\n", error
);
161 san
->destroy_offset(san
, offsetof(identification_t
, destroy
));
162 return command_usage(error
);
166 * Register the command.
168 static void __attribute__ ((constructor
))reg()
170 command_register((command_t
) {
172 "create a PKCS#10 certificate request",
173 {"[--in file] [--type rsa|ecdsa]",
174 " --dn distinguished-name [--san subjectAltName]+",
175 "[--password challengePassword]",
176 "[--digest md5|sha1|sha224|sha256|sha384|sha512]"},
178 {"help", 'h', 0, "show usage information"},
179 {"in", 'i', 1, "private key input file, default: stdin"},
180 {"type", 't', 1, "type of input key, default: rsa"},
181 {"dn", 'd', 1, "subject distinguished name"},
182 {"san", 'a', 1, "subjectAltName to include in cert request"},
183 {"password",'p', 1, "challengePassword to include in cert request"},
184 {"digest", 'g', 1, "digest for signature creation, default: sha1"},