@@ -794,42 +794,37 @@ nc_server_config_util_get_privkey_format(const char *privkey, enum nc_privkey_fo
794794 return 0 ;
795795}
796796
797+ /**
798+ * @brief Get private key using the TLS backend's functions.
799+ *
800+ * @param[in] privkey_path Path to the private key file.
801+ * @param[out] pkey TLS backend's underlying private key structure.
802+ * @return 0 on success, 1 on failure.
803+ */
797804static int
798- nc_server_config_util_get_privkey_libtls (const char * privkey_path , char * * privkey , void * * pkey )
805+ nc_server_config_util_get_privkey_libtls (const char * privkey_path , void * * pkey )
799806{
800- void * pkey_tmp ;
801- char * privkey_tmp ;
802-
803- NC_CHECK_ARG_RET (NULL , privkey_path , privkey , pkey , 1 );
804-
805- * privkey = * pkey = NULL ;
806-
807- pkey_tmp = nc_tls_import_privkey_file_wrap (privkey_path );
808- if (!pkey_tmp ) {
809- return 1 ;
810- }
811-
812- privkey_tmp = nc_tls_export_privkey_pem_wrap (pkey_tmp );
813- if (!privkey_tmp ) {
814- nc_tls_privkey_destroy_wrap (pkey_tmp );
815- return 1 ;
816- }
807+ * pkey = NULL ;
817808
818- * privkey = privkey_tmp ;
819- * pkey = pkey_tmp ;
820- return 0 ;
809+ * pkey = nc_tls_import_privkey_file_wrap (privkey_path );
810+ return * pkey ? 0 : 1 ;
821811}
822812
813+ /**
814+ * @brief Get private key using libssh functions.
815+ *
816+ * @param[in] privkey_path Path to the private key file.
817+ * @param[out] pkey TLS backend's underlying private key structure.
818+ * @return 0 on success, 1 on failure.
819+ */
823820static int
824- nc_server_config_util_get_privkey_libssh (const char * privkey_path , char * * privkey , void * * pkey )
821+ nc_server_config_util_get_privkey_libssh (const char * privkey_path , void * * pkey )
825822{
826823 int ret = 0 ;
827824 ssh_key key = NULL ;
828- void * pkey_tmp = NULL ;
829- char * privkey_tmp = NULL ;
830-
831- NC_CHECK_ARG_RET (NULL , privkey_path , privkey , pkey , 1 );
825+ char * privkey_buf = NULL ;
832826
827+ /* import the OpenSSH private key using libssh */
833828 ret = ssh_pki_import_privkey_file (privkey_path , NULL , NULL , NULL , & key );
834829 if (ret ) {
835830 ERR (NULL , "Importing privkey from file \"%s\" failed." , privkey_path );
@@ -838,45 +833,43 @@ nc_server_config_util_get_privkey_libssh(const char *privkey_path, char **privke
838833 }
839834
840835 /* export the key in PEM */
841- ret = ssh_pki_export_privkey_base64 (key , NULL , NULL , NULL , & privkey_tmp );
836+ ret = ssh_pki_export_privkey_base64 (key , NULL , NULL , NULL , & privkey_buf );
842837 if (ret ) {
843838 ERR (NULL , "Exporting privkey to base64 failed." );
844839 goto cleanup ;
845840 }
846841
847- pkey_tmp = nc_tls_pem_to_privkey_wrap ( privkey_tmp );
848- if (! pkey_tmp ) {
849- free ( privkey_tmp );
842+ /* convert the base64 PEM to libtls private key representation */
843+ * pkey = nc_tls_pem_to_privkey_wrap ( privkey_buf );
844+ if (! * pkey ) {
850845 ret = 1 ;
851846 goto cleanup ;
852847 }
853848
854- * privkey = privkey_tmp ;
855- * pkey = pkey_tmp ;
856-
857849cleanup :
850+ free (privkey_buf );
858851 ssh_key_free (key );
859852 return ret ;
860853}
861854
862855static int
863- nc_server_config_util_pem_strip_header_footer (const char * pem , char * * privkey )
856+ nc_server_config_util_privkey_strip_header_footer (const char * orig_privkey , char * * privkey )
864857{
865858 const char * header , * footer ;
866859
867- if (!strncmp (pem , NC_PKCS8_PRIVKEY_HEADER , strlen (NC_PKCS8_PRIVKEY_HEADER ))) {
860+ if (!strncmp (orig_privkey , NC_PKCS8_PRIVKEY_HEADER , strlen (NC_PKCS8_PRIVKEY_HEADER ))) {
868861 /* it's PKCS8 (X.509) private key */
869862 header = NC_PKCS8_PRIVKEY_HEADER ;
870863 footer = NC_PKCS8_PRIVKEY_FOOTER ;
871- } else if (!strncmp (pem , NC_OPENSSH_PRIVKEY_HEADER , strlen (NC_OPENSSH_PRIVKEY_HEADER ))) {
864+ } else if (!strncmp (orig_privkey , NC_OPENSSH_PRIVKEY_HEADER , strlen (NC_OPENSSH_PRIVKEY_HEADER ))) {
872865 /* it's OpenSSH private key */
873866 header = NC_OPENSSH_PRIVKEY_HEADER ;
874867 footer = NC_OPENSSH_PRIVKEY_FOOTER ;
875- } else if (!strncmp (pem , NC_PKCS1_RSA_PRIVKEY_HEADER , strlen (NC_PKCS1_RSA_PRIVKEY_HEADER ))) {
868+ } else if (!strncmp (orig_privkey , NC_PKCS1_RSA_PRIVKEY_HEADER , strlen (NC_PKCS1_RSA_PRIVKEY_HEADER ))) {
876869 /* it's RSA privkey in PKCS1 format */
877870 header = NC_PKCS1_RSA_PRIVKEY_HEADER ;
878871 footer = NC_PKCS1_RSA_PRIVKEY_FOOTER ;
879- } else if (!strncmp (pem , NC_SEC1_EC_PRIVKEY_HEADER , strlen (NC_SEC1_EC_PRIVKEY_HEADER ))) {
872+ } else if (!strncmp (orig_privkey , NC_SEC1_EC_PRIVKEY_HEADER , strlen (NC_SEC1_EC_PRIVKEY_HEADER ))) {
880873 /* it's EC privkey in SEC1 format */
881874 header = NC_SEC1_EC_PRIVKEY_HEADER ;
882875 footer = NC_SEC1_EC_PRIVKEY_FOOTER ;
@@ -885,7 +878,7 @@ nc_server_config_util_pem_strip_header_footer(const char *pem, char **privkey)
885878 }
886879
887880 /* make a copy without the header and footer */
888- * privkey = strndup (pem + strlen (header ), strlen (pem ) - strlen (header ) - strlen (footer ));
881+ * privkey = strndup (orig_privkey + strlen (header ), strlen (orig_privkey ) - strlen (header ) - strlen (footer ));
889882 NC_CHECK_ERRMEM_RET (!* privkey , 1 );
890883
891884 return 0 ;
@@ -930,13 +923,11 @@ nc_server_config_util_get_privkey(const char *privkey_path, enum nc_privkey_form
930923 case NC_PRIVKEY_FORMAT_EC :
931924 case NC_PRIVKEY_FORMAT_X509 :
932925 /* the TLS lib can do this */
933- ret = nc_server_config_util_get_privkey_libtls (privkey_path , & priv , pkey );
926+ ret = nc_server_config_util_get_privkey_libtls (privkey_path , pkey );
934927 break ;
935928 case NC_PRIVKEY_FORMAT_OPENSSH :
936929 /* need the help of libssh */
937- ret = nc_server_config_util_get_privkey_libssh (privkey_path , & priv , pkey );
938- /* if the function returned successfully, the key is no longer OpenSSH, it was converted to x509 */
939- * privkey_format = NC_PRIVKEY_FORMAT_X509 ;
930+ ret = nc_server_config_util_get_privkey_libssh (privkey_path , pkey );
940931 break ;
941932 default :
942933 ERR (NULL , "Private key format not recognized." );
@@ -947,17 +938,26 @@ nc_server_config_util_get_privkey(const char *privkey_path, enum nc_privkey_form
947938 goto cleanup ;
948939 }
949940
950- /* parsing may have changed its type, get it again */
941+ /* export the private key to its original format type,
942+ * all of this was done to avoid having to parse the private key ourselves
943+ * and since we have a "pkey" we can be sure, that the private key is valid */
944+ ret = nc_tls_privkey_export_wrap (* pkey , * privkey_format , & priv );
945+ if (ret ) {
946+ goto cleanup ;
947+ }
948+
949+ /* get the privkey format again from the exported private key,
950+ * it should match the previous one, but in case it doesn't,
951+ * we can still at least store the 'current' one in YANG and use it */
951952 ret = nc_server_config_util_get_privkey_format (priv , privkey_format );
952953 if (ret ) {
953- ERR (NULL , "Getting private key format from file \"%s\" failed ." , privkey_path );
954+ ERR (NULL , "Private key format \"%s\" not supported ." , priv );
954955 goto cleanup ;
955956 }
956957
957958 /* strip private key's header and footer */
958- ret = nc_server_config_util_pem_strip_header_footer (priv , privkey );
959+ ret = nc_server_config_util_privkey_strip_header_footer (priv , privkey );
959960 if (ret ) {
960- ERR (NULL , "Stripping header and footer from private key \"%s\" failed." , privkey_path );
961961 goto cleanup ;
962962 }
963963
0 commit comments