config UPDATE use correct public key types
diff --git a/src/config_new.c b/src/config_new.c
index 4cefadf..fa8dca2 100644
--- a/src/config_new.c
+++ b/src/config_new.c
@@ -210,7 +210,7 @@
     case NC_PRIVKEY_FORMAT_EC:
         return "ietf-crypto-types:ec-private-key-format";
     case NC_PRIVKEY_FORMAT_X509:
-        return "libnetconf2-netconf-server:subject-private-key-info-format";
+        return "libnetconf2-netconf-server:private-key-info-format";
     case NC_PRIVKEY_FORMAT_OPENSSH:
         return "libnetconf2-netconf-server:openssh-private-key-format";
     default:
@@ -219,6 +219,306 @@
     }
 }
 
+static int
+nc_server_config_new_pubkey_bin_to_b64(const unsigned char *pub_bin, int bin_len, char **pubkey)
+{
+    int ret = 0, b64_len;
+    char *pub_b64 = NULL;
+
+    /* get b64 buffer len, for ever 3 bytes of bin 4 bytes of b64 + NULL terminator */
+    if (bin_len % 3 == 0) {
+        pub_b64 = malloc((bin_len / 3) * 4 + 1);
+    } else {
+        /* bin len not divisible by 3, need to add 4 bytes for some padding so that the len is divisible by 4 */
+        pub_b64 = malloc((bin_len / 3) * 4 + 4 + 1);
+    }
+    if (!pub_b64) {
+        ERRMEM;
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* bin to b64 */
+    b64_len = EVP_EncodeBlock((unsigned char *)pub_b64, pub_bin, bin_len);
+    *pubkey = strndup(pub_b64, b64_len);
+    if (!*pubkey) {
+        ERRMEM;
+        ret = 1;
+        goto cleanup;
+    }
+
+cleanup:
+    free(pub_b64);
+    return ret;
+}
+
+static int
+nc_server_config_new_bn_to_bin(const BIGNUM *bn, unsigned char **bin, int *bin_len)
+{
+    int ret = 0;
+    unsigned char *bin_tmp = NULL;
+
+    NC_CHECK_ARG_RET(NULL, bn, bin, bin_len, 1);
+
+    *bin = NULL;
+
+    /* prepare buffer for converting BN to binary */
+    bin_tmp = calloc(BN_num_bytes(bn), sizeof *bin_tmp);
+    if (!bin_tmp) {
+        ERRMEM;
+        return 1;
+    }
+
+    /* convert to binary */
+    *bin_len = BN_bn2bin(bn, bin_tmp);
+
+    /* if the highest bit in the MSB is set a byte with the value 0 has to be prepended */
+    if (bin_tmp[0] & 0x80) {
+        *bin = malloc(*bin_len + 1);
+        if (!*bin) {
+            ERRMEM;
+            ret = 1;
+            goto cleanup;
+        }
+
+        (*bin)[0] = 0;
+        memcpy(*bin + 1, bin_tmp, *bin_len);
+        (*bin_len)++;
+    } else {
+        *bin = malloc(*bin_len);
+        if (!*bin) {
+            ERRMEM;
+            ret = 1;
+            goto cleanup;
+        }
+
+        memcpy(*bin, bin_tmp, *bin_len);
+    }
+
+cleanup:
+    free(bin_tmp);
+    return ret;
+}
+
+/* ssh pubkey defined in RFC 4253 section 6.6 */
+static int
+nc_server_config_new_evp_pkey_to_ssh_pubkey(EVP_PKEY *pkey, char **pubkey)
+{
+    int ret = 0, e_len, n_len, p_len, bin_len;
+    BIGNUM *e = NULL, *n = NULL, *p = NULL;
+    unsigned char *e_bin = NULL, *n_bin = NULL, *p_bin = NULL, *bin = NULL, *bin_tmp;
+    const char *algorithm_name, *curve_name;
+    char *ec_group = NULL;
+    uint32_t alg_name_len, curve_name_len, alg_name_len_be, curve_name_len_be, p_len_be, e_len_be, n_len_be;
+    size_t ec_group_len;
+
+    if (EVP_PKEY_is_a(pkey, "RSA")) {
+        /* RSA key */
+        algorithm_name = "ssh-rsa";
+
+        /* get the public key params */
+        if (!EVP_PKEY_get_bn_param(pkey, "e", &e) || !EVP_PKEY_get_bn_param(pkey, "n", &n)) {
+            ERR(NULL, "Getting public key parameters from RSA private key failed (%s).", ERR_reason_error_string(ERR_get_error()));
+            ret = 1;
+            goto cleanup;
+        }
+
+        /* BIGNUM to bin */
+        if (nc_server_config_new_bn_to_bin(e, &e_bin, &e_len) || nc_server_config_new_bn_to_bin(n, &n_bin, &n_len)) {
+            ret = 1;
+            goto cleanup;
+        }
+
+        alg_name_len = strlen(algorithm_name);
+        /* buffer for public key in binary, which looks like this:
+         * alg_name len (4 bytes), alg_name, PK exponent len (4 bytes), PK exponent, modulus len (4 bytes), modulus
+         */
+        bin_len = 4 + alg_name_len + 4 + e_len + 4 + n_len;
+        bin = malloc(bin_len);
+        if (!bin) {
+            ERRMEM;
+            ret = 1;
+            goto cleanup;
+        }
+
+        /* to network byte order (big endian) */
+        alg_name_len_be = htonl(alg_name_len);
+        e_len_be = htonl(e_len);
+        n_len_be = htonl(n_len);
+
+        /* create the public key in binary */
+        bin_tmp = bin;
+        memcpy(bin_tmp, &alg_name_len_be, 4);
+        bin_tmp += 4;
+        memcpy(bin_tmp, algorithm_name, alg_name_len);
+        bin_tmp += alg_name_len;
+        memcpy(bin_tmp, &e_len_be, 4);
+        bin_tmp += 4;
+        memcpy(bin_tmp, e_bin, e_len);
+        bin_tmp += e_len;
+        memcpy(bin_tmp, &n_len_be, 4);
+        bin_tmp += 4;
+        memcpy(bin_tmp, n_bin, n_len);
+    } else if (EVP_PKEY_is_a(pkey, "EC")) {
+        /* EC Private key, get it's group first */
+        /* get group len */
+        ret = EVP_PKEY_get_utf8_string_param(pkey, "group", NULL, 0, &ec_group_len);
+        if (!ret) {
+            ret = 1;
+            goto cleanup;
+        }
+        /* alloc mem for group + 1 for \0 */
+        ec_group = malloc(ec_group_len + 1);
+        if (!ec_group) {
+            ERRMEM;
+            ret = 1;
+            goto cleanup;
+        }
+        /* get the group */
+        ret = EVP_PKEY_get_utf8_string_param(pkey, "group", ec_group, ec_group_len + 1, NULL);
+        if (!ret) {
+            ERR(NULL, "Getting public key parameter from EC private key failed (%s).", ERR_reason_error_string(ERR_get_error()));
+            ret = 1;
+            goto cleanup;
+        }
+
+        /* get alg and curve names */
+        if (!strcmp(ec_group, "P-256") || !strcmp(ec_group, "secp256r1") || !strcmp(ec_group, "prime256v1")) {
+            algorithm_name = "ecdsa-sha2-nistp256";
+            curve_name = "nistp256";
+        } else if (!strcmp(ec_group, "P-384") || !strcmp(ec_group, "secp384r1")) {
+            algorithm_name = "ecdsa-sha2-nistp384";
+            curve_name = "nistp384";
+        } else if (!strcmp(ec_group, "P-521") || !strcmp(ec_group, "secp521r1")) {
+            algorithm_name = "ecdsa-sha2-nistp521";
+            curve_name = "nistp521";
+        } else {
+            ERR(NULL, "EC group \"%s\" not supported.", ec_group);
+            ret = 1;
+            goto cleanup;
+        }
+
+        /* get the public key - p, which is a point on the elliptic curve */
+        ret = EVP_PKEY_get_bn_param(pkey, "p", &p);
+        if (!ret) {
+            ERR(NULL, "Getting public key point from the EC private key failed (%s).", ERR_reason_error_string(ERR_get_error()));
+            ret = 1;
+            goto cleanup;
+        }
+
+        /* prepare buffer for converting p to binary */
+        p_bin = malloc(BN_num_bytes(p));
+        if (!p_bin) {
+            ERRMEM;
+            ret = 1;
+            goto cleanup;
+        }
+        /* convert to binary */
+        p_len = BN_bn2bin(p, p_bin);
+
+        alg_name_len = strlen(algorithm_name);
+        curve_name_len = strlen(curve_name);
+        /* buffer for public key in binary, which looks like so:
+         * alg_name len (4 bytes), alg_name, curve_name len (4 bytes), curve_name, PK point p len (4 bytes), PK point p
+         */
+        bin_len = 4 + alg_name_len + 4 + curve_name_len + 4 + p_len;
+        bin = malloc(bin_len);
+        if (!bin) {
+            ERRMEM;
+            ret = 1;
+            goto cleanup;
+        }
+
+        /* to network byte order (big endian) */
+        alg_name_len_be = htonl(alg_name_len);
+        curve_name_len_be = htonl(curve_name_len);
+        p_len_be = htonl(p_len);
+
+        /* create the public key in binary */
+        bin_tmp = bin;
+        memcpy(bin_tmp, &alg_name_len_be, 4);
+        bin_tmp += 4;
+        memcpy(bin_tmp, algorithm_name, alg_name_len);
+        bin_tmp += alg_name_len;
+        memcpy(bin_tmp, &curve_name_len_be, 4);
+        bin_tmp += 4;
+        memcpy(bin_tmp, curve_name, curve_name_len);
+        bin_tmp += curve_name_len;
+        memcpy(bin_tmp, &p_len_be, 4);
+        bin_tmp += 4;
+        memcpy(bin_tmp, p_bin, p_len);
+    } else if (EVP_PKEY_is_a(pkey, "ED25519")) {
+        ERR(NULL, "Generating PEM ED25519 key from OpenSSH is not supported by libssh yet.");
+        ret = 1;
+        goto cleanup;
+    } else {
+        ERR(NULL, "Unable to generate public key from private key (Private key type not supported).");
+        ret = 1;
+        goto cleanup;
+    }
+
+    ret = nc_server_config_new_pubkey_bin_to_b64(bin, bin_len, pubkey);
+    if (ret) {
+        ERR(NULL, "Converting public key from binary to base64 failed.");
+        goto cleanup;
+    }
+
+cleanup:
+    free(bin);
+    free(e_bin);
+    free(n_bin);
+    free(ec_group);
+    free(p_bin);
+    BN_free(e);
+    BN_free(n);
+    BN_free(p);
+    return ret;
+}
+
+/* spki = subject public key info */
+static int
+nc_server_config_new_evp_pkey_to_spki_pubkey(EVP_PKEY *pkey, char **pubkey)
+{
+    int ret = 0, len;
+    BIO *bio = NULL;
+    char *pub_b64 = NULL;
+
+    bio = BIO_new(BIO_s_mem());
+    if (!bio) {
+        ERR(NULL, "Creating new BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* write the evp_pkey contents to bio */
+    if (!PEM_write_bio_PUBKEY(bio, pkey)) {
+        ERR(NULL, "Writing public key to BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* read the pubkey from bio */
+    len = BIO_get_mem_data(bio, &pub_b64);
+    if (len <= 0) {
+        ERR(NULL, "Reading base64 private key from BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* copy the public key without the header and footer */
+    *pubkey = strndup(pub_b64 + strlen(NC_SUBJECT_PUBKEY_INFO_HEADER),
+            len - strlen(NC_SUBJECT_PUBKEY_INFO_HEADER) - strlen(NC_SUBJECT_PUBKEY_INFO_FOOTER));
+    if (!*pubkey) {
+        ERRMEM;
+        ret = 1;
+        goto cleanup;
+    }
+
+cleanup:
+    BIO_free(bio);
+    return ret;
+}
+
 int
 nc_server_config_new_read_certificate(const char *cert_path, char **cert)
 {
@@ -305,7 +605,7 @@
 }
 
 static int
-nc_server_config_new_read_ssh2_pubkey(FILE *f, char **pubkey)
+nc_server_config_new_read_pubkey_ssh2(FILE *f, char **pubkey)
 {
     char *buffer = NULL;
     size_t size = 0, pubkey_len = 0;
@@ -355,74 +655,20 @@
 nc_server_config_new_read_pubkey_openssl(FILE *f, char **pubkey)
 {
     int ret = 0;
-    EVP_PKEY *pkey = NULL;
-    BIO *bio = NULL;
-    char *key = NULL;
-    int pub_len;
+    EVP_PKEY *pub_pkey = NULL;
+
+    NC_CHECK_ARG_RET(NULL, f, pubkey, 1);
 
     /* read the pubkey from file */
-    pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
-    if (!pkey) {
-        ret = -1;
-        goto cleanup;
+    pub_pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
+    if (!pub_pkey) {
+        ERR(NULL, "Reading public key from file failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        return 1;
     }
 
-    bio = BIO_new(BIO_s_mem());
-    if (!bio) {
-        ret = -1;
-        goto cleanup;
-    }
+    ret = nc_server_config_new_evp_pkey_to_ssh_pubkey(pub_pkey, pubkey);
 
-    /* write the pubkey into bio */
-    ret = PEM_write_bio_PUBKEY(bio, pkey);
-    if (!ret) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    pub_len = BIO_pending(bio);
-    if (pub_len <= 0) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    /* get pubkey's length */
-    key = malloc(pub_len + 1);
-    if (!key) {
-        ERRMEM;
-        ret = 1;
-        goto cleanup;
-    }
-
-    /* read the public key from bio */
-    ret = BIO_read(bio, key, pub_len);
-    if (ret <= 0) {
-        ret = -1;
-        goto cleanup;
-    }
-    key[pub_len] = '\0';
-
-    /* strip the pubkey of the header and footer */
-    *pubkey = strdup(key + strlen(NC_SUBJECT_PUBKEY_INFO_HEADER));
-    if (!*pubkey) {
-        ERRMEM;
-        ret = 1;
-        goto cleanup;
-    }
-
-    (*pubkey)[strlen(*pubkey) - strlen(NC_SUBJECT_PUBKEY_INFO_FOOTER)] = '\0';
-
-    ret = 0;
-cleanup:
-    if (ret == -1) {
-        ERR(NULL, "Error getting public key from file (OpenSSL Error): \"%s\".", ERR_reason_error_string(ERR_get_error()));
-        ret = 1;
-    }
-
-    BIO_free(bio);
-    EVP_PKEY_free(pkey);
-    free(key);
-
+    EVP_PKEY_free(pub_pkey);
     return ret;
 }
 
@@ -432,6 +678,8 @@
     int ret = 0;
     ssh_key pub_sshkey = NULL;
 
+    NC_CHECK_ARG_RET(NULL, pubkey_path, pubkey, 1);
+
     ret = ssh_pki_import_pubkey_file(pubkey_path, &pub_sshkey);
     if (ret) {
         ERR(NULL, "Importing public key from file \"%s\" failed.", pubkey_path);
@@ -440,22 +688,24 @@
 
     ret = ssh_pki_export_pubkey_base64(pub_sshkey, pubkey);
     if (ret) {
-        ERR(NULL, "Exporting public key to base64 failed.");
+        ERR(NULL, "Importing pubkey failed.");
+        goto cleanup;
     }
 
+cleanup:
     ssh_key_free(pub_sshkey);
-    return ret;
+    return 0;
 }
 
 int
-nc_server_config_new_get_pubkey(const char *pubkey_path, char **pubkey, NC_PUBKEY_FORMAT *pubkey_type)
+nc_server_config_new_get_ssh_pubkey_file(const char *pubkey_path, char **pubkey)
 {
     int ret = 0;
     FILE *f = NULL;
     char *header = NULL;
     size_t len = 0;
 
-    NC_CHECK_ARG_RET(NULL, pubkey, pubkey_type, 1);
+    NC_CHECK_ARG_RET(NULL, pubkey_path, pubkey, 1);
 
     *pubkey = NULL;
 
@@ -466,6 +716,7 @@
         goto cleanup;
     }
 
+    /* read the header */
     if (getline(&header, &len, f) < 0) {
         ERR(NULL, "Error reading header from file \"%s\".", pubkey_path);
         ret = 1;
@@ -476,17 +727,13 @@
     if (!strncmp(header, NC_SUBJECT_PUBKEY_INFO_HEADER, strlen(NC_SUBJECT_PUBKEY_INFO_HEADER))) {
         /* it's subject public key info public key */
         ret = nc_server_config_new_read_pubkey_openssl(f, pubkey);
-        *pubkey_type = NC_PUBKEY_FORMAT_X509;
     } else if (!strncmp(header, NC_SSH2_PUBKEY_HEADER, strlen(NC_SSH2_PUBKEY_HEADER))) {
         /* it's ssh2 public key */
-        ret = nc_server_config_new_read_ssh2_pubkey(f, pubkey);
-        *pubkey_type = NC_PUBKEY_FORMAT_SSH2;
+        ret = nc_server_config_new_read_pubkey_ssh2(f, pubkey);
     } else {
         /* it's probably OpenSSH public key */
         ret = nc_server_config_new_read_pubkey_libssh(pubkey_path, pubkey);
-        *pubkey_type = NC_PUBKEY_FORMAT_SSH2;
     }
-
     if (ret) {
         ERR(NULL, "Error getting public key from file \"%s\".", pubkey_path);
         goto cleanup;
@@ -498,199 +745,190 @@
     }
 
     free(header);
-
-    return ret;
-}
-
-static int
-nc_server_config_new_get_privkey_openssl(FILE *f, char **privkey, EVP_PKEY **priv_pkey)
-{
-    int ret = 0, priv_len;
-    BIO *bio = NULL;
-
-    NC_CHECK_ARG_RET(NULL, privkey, priv_pkey, 1);
-
-    /* read private key from file */
-    *priv_pkey = PEM_read_PrivateKey(f, NULL, NULL, NULL);
-    if (!*priv_pkey) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    bio = BIO_new(BIO_s_mem());
-    if (!bio) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    /* write the private key in to bio */
-    ret = PEM_write_bio_PrivateKey(bio, *priv_pkey, NULL, NULL, 0, NULL, NULL);
-    if (!ret) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    priv_len = BIO_pending(bio);
-    if (priv_len <= 0) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    /* get private key's length */
-    *privkey = malloc(priv_len + 1);
-    if (!*privkey) {
-        ERRMEM;
-        ret = 1;
-        goto cleanup;
-    }
-
-    /* read the private key from bio */
-    ret = BIO_read(bio, *privkey, priv_len);
-    if (ret <= 0) {
-        ret = -1;
-        goto cleanup;
-    }
-    (*privkey)[priv_len] = '\0';
-
-    ret = 0;
-cleanup:
-    if (ret < 0) {
-        ERR(NULL, "Getting private key from file failed (%s).", ERR_reason_error_string(ERR_get_error()));
-    }
-    BIO_free(bio);
-    return ret;
-}
-
-static int
-nc_server_config_new_privkey_to_pubkey_openssl(EVP_PKEY *priv_pkey, char **pubkey)
-{
-    int ret = 0, pub_len;
-    BIO *bio = NULL;
-
-    bio = BIO_new(BIO_s_mem());
-    if (!bio) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    /* write the pubkey into bio */
-    ret = PEM_write_bio_PUBKEY(bio, priv_pkey);
-    if (!ret) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    /* get the length of the pubkey */
-    pub_len = BIO_pending(bio);
-    if (pub_len <= 0) {
-        ret = -1;
-        goto cleanup;
-    }
-
-    *pubkey = malloc(pub_len + 1);
-    if (!*pubkey) {
-        ERRMEM;
-        ret = 1;
-        goto cleanup;
-    }
-
-    /* read the pubkey from the bio */
-    ret = BIO_read(bio, *pubkey, pub_len);
-    if (ret <= 0) {
-        ret = -1;
-        goto cleanup;
-    }
-    (*pubkey)[pub_len] = '\0';
-
-    ret = 0;
-
-cleanup:
-    if (ret < 0) {
-        ERR(NULL, "Converting private to public key failed (%s).", ERR_reason_error_string(ERR_get_error()));
-    }
-    BIO_free(bio);
-    return ret;
-}
-
-static int
-nc_server_config_new_privkey_to_pubkey_libssh(const ssh_key priv_sshkey, char **pubkey)
-{
-    int ret;
-    ssh_key pub_sshkey = NULL;
-
-    ret = ssh_pki_export_privkey_to_pubkey(priv_sshkey, &pub_sshkey);
-    if (ret) {
-        ERR(NULL, "Exporting privkey to pubkey failed.");
-        return ret;
-    }
-
-    ret = ssh_pki_export_pubkey_base64(pub_sshkey, pubkey);
-    if (ret) {
-        ERR(NULL, "Exporting pubkey to base64 failed.");
-    }
-
-    ssh_key_free(pub_sshkey);
-    return ret;
-}
-
-static int
-nc_server_config_new_privkey_to_pubkey(EVP_PKEY *priv_pkey, const ssh_key priv_sshkey, NC_PRIVKEY_FORMAT privkey_type, char **pubkey, NC_PUBKEY_FORMAT *pubkey_type)
-{
-    switch (privkey_type) {
-    case NC_PRIVKEY_FORMAT_RSA:
-    case NC_PRIVKEY_FORMAT_EC:
-    case NC_PRIVKEY_FORMAT_OPENSSH:
-        *pubkey_type = NC_PUBKEY_FORMAT_SSH2;
-        return nc_server_config_new_privkey_to_pubkey_libssh(priv_sshkey, pubkey);
-    case NC_PRIVKEY_FORMAT_X509:
-        *pubkey_type = NC_PUBKEY_FORMAT_X509;
-        return nc_server_config_new_privkey_to_pubkey_openssl(priv_pkey, pubkey);
-    default:
-        break;
-    }
-
-    return 1;
-}
-
-static int
-nc_server_config_new_get_privkey_libssh(const char *privkey_path, char **privkey, ssh_key *priv_sshkey)
-{
-    int ret;
-
-    *priv_sshkey = NULL;
-
-    ret = ssh_pki_import_privkey_file(privkey_path, NULL, NULL, NULL, priv_sshkey);
-    if (ret) {
-        ERR(NULL, "Importing privkey from file \"%s\" failed.", privkey_path);
-        return ret;
-    }
-
-    ret = ssh_pki_export_privkey_base64(*priv_sshkey, NULL, NULL, NULL, privkey);
-    if (ret) {
-        ERR(NULL, "Exporting privkey from file \"%s\" to base64 failed.", privkey_path);
-    }
-
     return ret;
 }
 
 int
-nc_server_config_new_get_keys(const char *privkey_path, const char *pubkey_path,
-        char **privkey, char **pubkey, NC_PRIVKEY_FORMAT *privkey_type, NC_PUBKEY_FORMAT *pubkey_type)
+nc_server_config_new_get_spki_pubkey_file(const char *pubkey_path, char **pubkey)
 {
     int ret = 0;
-    EVP_PKEY *priv_pkey = NULL;
-    ssh_key priv_sshkey = NULL;
-    FILE *f_privkey = NULL;
-    char *header = NULL;
-    size_t len = 0;
-    char *priv = NULL, *pub = NULL;
+    FILE *f = NULL;
+    EVP_PKEY *pub_pkey = NULL;
 
-    NC_CHECK_ARG_RET(NULL, privkey_path, privkey, pubkey, privkey_type, 1);
+    NC_CHECK_ARG_RET(NULL, pubkey_path, pubkey, 1);
 
-    *privkey = NULL;
     *pubkey = NULL;
 
-    /* get private key first */
+    f = fopen(pubkey_path, "r");
+    if (!f) {
+        ERR(NULL, "Unable to open file \"%s\".", pubkey_path);
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* read the pubkey from file */
+    pub_pkey = PEM_read_PUBKEY(f, NULL, NULL, NULL);
+    if (!pub_pkey) {
+        ERR(NULL, "Reading public key from file failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        return 1;
+    }
+
+    ret = nc_server_config_new_evp_pkey_to_spki_pubkey(pub_pkey, pubkey);
+    if (ret) {
+        goto cleanup;
+    }
+
+cleanup:
+    if (f) {
+        fclose(f);
+    }
+
+    EVP_PKEY_free(pub_pkey);
+    return ret;
+}
+
+static int
+nc_server_config_new_privkey_header_to_format(FILE *f_privkey, const char *privkey_path, NC_PRIVKEY_FORMAT *privkey_format)
+{
+    char *privkey_header = NULL;
+    size_t len = 0;
+
+    /* read header */
+    if (getline(&privkey_header, &len, f_privkey) < 0) {
+        ERR(NULL, "Error reading header from file \"%s\".", privkey_path);
+        return 1;
+    }
+
+    if (!strncmp(privkey_header, NC_PKCS8_PRIVKEY_HEADER, strlen(NC_PKCS8_PRIVKEY_HEADER))) {
+        /* it's PKCS8 (X.509) private key */
+        *privkey_format = NC_PRIVKEY_FORMAT_X509;
+    } else if (!strncmp(privkey_header, NC_OPENSSH_PRIVKEY_HEADER, strlen(NC_OPENSSH_PRIVKEY_HEADER))) {
+        /* it's OpenSSH private key */
+        *privkey_format = NC_PRIVKEY_FORMAT_OPENSSH;
+    } else if (!strncmp(privkey_header, NC_PKCS1_RSA_PRIVKEY_HEADER, strlen(NC_PKCS1_RSA_PRIVKEY_HEADER))) {
+        /* it's RSA privkey in PKCS1 format */
+        *privkey_format = NC_PRIVKEY_FORMAT_RSA;
+    } else if (!strncmp(privkey_header, NC_SEC1_EC_PRIVKEY_HEADER, strlen(NC_SEC1_EC_PRIVKEY_HEADER))) {
+        /* it's EC privkey in SEC1 format */
+        *privkey_format = NC_PRIVKEY_FORMAT_EC;
+    } else {
+        ERR(NULL, "Private key format (%s) not supported.", privkey_header);
+        free(privkey_header);
+        return 1;
+    }
+
+    /* reset the reading head */
+    rewind(f_privkey);
+    free(privkey_header);
+    return 0;
+}
+
+static int
+nc_server_config_new_get_privkey_openssl(const char *privkey_path, FILE *f_privkey, char **privkey, EVP_PKEY **pkey)
+{
+    int ret = 0, len;
+    BIO *bio = NULL;
+    char *priv_b64 = NULL;
+
+    bio = BIO_new(BIO_s_mem());
+    if (!bio) {
+        ERR(NULL, "Creating new BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* read the privkey file, create EVP_PKEY */
+    *pkey = PEM_read_PrivateKey(f_privkey, NULL, NULL, NULL);
+    if (!*pkey) {
+        ERR(NULL, "Getting private key from file \"%s\" failed (%s).", privkey_path, ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* write the privkey to bio */
+    if (!PEM_write_bio_PrivateKey(bio, *pkey, NULL, NULL, 0, NULL, NULL)) {
+        ERR(NULL, "Writing private key to BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* read the privkey from bio */
+    len = BIO_get_mem_data(bio, &priv_b64);
+    if (len <= 0) {
+        ERR(NULL, "Reading base64 private key from BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    *privkey = strndup(priv_b64, len);
+
+cleanup:
+    BIO_free(bio);
+    return ret;
+}
+
+static int
+nc_server_config_new_get_privkey_libssh(const char *privkey_path, char **privkey, EVP_PKEY **pkey)
+{
+    int ret = 0;
+    BIO *bio = NULL;
+    char *priv_b64 = NULL;
+    ssh_key key = NULL;
+
+    ret = ssh_pki_import_privkey_file(privkey_path, NULL, NULL, NULL, &key);
+    if (ret) {
+        ERR(NULL, "Importing privkey from file \"%s\" failed.", privkey_path);
+        goto cleanup;
+    }
+
+    /* exports the key in a format in which OpenSSL can read it */
+    ret = ssh_pki_export_privkey_base64(key, NULL, NULL, NULL, &priv_b64);
+    if (ret) {
+        ERR(NULL, "Exporting privkey to base64 failed.");
+        goto cleanup;
+    }
+
+    bio = BIO_new(BIO_s_mem());
+    if (!bio) {
+        ERR(NULL, "Creating new BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    ret = BIO_write(bio, priv_b64, strlen(priv_b64));
+    if (ret <= 0) {
+        ERR(NULL, "Writing private key to BIO failed (%s).", ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    /* create EVP_PKEY from the b64 */
+    *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
+    if (!*pkey) {
+        ERR(NULL, "Getting private key from file \"%s\" failed (%s).", privkey_path, ERR_reason_error_string(ERR_get_error()));
+        ret = 1;
+        goto cleanup;
+    }
+
+    *privkey = strndup(priv_b64, ret);
+
+    /* ok */
+    ret = 0;
+
+cleanup:
+    free(priv_b64);
+    BIO_free(bio);
+    ssh_key_free(key);
+    return ret;
+}
+
+static int
+nc_server_config_new_get_privkey(const char *privkey_path, NC_PRIVKEY_FORMAT *privkey_format, char **privkey, EVP_PKEY **pkey)
+{
+    int ret = 0;
+    FILE *f_privkey = NULL;
+    char *priv = NULL;
+
     f_privkey = fopen(privkey_path, "r");
     if (!f_privkey) {
         ERR(NULL, "Unable to open file \"%s\".", privkey_path);
@@ -698,101 +936,98 @@
         goto cleanup;
     }
 
-    if (getline(&header, &len, f_privkey) < 0) {
-        ERR(NULL, "Error reading header from file \"%s\".", privkey_path);
-        ret = 1;
+    /* read the first line from the privkey to determine it's type */
+    ret = nc_server_config_new_privkey_header_to_format(f_privkey, privkey_path, privkey_format);
+    if (ret) {
+        ERR(NULL, "Getting private key format from file \"%s\" failed.", privkey_path);
         goto cleanup;
     }
-    rewind(f_privkey);
 
-    if (!strncmp(header, NC_PKCS8_PRIVKEY_HEADER, strlen(NC_PKCS8_PRIVKEY_HEADER))) {
-        /* it's PKCS8 (X.509) private key */
-        *privkey_type = NC_PRIVKEY_FORMAT_X509;
-        ret = nc_server_config_new_get_privkey_openssl(f_privkey, &priv, &priv_pkey);
-    } else if (!strncmp(header, NC_OPENSSH_PRIVKEY_HEADER, strlen(NC_OPENSSH_PRIVKEY_HEADER))) {
-        /* it's OpenSSH private key */
-        *privkey_type = NC_PRIVKEY_FORMAT_OPENSSH;
-        ret = nc_server_config_new_get_privkey_libssh(privkey_path, &priv, &priv_sshkey);
-    } else if (!strncmp(header, NC_PKCS1_RSA_PRIVKEY_HEADER, strlen(NC_PKCS1_RSA_PRIVKEY_HEADER))) {
-        /* it's RSA privkey in PKCS1 format */
-        *privkey_type = NC_PRIVKEY_FORMAT_RSA;
-        ret = nc_server_config_new_get_privkey_libssh(privkey_path, &priv, &priv_sshkey);
-    } else if (!strncmp(header, NC_SEC1_EC_PRIVKEY_HEADER, strlen(NC_SEC1_EC_PRIVKEY_HEADER))) {
-        /* it's EC privkey in SEC1 format */
-        *privkey_type = NC_PRIVKEY_FORMAT_EC;
-        ret = nc_server_config_new_get_privkey_libssh(privkey_path, &priv, &priv_sshkey);
-    } else {
-        ERR(NULL, "Private key format not supported.");
+    switch (*privkey_format) {
+    /* fall-through */
+    case NC_PRIVKEY_FORMAT_RSA:
+    case NC_PRIVKEY_FORMAT_EC:
+    case NC_PRIVKEY_FORMAT_X509:
+        /* OpenSSL solely can do this */
+        ret = nc_server_config_new_get_privkey_openssl(privkey_path, f_privkey, &priv, pkey);
+        break;
+    case NC_PRIVKEY_FORMAT_OPENSSH:
+        /* need the help of libssh */
+        ret = nc_server_config_new_get_privkey_libssh(privkey_path, &priv, pkey);
+        /* if the function returned successfully, the key is no longer OpenSSH, it was converted to x509 */
+        *privkey_format = NC_PRIVKEY_FORMAT_X509;
+        break;
+    default:
+        ERR(NULL, "Private key format not recognized.");
         ret = 1;
-        goto cleanup;
+        break;
     }
     if (ret) {
         goto cleanup;
     }
 
-    if (pubkey_path) {
-        ret = nc_server_config_new_get_pubkey(pubkey_path, &pub, pubkey_type);
-    } else {
-        ret = nc_server_config_new_privkey_to_pubkey(priv_pkey, priv_sshkey, *privkey_type, &pub, pubkey_type);
-    }
-    if (ret) {
-        ERR(NULL, "Getting public key failed.");
-        goto cleanup;
-    }
-
-    /* strip pubkey's header and footer only if it's generated from pkcs8 key (using OpenSSL),
-     * otherwise it's already stripped
-     */
-    if (!pubkey_path && (*privkey_type == NC_PRIVKEY_FORMAT_X509)) {
-        *pubkey = strdup(pub + strlen(NC_SUBJECT_PUBKEY_INFO_HEADER));
-        if (!*pubkey) {
-            ERRMEM;
-            ret = 1;
-            goto cleanup;
-        }
-        (*pubkey)[strlen(*pubkey) - strlen(NC_SUBJECT_PUBKEY_INFO_FOOTER)] = '\0';
-    } else {
-        *pubkey = strdup(pub);
-        if (!*pubkey) {
-            ERRMEM;
-            ret = 1;
-            goto cleanup;
-        }
-    }
-
     /* strip private key's header and footer */
-    if (*privkey_type == NC_PRIVKEY_FORMAT_OPENSSH) {
-        /* only OpenSSH private keys have different header and footer after processing */
-        *privkey = strdup(priv + strlen(NC_OPENSSH_PRIVKEY_HEADER));
-        if (!*privkey) {
-            ERRMEM;
-            ret = 1;
-            goto cleanup;
-        }
-        (*privkey)[strlen(*privkey) - strlen(NC_OPENSSH_PRIVKEY_FOOTER)] = '\0';
-    } else {
-        /* the rest share the same header and footer */
-        *privkey = strdup(priv + strlen(NC_PKCS8_PRIVKEY_HEADER));
-        if (!*privkey) {
-            ERRMEM;
-            ret = 1;
-            goto cleanup;
-        }
-        (*privkey)[strlen(*privkey) - strlen(NC_PKCS8_PRIVKEY_FOOTER)] = '\0';
+    *privkey = strdup(priv + strlen(NC_PKCS8_PRIVKEY_HEADER));
+    if (!*privkey) {
+        ERRMEM;
+        ret = 1;
+        goto cleanup;
     }
+    (*privkey)[strlen(*privkey) - strlen(NC_PKCS8_PRIVKEY_FOOTER)] = '\0';
 
 cleanup:
     if (f_privkey) {
         fclose(f_privkey);
     }
 
-    free(header);
-    free(pub);
     free(priv);
+    return ret;
+}
 
-    ssh_key_free(priv_sshkey);
+int
+nc_server_config_new_get_asym_key_pair(const char *privkey_path, const char *pubkey_path, NC_PUBKEY_FORMAT wanted_pubkey_format,
+        char **privkey, NC_PRIVKEY_FORMAT *privkey_type, char **pubkey)
+{
+    int ret = 0;
+    EVP_PKEY *priv_pkey = NULL;
+
+    NC_CHECK_ARG_RET(NULL, privkey_path, privkey, privkey_type, pubkey, 1);
+
+    *privkey = NULL;
+    *pubkey = NULL;
+
+    /* get private key base64 and EVP_PKEY */
+    ret = nc_server_config_new_get_privkey(privkey_path, privkey_type, privkey, &priv_pkey);
+    if (ret) {
+        ERR(NULL, "Getting private key from file \"%s\" failed.", privkey_path);
+        goto cleanup;
+    }
+
+    /* get public key, either from file or generate it from the EVP_PKEY */
+    if (!pubkey_path) {
+        if (wanted_pubkey_format == NC_PUBKEY_FORMAT_SSH) {
+            ret = nc_server_config_new_evp_pkey_to_ssh_pubkey(priv_pkey, pubkey);
+        } else {
+            ret = nc_server_config_new_evp_pkey_to_spki_pubkey(priv_pkey, pubkey);
+        }
+    } else {
+        if (wanted_pubkey_format == NC_PUBKEY_FORMAT_SSH) {
+            ret = nc_server_config_new_get_ssh_pubkey_file(pubkey_path, pubkey);
+        } else {
+            ret = nc_server_config_new_get_spki_pubkey_file(pubkey_path, pubkey);
+        }
+    }
+    if (ret) {
+        if (pubkey_path) {
+            ERR(NULL, "Getting public key from file \"%s\" failed.", pubkey_path);
+        } else {
+            ERR(NULL, "Generating public key from private key failed.");
+        }
+        goto cleanup;
+    }
+
+cleanup:
     EVP_PKEY_free(priv_pkey);
-
     return ret;
 }
 
@@ -911,29 +1146,36 @@
 }
 
 API int
-nc_server_config_new_keystore_asym_key(const struct ly_ctx *ctx, const char *asym_key_name, const char *privkey_path,
-        const char *pubkey_path, struct lyd_node **config)
+nc_server_config_new_keystore_asym_key(const struct ly_ctx *ctx, NC_TRANSPORT_IMPL ti, const char *asym_key_name,
+        const char *privkey_path, const char *pubkey_path, struct lyd_node **config)
 {
     int ret = 0;
     char *privkey = NULL, *pubkey = NULL;
     NC_PRIVKEY_FORMAT privkey_type;
-    NC_PUBKEY_FORMAT pubkey_type;
     const char *privkey_format, *pubkey_format;
 
     NC_CHECK_ARG_RET(NULL, ctx, asym_key_name, privkey_path, config, 1);
 
     /* get the keys as a string from the given files */
-    ret = nc_server_config_new_get_keys(privkey_path, pubkey_path, &privkey, &pubkey, &privkey_type, &pubkey_type);
+    if (ti == NC_TI_LIBSSH) {
+        ret = nc_server_config_new_get_asym_key_pair(privkey_path, pubkey_path, NC_PUBKEY_FORMAT_SSH, &privkey, &privkey_type, &pubkey);
+    } else if (ti == NC_TI_OPENSSL) {
+        ret = nc_server_config_new_get_asym_key_pair(privkey_path, pubkey_path, NC_PUBKEY_FORMAT_X509, &privkey, &privkey_type, &pubkey);
+    } else {
+        ERR(NULL, "Only SSH and TLS transports can be used to create an asymmetric key pair in the keystore.");
+        ret = 1;
+        goto cleanup;
+    }
     if (ret) {
         ERR(NULL, "Getting keys from file(s) failed.");
         goto cleanup;
     }
 
     /* get pubkey format str */
-    if (pubkey_type == NC_PUBKEY_FORMAT_X509) {
-        pubkey_format = "ietf-crypto-types:public-key-info-format";
-    } else {
+    if (ti == NC_TI_LIBSSH) {
         pubkey_format = "ietf-crypto-types:ssh-public-key-format";
+    } else {
+        pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
     }
 
     /* get privkey identityref value */
@@ -1028,24 +1270,16 @@
 {
     int ret = 0;
     char *pubkey = NULL;
-    NC_PUBKEY_FORMAT pubkey_format;
-    const char *format;
+    const char *pubkey_format = "ietf-crypto-types:ssh-public-key-format";
 
     NC_CHECK_ARG_RET(NULL, ctx, pub_bag_name, pubkey_name, pubkey_path, config, 1);
 
-    ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_format);
+    ret = nc_server_config_new_get_ssh_pubkey_file(pubkey_path, &pubkey);
     if (ret) {
         goto cleanup;
     }
 
-    /* pubkey format to str */
-    if (pubkey_format == NC_PUBKEY_FORMAT_SSH2) {
-        format = "ietf-crypto-types:ssh-public-key-format";
-    } else {
-        format = "ietf-crypto-types:subject-public-key-info-format";
-    }
-
-    ret = nc_config_new_create(ctx, config, format, "/ietf-truststore:truststore/public-key-bags/"
+    ret = nc_config_new_create(ctx, config, pubkey_format, "/ietf-truststore:truststore/public-key-bags/"
             "public-key-bag[name='%s']/public-key[name='%s']/public-key-format", pub_bag_name, pubkey_name);
     if (ret) {
         goto cleanup;