diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 7873ea79..6aaffdb8 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -449,6 +449,9 @@ LIBSSH_API int ssh_pki_import_pubkey_base64(const char *b64_key, ssh_key *pkey); LIBSSH_API int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey); + +LIBSSH_API int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey, + ssh_key *pkey); LIBSSH_API int ssh_pki_export_pubkey_base64(const ssh_key key, char **b64_key); LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key, diff --git a/include/libssh/pki.h b/include/libssh/pki.h index 77106b43..7784deb9 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -80,9 +80,6 @@ int ssh_pki_export_pubkey_blob(const ssh_key key, int ssh_pki_import_pubkey_blob(const ssh_string key_blob, ssh_key *pkey); -/* SSH Private Key Functions */ -ssh_key ssh_pki_publickey_from_privatekey(const ssh_key privkey); - /* SSH Signing Functions */ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, ssh_key privatekey); diff --git a/src/auth.c b/src/auth.c index 3792854a..f5ce7496 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1118,8 +1118,8 @@ int ssh_userauth_publickey_auto(ssh_session session, continue; } - pubkey = ssh_pki_publickey_from_privatekey(privkey); - if (pubkey == NULL) { + rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); + if (rc == SSH_ERROR) { ssh_key_free(privkey); return SSH_AUTH_ERROR; } diff --git a/src/pki.c b/src/pki.c index 7628bb4e..a0c2d35a 100644 --- a/src/pki.c +++ b/src/pki.c @@ -784,19 +784,33 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) } /** - * @brief Generate and duplicate a public key from a private key. + * @brief Create a public key from a private key. * - * @param[in] privkey The private key to get the public key from. + * @param[in] privkey The private key to get the public key from. + * + * @param[out] pkey A pointer to store the newly allocated public key. You + * NEED to free the key. * * @return A public key, NULL on error. + * + * @see ssh_key_free() */ -ssh_key ssh_pki_publickey_from_privatekey(const ssh_key privkey) { +int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey, + ssh_key *pkey) +{ + ssh_key pubkey; if (privkey == NULL || !ssh_key_is_private(privkey)) { - return NULL; + return SSH_ERROR; } - return pki_key_dup(privkey, 1); + pubkey = pki_key_dup(privkey, 1); + if (pubkey == NULL) { + return SSH_ERROR; + } + + *pkey = pubkey; + return SSH_OK; } /** diff --git a/src/server.c b/src/server.c index 7f3618a4..5b2ccee8 100644 --- a/src/server.c +++ b/src/server.c @@ -189,8 +189,8 @@ static int dh_handshake_server(ssh_session session) { privkey = NULL; } - pubkey = ssh_pki_publickey_from_privatekey(privkey); - if (pubkey == NULL) { + rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); + if (rc < 0) { ssh_set_error(session, SSH_FATAL, "Could not get the public key from the private key"); ssh_string_free(f); diff --git a/tests/unittests/torture_pki.c b/tests/unittests/torture_pki.c index 02dd8181..bf924f2c 100644 --- a/tests/unittests/torture_pki.c +++ b/tests/unittests/torture_pki.c @@ -292,8 +292,8 @@ static void torture_pki_pki_publickey_from_privatekey_RSA(void **state) { rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); assert_true(rc == 0); - pubkey = ssh_pki_publickey_from_privatekey(key); - assert_true(pubkey != NULL); + rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); + assert_true(rc == SSH_OK); free(key_str); ssh_key_free(key); @@ -315,8 +315,8 @@ static void torture_pki_pki_publickey_from_privatekey_DSA(void **state) { rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); assert_true(rc == 0); - pubkey = ssh_pki_publickey_from_privatekey(key); - assert_true(pubkey != NULL); + rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); + assert_true(rc == SSH_OK); free(key_str); ssh_key_free(key); @@ -422,8 +422,8 @@ static void torture_generate_pubkey_from_privkey_rsa(void **state) { &privkey); assert_true(rc == 0); - pubkey = ssh_pki_publickey_from_privatekey(privkey); - assert_true(pubkey != NULL); + rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); + assert_true(rc == SSH_OK); rc = ssh_pki_export_pubkey_file(pubkey, LIBSSH_RSA_TESTKEY ".pub"); assert_true(rc == 0); @@ -463,8 +463,8 @@ static void torture_generate_pubkey_from_privkey_dsa(void **state) { &privkey); assert_true(rc == 0); - pubkey = ssh_pki_publickey_from_privatekey(privkey); - assert_true(pubkey != NULL); + rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); + assert_true(rc == SSH_OK); rc = ssh_pki_export_pubkey_file(pubkey, LIBSSH_DSA_TESTKEY ".pub"); assert_true(rc == 0); @@ -508,8 +508,8 @@ static void torture_pki_duplicate_key_rsa(void **state) privkey_dup = ssh_key_dup(privkey); assert_true(privkey_dup != NULL); - pubkey = ssh_pki_publickey_from_privatekey(privkey_dup); - assert_true(pubkey != NULL); + rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); + assert_true(rc == SSH_OK); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen); assert_true(rc == 0); @@ -551,8 +551,8 @@ static void torture_pki_duplicate_key_dsa(void **state) privkey_dup = ssh_key_dup(privkey); assert_true(privkey_dup != NULL); - pubkey = ssh_pki_publickey_from_privatekey(privkey_dup); - assert_true(pubkey != NULL); + rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); + assert_true(rc == SSH_OK); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen); assert_true(rc == 0); @@ -589,7 +589,7 @@ int torture_run_tests(void) { unit_test_setup_teardown(torture_pki_import_privkey_base64_passphrase, setup_both_keys_passphrase, teardown), - /* ssh_pki_publickey_from_privatekey */ + /* ssh_pki_export_privkey_to_pubkey */ unit_test_setup_teardown(torture_pki_pki_publickey_from_privatekey_RSA, setup_rsa_key, teardown),