const char *pub_filename,
const char *prv_filename,
const char *pub_identifier,
+ const char *passphrase,
SilcPKCS *return_pkcs,
SilcPublicKey *return_public_key,
SilcPrivateKey *return_private_key,
char *prvfile = prv_filename ? strdup(prv_filename) : NULL;
char *alg = pkcs_name ? strdup(pkcs_name) : NULL;
char *identifier = pub_identifier ? strdup(pub_identifier) : NULL;
+ char *pass = passphrase ? strdup(passphrase) : NULL;
if (interactive && (!alg || !pub_filename || !prv_filename))
printf("\
if (!pkfile) {
if (interactive) {
memset(line, 0, sizeof(line));
- snprintf(line, sizeof(line), "Public key filename [public_key.pub] ");
+ snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
pkfile = silc_get_input(line, FALSE);
}
if (!pkfile)
if (!prvfile) {
if (interactive) {
memset(line, 0, sizeof(line));
- snprintf(line, sizeof(line), "Public key filename [private_key.prv] ");
+ snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
prvfile = silc_get_input(line, FALSE);
}
if (!prvfile)
prvfile = strdup("private_key.prv");
}
+ if (!pass) {
+ char *pass2 = NULL;
+ pass = silc_get_input("Private key passphrase: ", TRUE);
+ if (!pass) {
+ pass = strdup("");
+ } else {
+ while (TRUE) {
+ printf("\n");
+ pass2 = silc_get_input("Retype private key passphrase: ", TRUE);
+ if (!pass2)
+ pass2 = strdup("");
+ if (!strcmp(pass, pass2))
+ break;
+ fprintf(stderr, "\nPassphrases do not match");
+ }
+ silc_free(pass2);
+ }
+ }
+
/* Generate keys */
silc_pkcs_alloc(alg, &pkcs);
silc_pkcs_generate_key(pkcs, key_len_bits, rng);
key = silc_pkcs_get_private_key(pkcs, &key_len);
prv_key = silc_pkcs_private_key_alloc(silc_pkcs_get_name(pkcs),
key, key_len);
- silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN);
+ silc_pkcs_save_private_key(prvfile, prv_key,
+ (unsigned char *)pass, strlen(pass),
+ SILC_PKCS_FILE_BIN);
if (return_private_key)
*return_private_key = prv_key;
else
silc_free(pkfile);
silc_free(prvfile);
silc_free(identifier);
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
return TRUE;
}
bool silc_load_key_pair(const char *pub_filename,
const char *prv_filename,
+ const char *passphrase,
SilcPKCS *return_pkcs,
SilcPublicKey *return_public_key,
SilcPrivateKey *return_private_key)
{
+ char *pass = passphrase ? strdup(passphrase) : NULL;
+
SILC_LOG_DEBUG(("Loading public and private keys"));
if (silc_pkcs_load_public_key((char *)pub_filename, return_public_key,
SILC_PKCS_FILE_PEM) == FALSE)
if (silc_pkcs_load_public_key((char *)pub_filename, return_public_key,
- SILC_PKCS_FILE_BIN) == FALSE)
+ SILC_PKCS_FILE_BIN) == FALSE) {
+ if (pass)
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
return FALSE;
+ }
+
+ if (!pass) {
+ pass = silc_get_input("Private key passphrase: ", TRUE);
+ if (!pass)
+ pass = strdup("");
+ }
if (silc_pkcs_load_private_key((char *)prv_filename, return_private_key,
+ (unsigned char *)pass, strlen(pass),
SILC_PKCS_FILE_BIN) == FALSE)
if (silc_pkcs_load_private_key((char *)prv_filename, return_private_key,
- SILC_PKCS_FILE_PEM) == FALSE)
+ (unsigned char *)pass, strlen(pass),
+ SILC_PKCS_FILE_PEM) == FALSE) {
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
return FALSE;
+ }
if (return_pkcs) {
silc_pkcs_alloc((*return_public_key)->name, return_pkcs);
silc_pkcs_private_key_set(*return_pkcs, *return_private_key);
}
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
return TRUE;
}
return TRUE;
}
+
+/* Change private key passphrase */
+
+bool silc_change_private_key_passphrase(const char *prv_filename,
+ const char *old_passphrase,
+ const char *new_passphrase)
+{
+ SilcPrivateKey private_key;
+ bool base64 = FALSE;
+ char *pass;
+
+ pass = old_passphrase ? strdup(old_passphrase) : NULL;
+ if (!pass) {
+ pass = silc_get_input("Old passphrase: ", TRUE);
+ if (!pass)
+ pass = strdup("");
+ }
+
+ if (silc_pkcs_load_private_key((char *)prv_filename, &private_key,
+ (unsigned char *)pass, strlen(pass),
+ SILC_PKCS_FILE_BIN) == FALSE) {
+ base64 = TRUE;
+ if (silc_pkcs_load_private_key((char *)prv_filename, &private_key,
+ (unsigned char *)pass, strlen(pass),
+ SILC_PKCS_FILE_PEM) == FALSE) {
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
+ fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
+ return FALSE;
+ }
+ }
+
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
+
+ pass = new_passphrase ? strdup(new_passphrase) : NULL;
+ if (!pass) {
+ char *pass2 = NULL;
+ fprintf(stdout, "\n");
+ pass = silc_get_input("New passphrase: ", TRUE);
+ if (!pass) {
+ pass = strdup("");
+ } else {
+ while (TRUE) {
+ printf("\n");
+ pass2 = silc_get_input("Retype new passphrase: ", TRUE);
+ if (!pass2)
+ pass2 = strdup("");
+ if (!strcmp(pass, pass2))
+ break;
+ fprintf(stderr, "\nPassphrases do not match");
+ }
+ silc_free(pass2);
+ }
+ }
+
+ silc_pkcs_save_private_key((char *)prv_filename, private_key,
+ (unsigned char *)pass, strlen(pass),
+ base64 ? SILC_PKCS_FILE_PEM : SILC_PKCS_FILE_BIN);
+
+ fprintf(stdout, "\nPassphrase changed\n");
+
+ memset(pass, 0, strlen(pass));
+ silc_free(pass);
+
+ silc_pkcs_private_key_free(private_key);
+ return TRUE;
+}