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;
diff --git a/src/config_new.h b/src/config_new.h
index 76ae481..3b7401b 100644
--- a/src/config_new.h
+++ b/src/config_new.h
@@ -73,10 +73,10 @@
     NC_ALG_MAC
 } NC_ALG_TYPE;
 
-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);
+int nc_server_config_new_get_asym_key_pair(const char *privkey_path, const char *pubkey_path, NC_PUBKEY_FORMAT wanted_pubkey_type,
+        char **privkey, NC_PRIVKEY_FORMAT *privkey_type, char **pubkey);
 
-int nc_server_config_new_get_pubkey(const char *pubkey_path, char **pubkey, NC_PUBKEY_FORMAT *pubkey_type);
+int nc_server_config_new_get_ssh_pubkey_file(const char *pubkey_path, char **pubkey);
 
 int nc_server_config_new_read_certificate(const char *cert_path, char **cert);
 
diff --git a/src/config_new_ssh.c b/src/config_new_ssh.c
index 6c10e2f..db9670e 100644
--- a/src/config_new_ssh.c
+++ b/src/config_new_ssh.c
@@ -41,23 +41,15 @@
     int ret = 0;
     char *pubkey = NULL, *privkey = NULL;
     NC_PRIVKEY_FORMAT privkey_type;
-    NC_PUBKEY_FORMAT pubkey_type;
-    const char *privkey_format, *pubkey_format;
+    const char *privkey_format, *pubkey_format = "ietf-crypto-types:ssh-public-key-format";
 
     /* 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);
+    ret = nc_server_config_new_get_asym_key_pair(privkey_path, pubkey_path, NC_PUBKEY_FORMAT_SSH, &privkey, &privkey_type, &pubkey);
     if (ret) {
         ERR(NULL, "Getting keys from file(s) failed.");
         goto cleanup;
     }
 
-    /* pubkey format to str */
-    if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
-        pubkey_format = "ietf-crypto-types:ssh-public-key-format";
-    } else {
-        pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
-    }
-
     /* get privkey identityref value */
     privkey_format = nc_config_new_privkey_format_to_identityref(privkey_type);
     if (!privkey_format) {
@@ -372,22 +364,14 @@
 {
     int ret = 0;
     char *pubkey = NULL;
-    NC_PUBKEY_FORMAT pubkey_type;
-    const char *pubkey_format;
+    const char *pubkey_format = "ietf-crypto-types:ssh-public-key-format";
 
     /* get pubkey data */
-    ret = nc_server_config_new_get_pubkey(pubkey_path, &pubkey, &pubkey_type);
+    ret = nc_server_config_new_get_ssh_pubkey_file(pubkey_path, &pubkey);
     if (ret) {
         goto cleanup;
     }
 
-    /* get pubkey format */
-    if (pubkey_type == NC_PUBKEY_FORMAT_SSH2) {
-        pubkey_format = "ietf-crypto-types:ssh-public-key-format";
-    } else {
-        pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
-    }
-
     ret = nc_config_new_create_append(ctx, tree_path, "public-key-format", pubkey_format, config);
     if (ret) {
         goto cleanup;
diff --git a/src/config_new_tls.c b/src/config_new_tls.c
index 985f176..a094ec6 100644
--- a/src/config_new_tls.c
+++ b/src/config_new_tls.c
@@ -38,11 +38,10 @@
     int ret = 0;
     char *privkey = NULL, *pubkey = NULL, *cert = NULL;
     NC_PRIVKEY_FORMAT privkey_type;
-    NC_PUBKEY_FORMAT pubkey_type;
-    const char *privkey_format, *pubkey_format;
+    const char *privkey_format, *pubkey_format = "ietf-crypto-types:subject-public-key-info-format";
 
     /* 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);
+    ret = nc_server_config_new_get_asym_key_pair(privkey_path, pubkey_path, NC_PUBKEY_FORMAT_X509, &privkey, &privkey_type, &pubkey);
     if (ret) {
         ERR(NULL, "Getting keys from file(s) failed.");
         goto cleanup;
@@ -55,13 +54,6 @@
         goto cleanup;
     }
 
-    /* get pubkey format str */
-    if (pubkey_type == NC_PUBKEY_FORMAT_X509) {
-        pubkey_format = "ietf-crypto-types:public-key-info-format";
-    } else {
-        pubkey_format = "ietf-crypto-types:ssh-public-key-format";
-    }
-
     /* get privkey identityref value */
     privkey_format = nc_config_new_privkey_format_to_identityref(privkey_type);
     if (!privkey_format) {
diff --git a/src/server_config.c b/src/server_config.c
index 7ffaad8..b6f693e 100644
--- a/src/server_config.c
+++ b/src/server_config.c
@@ -26,6 +26,9 @@
 #include <libyang/libyang.h>
 
 #ifdef NC_ENABLED_SSH_TLS
+#include <openssl/err.h>
+#include <openssl/evp.h> // EVP_PKEY_free
+#include <openssl/x509.h> // d2i_PUBKEY
 #include <openssl/x509_vfy.h> // X509_STORE_free
 #endif
 
@@ -525,7 +528,7 @@
         return NC_PRIVKEY_FORMAT_RSA;
     } else if (!strcmp(format, "ec-private-key-format")) {
         return NC_PRIVKEY_FORMAT_EC;
-    } else if (!strcmp(format, "subject-private-key-info-format")) {
+    } else if (!strcmp(format, "private-key-info-format")) {
         return NC_PRIVKEY_FORMAT_X509;
     } else if (!strcmp(format, "openssh-private-key-format")) {
         return NC_PRIVKEY_FORMAT_OPENSSH;
@@ -2006,7 +2009,7 @@
 
     format = ((struct lyd_node_term *)node)->value.ident->name;
     if (!strcmp(format, "ssh-public-key-format")) {
-        pubkey_type = NC_PUBKEY_FORMAT_SSH2;
+        pubkey_type = NC_PUBKEY_FORMAT_SSH;
     } else if (!strcmp(format, "subject-public-key-info-format")) {
         pubkey_type = NC_PUBKEY_FORMAT_X509;
     } else {
@@ -2114,6 +2117,41 @@
 }
 
 static int
+nc_server_config_is_pk_subject_public_key_info(const char *b64)
+{
+    int ret = 0;
+    long len;
+    char *bin = NULL, *tmp;
+    EVP_PKEY *pkey = NULL;
+
+    /* base64 2 binary */
+    len = nc_base64_to_bin(b64, &bin);
+    if (len == -1) {
+        ERR(NULL, "Decoding base64 public key to binary failed.");
+        ret = -1;
+        goto cleanup;
+    }
+
+    /* for deallocation later */
+    tmp = bin;
+
+    /* try to create EVP_PKEY from the supposed SubjectPublicKeyInfo binary data */
+    pkey = d2i_PUBKEY(NULL, (const unsigned char **)&tmp, len);
+    if (pkey) {
+        /* success, it's most likely SubjectPublicKeyInfo pubkey */
+        ret = 1;
+    } else {
+        /* fail, it's most likely not SubjectPublicKeyInfo pubkey */
+        ret = 0;
+    }
+
+cleanup:
+    EVP_PKEY_free(pkey);
+    free(bin);
+    return ret;
+}
+
+static int
 nc_server_config_public_key(const struct lyd_node *node, NC_OPERATION op)
 {
     int ret = 0;
@@ -2137,6 +2175,13 @@
             goto cleanup;
         }
 
+        /* the public key must not be SubjectPublicKeyInfoFormat, as per the ietf-netconf-server model */
+        if (nc_server_config_is_pk_subject_public_key_info(lyd_get_value(node))) {
+            ERR(NULL, "Using Public Key in the SubjectPublicKeyInfo format as an SSH hostkey is forbidden!");
+            ret = 1;
+            goto cleanup;
+        }
+
         if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
             /* set to local */
             hostkey->store = NC_STORE_LOCAL;
@@ -2176,6 +2221,13 @@
             goto cleanup;
         }
 
+        /* the public key must not be SubjectPublicKeyInfoFormat, as per the ietf-netconf-server model */
+        if (nc_server_config_is_pk_subject_public_key_info(lyd_get_value(node))) {
+            ERR(NULL, "Using Public Key in the SubjectPublicKeyInfo format as an SSH user's key is forbidden!");
+            ret = 1;
+            goto cleanup;
+        }
+
         if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
             ret = nc_server_config_replace_auth_key_public_key_leaf(node, pubkey);
             if (ret) {
@@ -2191,6 +2243,13 @@
             goto cleanup;
         }
 
+        /* the public key must be SubjectPublicKeyInfoFormat, as per the ietf-netconf-server model */
+        if (!nc_server_config_is_pk_subject_public_key_info(lyd_get_value(node))) {
+            ERR(NULL, "TLS server certificate's Public Key must be in the SubjectPublicKeyInfo format!");
+            ret = 1;
+            goto cleanup;
+        }
+
         if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
             /* set to local */
             opts->store = NC_STORE_LOCAL;
@@ -2364,12 +2423,18 @@
     }
 
     if (i == ks->asym_key_count) {
-        ERR(NULL, "Keystore \"%s\" not found.", lyd_get_value(node));
+        ERR(NULL, "Keystore entry \"%s\" not found.", lyd_get_value(node));
         return 1;
     }
 
     hostkey->ks_ref = &ks->asym_keys[i];
 
+    /* check if the referenced public key is SubjectPublicKeyInfo */
+    if (nc_server_config_is_pk_subject_public_key_info(hostkey->ks_ref->pubkey_data)) {
+        ERR(NULL, "Using Public Key in the SubjectPublicKeyInfo format as an SSH hostkey is forbidden!");
+        return 1;
+    }
+
     return 0;
 }
 
@@ -2530,7 +2595,7 @@
 }
 
 static int
-nc_server_config_replace_truststore_reference(const struct lyd_node *node, struct nc_client_auth *client_auth)
+nc_server_config_ssh_replace_truststore_reference(const struct lyd_node *node, struct nc_client_auth *client_auth)
 {
     uint16_t i;
     struct nc_truststore *ts = &server_opts.truststore;
@@ -2549,6 +2614,14 @@
 
     client_auth->ts_ref = &ts->pub_bags[i];
 
+    /* check if any of the referenced public keys is SubjectPublicKeyInfo */
+    for (i = 0; i < client_auth->ts_ref->pubkey_count; i++) {
+        if (nc_server_config_is_pk_subject_public_key_info(client_auth->ts_ref->pubkeys[i].data)) {
+            ERR(NULL, "Using Public Key in the SubjectPublicKeyInfo format as an SSH user's key is forbidden!");
+            return 1;
+        }
+    }
+
     return 0;
 }
 
@@ -2601,7 +2674,7 @@
             /* set to truststore */
             auth_client->store = NC_STORE_TRUSTSTORE;
 
-            ret = nc_server_config_replace_truststore_reference(node, auth_client);
+            ret = nc_server_config_ssh_replace_truststore_reference(node, auth_client);
             if (ret) {
                 goto cleanup;
             }
diff --git a/src/server_config.h b/src/server_config.h
index ec48fb2..bf12757 100644
--- a/src/server_config.h
+++ b/src/server_config.h
@@ -138,6 +138,7 @@
  * @brief Creates new YANG data nodes for an asymmetric key in the keystore.
  *
  * @param[in] ctx libyang context.
+ * @param[in] ti Transport in which the key pair will be used. Either SSH or TLS.
  * @param[in] asym_key_name Identifier of the asymmetric key pair.
  * This identifier is used to reference the key pair.
  * @param[in] privkey_path Path to a private key file.
@@ -147,8 +148,8 @@
  * Otherwise the new YANG data will be added to the previous data and may override it.
  * @return 0 on success, non-zero otherwise.
  */
-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);
+int 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);
 
 /**
  * @brief Deletes a keystore's asymmetric key from the YANG data.
diff --git a/src/server_config_ks.c b/src/server_config_ks.c
index 9024334..b39f8d8 100644
--- a/src/server_config_ks.c
+++ b/src/server_config_ks.c
@@ -261,7 +261,7 @@
 
     format = ((struct lyd_node_term *)node)->value.ident->name;
     if (!strcmp(format, "ssh-public-key-format")) {
-        key->pubkey_type = NC_PUBKEY_FORMAT_SSH2;
+        key->pubkey_type = NC_PUBKEY_FORMAT_SSH;
     } else if (!strcmp(format, "subject-public-key-info-format")) {
         key->pubkey_type = NC_PUBKEY_FORMAT_X509;
     } else {
diff --git a/src/server_config_ts.c b/src/server_config_ts.c
index e32ef99..11fec83 100644
--- a/src/server_config_ts.c
+++ b/src/server_config_ts.c
@@ -544,7 +544,7 @@
 
     format = ((struct lyd_node_term *)node)->value.ident->name;
     if (!strcmp(format, "ssh-public-key-format")) {
-        pkey->type = NC_PUBKEY_FORMAT_SSH2;
+        pkey->type = NC_PUBKEY_FORMAT_SSH;
     } else if (!strcmp(format, "subject-public-key-info-format")) {
         pkey->type = NC_PUBKEY_FORMAT_X509;
     } else {
diff --git a/src/session.c b/src/session.c
index 3851a1d..ad96fc5 100644
--- a/src/session.c
+++ b/src/session.c
@@ -36,6 +36,7 @@
 #ifdef NC_ENABLED_SSH_TLS
 
 #include <libssh/libssh.h>
+#include <openssl/bio.h>
 #include <openssl/conf.h>
 #include <openssl/err.h>
 
@@ -120,6 +121,68 @@
     }
 }
 
+int
+nc_base64_to_bin(const char *base64, char **bin)
+{
+    BIO *bio, *bio64;
+    size_t used = 0, size = 0, r = 0;
+    void *tmp = NULL;
+    int nl_count, i, remainder;
+    char *b64;
+
+    /* insert new lines into the base64 string, so BIO_read works correctly */
+    nl_count = strlen(base64) / 64;
+    remainder = strlen(base64) - 64 * nl_count;
+    b64 = calloc(strlen(base64) + nl_count + 1, 1);
+    if (!b64) {
+        ERRMEM;
+        return -1;
+    }
+
+    for (i = 0; i < nl_count; i++) {
+        /* copy 64 bytes and add a NL */
+        strncpy(b64 + i * 65, base64 + i * 64, 64);
+        b64[i * 65 + 64] = '\n';
+    }
+
+    /* copy the rest */
+    strncpy(b64 + i * 65, base64 + i * 64, remainder);
+
+    bio64 = BIO_new(BIO_f_base64());
+    if (!bio64) {
+        ERR(NULL, "Error creating a bio (%s).", ERR_reason_error_string(ERR_get_error()));
+        return -1;
+    }
+
+    bio = BIO_new_mem_buf(b64, strlen(b64));
+    if (!bio) {
+        ERR(NULL, "Error creating a bio (%s).", ERR_reason_error_string(ERR_get_error()));
+        return -1;
+    }
+
+    BIO_push(bio64, bio);
+
+    /* store the decoded base64 in bin */
+    *bin = NULL;
+    do {
+        size += 64;
+
+        tmp = realloc(*bin, size);
+        if (!tmp) {
+            free(*bin);
+            return -1;
+        }
+        *bin = tmp;
+
+        r = BIO_read(bio64, *bin + used, 64);
+        used += r;
+    } while (r == 64);
+
+    free(b64);
+    BIO_free_all(bio64);
+    return size;
+}
+
 #endif /* NC_ENABLED_SSH_TLS */
 
 int
diff --git a/src/session_p.h b/src/session_p.h
index d6ca52d..1b12733 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -63,8 +63,8 @@
  * Enumeration of SSH public key formats.
  */
 typedef enum {
-    NC_PUBKEY_FORMAT_SSH2, /**< begins with BEGIN SSH2 PUBLICKEY, see RFC 4716 */
-    NC_PUBKEY_FORMAT_X509 /**< begins with BEGIN PUBLICKEY, see RFC 5280 sec. 4.1.2.7 */
+    NC_PUBKEY_FORMAT_SSH, /**< see RFC 4253, section 6.6 */
+    NC_PUBKEY_FORMAT_X509 /**< see RFC 5280 sec. 4.1.2.7 */
 } NC_PUBKEY_FORMAT;
 
 /**
@@ -745,6 +745,15 @@
  */
 const char *nc_privkey_format_to_str(NC_PRIVKEY_FORMAT format);
 
+/**
+ * @brief Decodes base64 to binary.
+ *
+ * @param[in] base64 Base64 string.
+ * @param[out] bin Binary result, memory managed by the caller.
+ * @return Length of the binary data on success, -1 on error.
+ */
+int nc_base64_to_bin(const char *base64, char **bin);
+
 #endif /* NC_ENABLED_SSH_TLS */
 
 void *nc_realloc(void *ptr, size_t size);