5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2005 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "silcincludes.h"
23 static char *silc_create_pk_identifier(void)
25 char *username = NULL, *realname = NULL;
26 char *hostname, email[256];
30 realname = silc_get_real_name();
33 hostname = silc_net_localhost();
37 /* Get username (mandatory) */
38 username = silc_get_username();
42 /* Create default email address, whether it is right or not */
43 snprintf(email, sizeof(email), "%s@%s", username, hostname);
45 ident = silc_pkcs_encode_identifier(username, hostname, realname, email,
55 /* Generate key pair */
57 SilcBool silc_create_key_pair(const char *pkcs_name,
58 SilcUInt32 key_len_bits,
59 const char *pub_filename,
60 const char *prv_filename,
61 const char *pub_identifier,
62 const char *passphrase,
63 SilcPKCS *return_pkcs,
64 SilcPublicKey *return_public_key,
65 SilcPrivateKey *return_private_key,
69 SilcPublicKey pub_key;
70 SilcPrivateKey prv_key;
75 char *pkfile = pub_filename ? strdup(pub_filename) : NULL;
76 char *prvfile = prv_filename ? strdup(prv_filename) : NULL;
77 char *alg = pkcs_name ? strdup(pkcs_name) : NULL;
78 char *identifier = pub_identifier ? strdup(pub_identifier) : NULL;
79 char *pass = passphrase ? strdup(passphrase) : NULL;
81 if (interactive && (!alg || !pub_filename || !prv_filename))
83 New pair of keys will be created. Please, answer to following questions.\n\
89 alg = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
93 if (*alg == 'l' || *alg == 'L') {
94 char *list = silc_pkcs_get_supported();
106 if (!silc_pkcs_is_supported(alg)) {
107 fprintf(stderr, "Unknown PKCS algorithm `%s' or crypto library"
108 "is not initialized", alg);
115 length = silc_get_input("Key length in key_len_bits [2048]: ", FALSE);
117 key_len_bits = atoi(length);
125 char *def = silc_create_pk_identifier();
128 memset(line, 0, sizeof(line));
130 snprintf(line, sizeof(line), "Identifier [%s]: ", def);
132 snprintf(line, sizeof(line),
133 "Identifier (eg. UN=jon, HN=jon.dummy.com, "
134 "RN=Jon Johnson, E=jon@dummy.com): ");
136 while (!identifier) {
137 identifier = silc_get_input(line, FALSE);
138 if (!identifier && def)
139 identifier = strdup(def);
143 fprintf(stderr, "Could not create public key identifier: %s\n",
147 identifier = strdup(def);
153 rng = silc_rng_alloc();
155 silc_rng_global_init(rng);
159 memset(line, 0, sizeof(line));
160 snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
161 pkfile = silc_get_input(line, FALSE);
164 pkfile = strdup("public_key.pub");
169 memset(line, 0, sizeof(line));
170 snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
171 prvfile = silc_get_input(line, FALSE);
174 prvfile = strdup("private_key.prv");
180 pass = silc_get_input("Private key passphrase: ", TRUE);
187 pass2 = silc_get_input("Retype private key passphrase: ", TRUE);
190 match = !strcmp(pass, pass2);
194 fprintf(stderr, "\nPassphrases do not match\n\n");
200 silc_pkcs_alloc(alg, &pkcs);
201 silc_pkcs_generate_key(pkcs, key_len_bits, rng);
203 /* Save public key into file */
204 key = silc_pkcs_get_public_key(pkcs, &key_len);
205 pub_key = silc_pkcs_public_key_alloc(silc_pkcs_get_name(pkcs),
206 identifier, key, key_len);
207 silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM);
208 if (return_public_key)
209 *return_public_key = pub_key;
211 silc_pkcs_public_key_free(pub_key);
212 memset(key, 0, key_len);
215 /* Save private key into file */
216 key = silc_pkcs_get_private_key(pkcs, &key_len);
217 prv_key = silc_pkcs_private_key_alloc(silc_pkcs_get_name(pkcs),
219 silc_pkcs_save_private_key(prvfile, prv_key,
220 (unsigned char *)pass, strlen(pass),
222 if (return_private_key)
223 *return_private_key = prv_key;
225 silc_pkcs_private_key_free(prv_key);
226 memset(key, 0, key_len);
229 printf("Public key has been saved into `%s'.\n", pkfile);
230 printf("Private key has been saved into `%s'.\n", prvfile);
232 printf("Press <Enter> to continue...\n");
239 silc_pkcs_free(pkcs);
245 silc_free(identifier);
246 memset(pass, 0, strlen(pass));
254 SilcBool silc_load_key_pair(const char *pub_filename,
255 const char *prv_filename,
256 const char *passphrase,
257 SilcPKCS *return_pkcs,
258 SilcPublicKey *return_public_key,
259 SilcPrivateKey *return_private_key)
261 char *pass = passphrase ? strdup(passphrase) : NULL;
263 SILC_LOG_DEBUG(("Loading public and private keys"));
265 if (silc_pkcs_load_public_key((char *)pub_filename, return_public_key,
266 SILC_PKCS_FILE_PEM) == FALSE)
267 if (silc_pkcs_load_public_key((char *)pub_filename, return_public_key,
268 SILC_PKCS_FILE_BIN) == FALSE) {
270 memset(pass, 0, strlen(pass));
276 pass = silc_get_input("Private key passphrase: ", TRUE);
281 if (silc_pkcs_load_private_key((char *)prv_filename, return_private_key,
282 (unsigned char *)pass, strlen(pass),
283 SILC_PKCS_FILE_BIN) == FALSE)
284 if (silc_pkcs_load_private_key((char *)prv_filename, return_private_key,
285 (unsigned char *)pass, strlen(pass),
286 SILC_PKCS_FILE_PEM) == FALSE) {
287 memset(pass, 0, strlen(pass));
293 silc_pkcs_alloc((*return_public_key)->name, return_pkcs);
294 silc_pkcs_public_key_set(*return_pkcs, *return_public_key);
295 silc_pkcs_private_key_set(*return_pkcs, *return_private_key);
298 memset(pass, 0, strlen(pass));
303 /* Dump public key into stdout */
305 SilcBool silc_show_public_key(const char *pub_filename)
307 SilcPublicKey public_key;
308 SilcPublicKeyIdentifier ident;
309 char *fingerprint, *babbleprint;
313 SilcUInt32 key_len = 0;
315 if (silc_pkcs_load_public_key((char *)pub_filename, &public_key,
316 SILC_PKCS_FILE_PEM) == FALSE)
317 if (silc_pkcs_load_public_key((char *)pub_filename, &public_key,
318 SILC_PKCS_FILE_BIN) == FALSE) {
319 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
323 ident = silc_pkcs_decode_identifier(public_key->identifier);
325 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
326 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
327 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
329 if (silc_pkcs_alloc(public_key->name, &pkcs)) {
330 key_len = silc_pkcs_public_key_set(pkcs, public_key);
331 silc_pkcs_free(pkcs);
334 printf("Public key file : %s\n", pub_filename);
335 printf("Algorithm : %s\n", public_key->name);
337 printf("Key length (bits) : %d\n", (unsigned int)key_len);
339 printf("Real name : %s\n", ident->realname);
341 printf("Username : %s\n", ident->username);
343 printf("Hostname : %s\n", ident->host);
345 printf("Email : %s\n", ident->email);
347 printf("Organization : %s\n", ident->org);
349 printf("Country : %s\n", ident->country);
350 printf("Fingerprint (SHA1) : %s\n", fingerprint);
351 printf("Babbleprint (SHA1) : %s\n", babbleprint);
355 silc_free(fingerprint);
356 silc_free(babbleprint);
358 silc_pkcs_public_key_free(public_key);
359 silc_pkcs_free_identifier(ident);
364 /* Change private key passphrase */
366 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
367 const char *old_passphrase,
368 const char *new_passphrase)
370 SilcPrivateKey private_key;
371 SilcBool base64 = FALSE;
374 pass = old_passphrase ? strdup(old_passphrase) : NULL;
376 pass = silc_get_input("Old passphrase: ", TRUE);
381 if (silc_pkcs_load_private_key((char *)prv_filename, &private_key,
382 (unsigned char *)pass, strlen(pass),
383 SILC_PKCS_FILE_BIN) == FALSE) {
385 if (silc_pkcs_load_private_key((char *)prv_filename, &private_key,
386 (unsigned char *)pass, strlen(pass),
387 SILC_PKCS_FILE_PEM) == FALSE) {
388 memset(pass, 0, strlen(pass));
390 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
395 memset(pass, 0, strlen(pass));
398 pass = new_passphrase ? strdup(new_passphrase) : NULL;
401 fprintf(stdout, "\n");
402 pass = silc_get_input("New passphrase: ", TRUE);
408 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
411 if (!strcmp(pass, pass2))
413 fprintf(stderr, "\nPassphrases do not match");
419 silc_pkcs_save_private_key((char *)prv_filename, private_key,
420 (unsigned char *)pass, strlen(pass),
421 base64 ? SILC_PKCS_FILE_PEM : SILC_PKCS_FILE_BIN);
423 fprintf(stdout, "\nPassphrase changed\n");
425 memset(pass, 0, strlen(pass));
428 silc_pkcs_private_key_free(private_key);