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.
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_silc_encode_identifier(username, hostname, realname,
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 SilcPublicKey *return_public_key,
64 SilcPrivateKey *return_private_key,
69 char *pkfile = pub_filename ? strdup(pub_filename) : NULL;
70 char *prvfile = prv_filename ? strdup(prv_filename) : NULL;
71 char *alg = pkcs_name ? strdup(pkcs_name) : NULL;
72 char *identifier = pub_identifier ? strdup(pub_identifier) : NULL;
73 char *pass = passphrase ? strdup(passphrase) : NULL;
75 if (interactive && (!alg || !pub_filename || !prv_filename))
77 New pair of keys will be created. Please, answer to following questions.\n\
83 alg = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
87 if (*alg == 'l' || *alg == 'L') {
88 char *list = silc_pkcs_get_supported();
100 if (!silc_pkcs_find_algorithm(alg, NULL)) {
101 fprintf(stderr, "Unknown PKCS algorithm `%s' or crypto library"
102 "is not initialized", alg);
109 length = silc_get_input("Key length in key_len_bits [2048]: ", FALSE);
111 key_len_bits = atoi(length);
119 char *def = silc_create_pk_identifier();
122 memset(line, 0, sizeof(line));
124 snprintf(line, sizeof(line), "Identifier [%s]: ", def);
126 snprintf(line, sizeof(line),
127 "Identifier (eg. UN=jon, HN=jon.dummy.com, "
128 "RN=Jon Johnson, E=jon@dummy.com): ");
130 while (!identifier) {
131 identifier = silc_get_input(line, FALSE);
132 if (!identifier && def)
133 identifier = strdup(def);
137 fprintf(stderr, "Could not create public key identifier: %s\n",
141 identifier = strdup(def);
147 rng = silc_rng_alloc();
149 silc_rng_global_init(rng);
153 memset(line, 0, sizeof(line));
154 snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
155 pkfile = silc_get_input(line, FALSE);
158 pkfile = strdup("public_key.pub");
163 memset(line, 0, sizeof(line));
164 snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
165 prvfile = silc_get_input(line, FALSE);
168 prvfile = strdup("private_key.prv");
174 pass = silc_get_input("Private key passphrase: ", TRUE);
181 pass2 = silc_get_input("Retype private key passphrase: ", TRUE);
184 match = !strcmp(pass, pass2);
188 fprintf(stderr, "\nPassphrases do not match\n\n");
194 if (!silc_pkcs_silc_generate_key(alg, "pkcs1-no-oid", key_len_bits,
195 identifier, rng, return_public_key,
199 /* Save public key into file */
200 silc_pkcs_save_public_key(pkfile, *return_public_key, SILC_PKCS_FILE_BASE64);
202 /* Save private key into file */
203 silc_pkcs_save_private_key(prvfile, *return_private_key,
204 (const unsigned char *)pass, strlen(pass),
205 SILC_PKCS_FILE_BIN, rng);
207 printf("Public key has been saved into `%s'.\n", pkfile);
208 printf("Private key has been saved into `%s'.\n", prvfile);
210 printf("Press <Enter> to continue...\n");
218 silc_free(identifier);
219 memset(pass, 0, strlen(pass));
227 SilcBool silc_load_key_pair(const char *pub_filename,
228 const char *prv_filename,
229 const char *passphrase,
230 SilcPublicKey *return_public_key,
231 SilcPrivateKey *return_private_key)
233 char *pass = passphrase ? strdup(passphrase) : NULL;
235 SILC_LOG_DEBUG(("Loading public and private keys"));
237 if (!silc_pkcs_load_public_key(pub_filename, return_public_key)) {
239 memset(pass, 0, strlen(pass));
245 pass = silc_get_input("Private key passphrase: ", TRUE);
250 if (!silc_pkcs_load_private_key(prv_filename,
251 (const unsigned char *)pass, strlen(pass),
252 return_private_key)) {
253 memset(pass, 0, strlen(pass));
258 memset(pass, 0, strlen(pass));
263 /* Dump public key into stdout */
265 SilcBool silc_show_public_key(const char *pub_filename)
267 SilcPublicKey public_key;
268 SilcSILCPublicKey silc_pubkey;
269 SilcPublicKeyIdentifier ident;
270 char *fingerprint, *babbleprint;
273 SilcUInt32 key_len = 0;
275 if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
276 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
280 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
282 silc_pkcs_public_key_free(public_key);
286 ident = &silc_pubkey->identifier;
287 key_len = silc_pkcs_public_key_get_len(public_key);
288 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
290 silc_pkcs_public_key_free(public_key);
293 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
294 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
296 printf("Public key file : %s\n", pub_filename);
297 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
299 printf("Key length (bits) : %d\n", (unsigned int)key_len);
301 printf("Real name : %s\n", ident->realname);
303 printf("Username : %s\n", ident->username);
305 printf("Hostname : %s\n", ident->host);
307 printf("Email : %s\n", ident->email);
309 printf("Organization : %s\n", ident->org);
311 printf("Country : %s\n", ident->country);
312 printf("Fingerprint (SHA1) : %s\n", fingerprint);
313 printf("Babbleprint (SHA1) : %s\n", babbleprint);
317 silc_free(fingerprint);
318 silc_free(babbleprint);
320 silc_pkcs_public_key_free(public_key);
325 /* Change private key passphrase */
327 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
328 const char *old_passphrase,
329 const char *new_passphrase)
331 SilcPrivateKey private_key;
335 pass = old_passphrase ? strdup(old_passphrase) : NULL;
337 pass = silc_get_input("Old passphrase: ", TRUE);
342 if (!silc_pkcs_load_private_key(prv_filename,
343 (const unsigned char *)pass, strlen(pass),
345 memset(pass, 0, strlen(pass));
347 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
351 memset(pass, 0, strlen(pass));
354 pass = new_passphrase ? strdup(new_passphrase) : NULL;
357 fprintf(stdout, "\n");
358 pass = silc_get_input("New passphrase: ", TRUE);
364 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
367 if (!strcmp(pass, pass2))
369 fprintf(stderr, "\nPassphrases do not match");
375 rng = silc_rng_alloc();
378 silc_pkcs_save_private_key((char *)prv_filename, private_key,
379 (unsigned char *)pass, strlen(pass),
380 SILC_PKCS_FILE_BIN, rng);
382 fprintf(stdout, "\nPassphrase changed\n");
384 memset(pass, 0, strlen(pass));
387 silc_pkcs_private_key_free(private_key);