File libpki-0.8.9.patch of Package libpki-0.8.9

diff -ur libpki-0.8.9-orig/acinclude.m4 libpki-0.8.9/acinclude.m4
--- libpki-0.8.9-orig/acinclude.m4	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/acinclude.m4	2023-07-14 16:39:36.288164737 +0200
@@ -115,7 +115,7 @@
 
 
 		AC_MSG_RESULT([Searching OpenSSL Version: $library_includes]);
-		ver=`grep "#define SHLIB_VERSION_NUMBER" $library_includes | sed 's/[#_a-zA-Z" ]//g' | sed 's|\.|0|g'`;
+		ver=`grep "#.*define SHLIB_VERSION_NUMBER" $library_includes | sed 's/[#_a-zA-Z" ]//g' | sed 's|\.|0|g'`;
 		my_ver=`echo $_version | sed "s|\.|0|g"`;
 
 		AC_MSG_RESULT([Detected Version: $ver (required > $my_ver )]);
diff -ur libpki-0.8.9-orig/configure libpki-0.8.9/configure
--- libpki-0.8.9-orig/configure	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/configure	2023-07-14 16:39:36.296164737 +0200
@@ -3556,7 +3556,7 @@
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
+    CFLAGS="-g"
   else
     CFLAGS="-g"
   fi
@@ -12132,7 +12132,7 @@
 if [ -f "/etc/issue" ] ; then
    DIST_NAME=`head -n 1 /etc/issue | cut -f 1,1 -d ' '`
 else
-   DIST_NAME=`echo ${build_os} | $EGREP -o [A-Za-z]+`
+   DIST_NAME=`echo ${build_os} | $EGREP -o [A-Za-z]+ | head -n 1`
 fi
 
 
@@ -16253,7 +16253,7 @@
 
 		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Searching OpenSSL Version: $library_includes" >&5
 $as_echo "Searching OpenSSL Version: $library_includes" >&6; };
-		ver=`grep "#define SHLIB_VERSION_NUMBER" $library_includes | sed 's/[#_a-zA-Z" ]//g' | sed 's|\.|0|g'`;
+		ver=`grep "#.*define SHLIB_VERSION_NUMBER" $library_includes | sed 's/[#_a-zA-Z" ]//g' | sed 's|\.|0|g'`;
 		my_ver=`echo $_version | sed "s|\.|0|g"`;
 
 		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Detected Version: $ver (required > $my_ver )" >&5
@@ -16789,7 +16789,7 @@
     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Removing duplicate entries for -L${dir}${mybits_install} from libpki_ldflags" >&5
 $as_echo "Removing duplicate entries for -L${dir}${mybits_install} from libpki_ldflags" >&6; }
       libpki_ldflags=`echo $libpki_ldflags | sed -e "s|-L${dir}${mybits_install} ||g"`
-      libpki_ldflags="-L${dir}${mybits_install} $libpki_ldflags"
+      libpki_ldflags="$libpki_ldflags -L${dir}${mybits_install}"
     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Removed duplicate entries for -L$dir${mybits_install} from libpki_ldflags" >&5
 $as_echo "Removed duplicate entries for -L$dir${mybits_install} from libpki_ldflags" >&6; }
     fi
@@ -16858,7 +16858,7 @@
     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Removing duplicate entries for -L${dir}${mybits_install} from my_ldflags" >&5
 $as_echo "Removing duplicate entries for -L${dir}${mybits_install} from my_ldflags" >&6; }
       my_ldflags=`echo $my_ldflags | sed -e "s|-L${dir}${mybits_install} ||g"`
-      my_ldflags="-L${dir}${mybits_install} $my_ldflags"
+      my_ldflags="$my_ldflags -L${dir}${mybits_install}"
     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Removed duplicate entries for -L${dir}${mybits_install} from my_ldflags" >&5
 $as_echo "Removed duplicate entries for -L${dir}${mybits_install} from my_ldflags" >&6; }
     fi
diff -ur libpki-0.8.9-orig/src/drivers/engine/engine_hsm.c libpki-0.8.9/src/drivers/engine/engine_hsm.c
--- libpki-0.8.9-orig/src/drivers/engine/engine_hsm.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/engine/engine_hsm.c	2023-07-14 16:39:36.316164738 +0200
@@ -45,7 +45,7 @@
 		/* Key Unwrap */
 		NULL,
 		/* Object stack Get Function */
-		NULL, // HSM_ENGINE_OBJSK_get_url,
+		HSM_ENGINE_OBJSK_get_url,
 		/* Object stack Add Function */
 		NULL, /* HSM_ENGINE_KEYPAIR_put_url, */
 		/* Object stack Del Function */
@@ -60,8 +60,8 @@
 		NULL, /* HSM_ENGINE_SLOT_select */
 		/* Cleans up the current slot */
 		NULL, /* HSM_ENGINE_SLOT_clean */
-		/* Returns the Callbacks */
-		NULL /* HSM_OPENSSL_X509_get_cb */
+		/* Gets X509 Callbacks */
+		HSM_OPENSSL_X509_get_cb
 };
 
 /* Structure for PKI_TOKEN definition */
@@ -211,6 +211,7 @@
 
 	/* Let's copy the right callbacks to call when needed! */
 	hsm->callbacks = &engine_hsm_callbacks;
+	hsm->config = conf;
 
 	/* Let's get the ID for the HSM */
 	if((engine_id = PKI_CONFIG_get_value( conf, "/hsm/id" )) == NULL ) {
@@ -244,14 +245,14 @@
 	return( hsm );
 }
 
-int HSM_ENGINE_free ( HSM *driver, PKI_CONFIG *conf ) {
+int HSM_ENGINE_free ( HSM *hsm, PKI_CONFIG *conf ) {
 
-	if( driver == NULL ) return (PKI_OK);
+	if( hsm == NULL ) return (PKI_OK);
 
 	return (PKI_ERR);
 }
 
-int HSM_ENGINE_init( HSM *driver, PKI_CONFIG *conf ) {
+int HSM_ENGINE_init( HSM *hsm, PKI_CONFIG *conf ) {
 
 	/* We need to initialize the driver by using the config
 	   options. For the ENGINE, we do not need the driver
@@ -264,12 +265,12 @@
 	PKI_STACK *pre_cmds = NULL;
 	PKI_STACK *post_cmds = NULL;
 
-	if( !driver ) return ( PKI_ERR );
+	if( !hsm ) return ( PKI_ERR );
 
        	PKI_log_debug("INFO, Initialising HSM [%s]", 
 		PKI_CONFIG_get_value(conf, "/hsm/name"));
 
-	e = (ENGINE *) driver;
+	e = (ENGINE *) hsm;
 
 	if( !conf ) {
 		PKI_log_debug("WARNING, no PRECMDS provided (?!?!?)");
diff -ur libpki-0.8.9-orig/src/drivers/engine/engine_hsm_obj.c libpki-0.8.9/src/drivers/engine/engine_hsm_obj.c
--- libpki-0.8.9-orig/src/drivers/engine/engine_hsm_obj.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/engine/engine_hsm_obj.c	2023-07-14 16:39:36.316164738 +0200
@@ -4,7 +4,6 @@
 
 /* ---------------- OpenSSL HSM Keypair get/put --------------------------- */
 
-/*
 PKI_STACK * HSM_ENGINE_OBJSK_get_url ( PKI_DATATYPE type, URL *url, 
 					PKI_CRED *cred, struct hsm_st *hsm ) {
 
@@ -14,32 +13,27 @@
 
 	switch ( type ) {
 		case PKI_DATATYPE_X509_KEYPAIR:
-			ret = HSM_ENGINE_KEYPAIR_get_url ( url, cred, hsm );
+			ret = (void *) HSM_ENGINE_KEYPAIR_get_url ( url, cred, hsm );
 			break;
 		default:
-			HSM_OPENSSL_OBJSK_get_url ( type, url, cred, hsm );
+			//HSM_OPENSSL_OBJSK_get_url ( type, url, cred, hsm );
 			ret = NULL;
 	}
 
 	return ( ret );
 }
 
-*/
 /* ------------------------ Internal Retrieve Functions ------------------- */
 
-/*
-PKI_X509_KEYPAIR_STACK * HSM_ENGINE_KEYPAIR_get_url ( URL *url, PKI_CRED *cred, 
-							HSM *driver ) {
-	HSM *hsm = NULL;
-	PKI_X509_KEYPAIR_STACK *ret = NULL;
-	PKI_X509_KEYPAIR *keypair = NULL;
+PKI_X509_STACK * HSM_ENGINE_KEYPAIR_get_url ( URL *url, PKI_CRED *cred, 
+							HSM *hsm ) {
+
+	PKI_X509_KEYPAIR *ret = NULL;
+	PKI_X509_KEYPAIR_STACK *ret_sk = NULL;
+
 	PW_CB_DATA cb_data;
 	ENGINE *e = NULL;
 
-	if((hsm = (HSM *) driver) == NULL ) {
-		PKI_log_debug("ERROR, Memory Allocation", __FILE__, __LINE__);
-		return(NULL);
-	}
 
 	if( hsm->driver == NULL ) {
 		PKI_log_debug("ERROR, No HSM pointer provided (keypair get"
@@ -56,25 +50,27 @@
 	}
 
 	if( url ) {
-        	cb_data.prompt_info = url->addr;
+		cb_data.prompt_info = url->addr;
 	}
 
-	if((ret = PKI_STACK_X509_KEYPAIR_new()) == NULL ) {
-		PKI_log_debug("ERROR, can not allocate new memory!");
+	if((ret = PKI_X509_new ( PKI_DATATYPE_X509_KEYPAIR, hsm))== NULL ) {
+		return (NULL);
+	}
+
+	if((ret->value = (PKI_X509_KEYPAIR_VALUE *) ENGINE_load_private_key(e, 
+		url->addr, NULL, &cb_data)) == NULL ) {
+		PKI_log_debug("ERROR, Error loading key (%s) [ENGINE HSM]", url->addr );
 		return ( NULL );
 	}
 
-        if((keypair = (PKI_X509_KEYPAIR *) ENGINE_load_private_key(e, 
-				url->addr, NULL, &cb_data)) == NULL ) {
-		PKI_log_debug("ERROR, Error loading key (%s) [ENGINE HSM]",
-							url->addr );
-		if ( ret ) PKI_STACK_X509_KEYPAIR_free ( ret );
+	if((ret_sk = PKI_STACK_X509_KEYPAIR_new()) == NULL ) {
+		PKI_log_debug("PKI_STACK_X509_KEYPAIR_new() failed");
+		if ( ret ) PKI_X509_KEYPAIR_free ( ret );
 		return ( NULL );
 	}
 
-	PKI_STACK_X509_KEYPAIR_push ( ret, keypair );
+	PKI_STACK_X509_KEYPAIR_push ( ret_sk, ret );
 
-	return ( ret );
+	return ( ret_sk );
 }
 
-*/
diff -ur libpki-0.8.9-orig/src/drivers/engine/engine_hsm_pkey.c libpki-0.8.9/src/drivers/engine/engine_hsm_pkey.c
--- libpki-0.8.9-orig/src/drivers/engine/engine_hsm_pkey.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/engine/engine_hsm_pkey.c	2023-07-14 16:39:36.316164738 +0200
@@ -119,7 +119,7 @@
 
 
 PKI_X509_KEYPAIR *HSM_ENGINE_X509_KEYPAIR_new( PKI_KEYPARAMS *kp, 
-				URL *url, PKI_CRED *cred, HSM *driver ) {
+				URL *url, PKI_CRED *cred, HSM *hsm ) {
 
 	PKI_X509_KEYPAIR *ret = NULL;
 	PKI_X509_KEYPAIR_VALUE *val = NULL;
@@ -139,7 +139,7 @@
 		return NULL;
 	}
 
-	e = (ENGINE *) driver;
+	e = (ENGINE *) hsm;
 	if( _engine_pki_rand_seed() == 0 ) {
 		/* Probably low level of randomization available */
 		PKI_log_debug("WARNING, low rand available (ENGINE HSM)");
@@ -201,7 +201,7 @@
 			return NULL;
 	}
 
-	if((ret = PKI_X509_new( PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL ) {
+	if((ret = PKI_X509_new( PKI_DATATYPE_X509_KEYPAIR, hsm)) == NULL ) {
 		if( val ) EVP_PKEY_free ( val );
 		return NULL;
 	}
diff -ur libpki-0.8.9-orig/src/drivers/hsm_keypair.c libpki-0.8.9/src/drivers/hsm_keypair.c
--- libpki-0.8.9-orig/src/drivers/hsm_keypair.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/hsm_keypair.c	2023-07-14 16:39:36.316164738 +0200
@@ -34,7 +34,7 @@
 }
 
 PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new_url( PKI_KEYPARAMS *params,
-			URL *url, PKI_CRED *cred, HSM *driver ) {
+			URL *url, PKI_CRED *cred, HSM *hsm_in ) {
 
 	PKI_X509_KEYPAIR *ret = NULL;
 	HSM *hsm = NULL;
@@ -44,8 +44,8 @@
 		return NULL;
 	};
 
-	if( driver ) {
-		hsm = driver;
+	if( hsm_in ) {
+		hsm = hsm_in;
 	} else {
 		hsm = (HSM *) HSM_get_default();
 		// PKI_log_debug("Getting Default HSM (%p/%p)", hsm, &openssl_hsm );
diff -ur libpki-0.8.9-orig/src/drivers/hsm_main.c libpki-0.8.9/src/drivers/hsm_main.c
--- libpki-0.8.9-orig/src/drivers/hsm_main.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/hsm_main.c	2023-07-14 16:39:36.316164738 +0200
@@ -100,7 +100,6 @@
 
 	HSM *hsm = NULL;
 	char * url_s = NULL;
-	char * buff = NULL;
 
 	PKI_CONFIG *conf = NULL;
 	char *type = NULL;
@@ -120,26 +119,26 @@
 
 	if((conf = PKI_CONFIG_load( url_s )) == NULL ) {
 		PKI_log_debug( "Can not load config from %s", url_s );
-		return(NULL);
+		goto ret;
 	}
 
-	if((buff = PKI_Malloc ( BUFF_MAX_SIZE )) == NULL ) {
-		return(NULL);
-	}
 
 	/* Let's generate the right searching string with the namespace
 	   prefix */
 	if((type = PKI_CONFIG_get_value ( conf, "/hsm/type")) == NULL ) {
 		/* No type in the config! */
-		PKI_log_debug("ERROR, No HSM type in the config!");
-		// PKI_CONFIG_free ( conf );
-		// return (NULL);
-		type = "software";
+		PKI_log_debug("ERROR, No HSM type in the config - defaults to software!");
+		if( (type = strdup("software")) == NULL)
+		{
+			PKI_log_err ("Memory Error");
+			goto ret;
+		}
 	}
 
 	if( strcmp_nocase(type,"software") == 0 ) {
 		if((hsm = HSM_OPENSSL_new( conf )) == NULL ) {
 			PKI_log_debug("ERROR, Can not generate software HSM object!");
+			goto ret;
 		} else {
 			hsm->type = HSM_TYPE_SOFTWARE;
 		}
@@ -147,6 +146,7 @@
 	} else if( strcmp_nocase(type,"engine") == 0 ) {
 		if((hsm = HSM_ENGINE_new( conf )) == NULL ) {
 			PKI_log_debug("ERROR, Can not generate engine HSM object!");
+			goto ret;
 		} else {
 			hsm->type = HSM_TYPE_ENGINE;
 		}
@@ -154,6 +154,7 @@
 	} else if( strcmp_nocase(type,"pkcs11") == 0 ) {
 		if((hsm = HSM_PKCS11_new( conf )) == NULL ) {
 			PKI_log_debug("ERROR, Can not generate engine HSM object!");
+			goto ret;
 		} else {
 			hsm->type = HSM_TYPE_PKCS11;
 		}
@@ -161,20 +162,14 @@
 	} else if( strcmp_nocase(type,"kmf") == 0 ) {
 		if((hsm = HSM_KMF_new( conf )) == NULL ) {
 			PKI_log_debug("ERROR, Can not generate kmf HSM object!\n");
+			goto ret;
 		} else {
 			hsm->type = HSM_TYPE_KMF;
 		}
 #endif
 	} else {
 		PKI_log_debug( "Unknown HSM type (%s)", type );
-		PKI_CONFIG_free ( conf );
-		return (NULL);
-	}
-
-	if ( ( hsm != NULL ) && (HSM_init ( hsm ) != PKI_OK) )
-	{
-			HSM_free ( hsm );
-			return NULL;
+		goto ret;
 	}
 
 	// Let' see if we can enforce the FIPS mode (optional, therefore
@@ -189,7 +184,8 @@
 			{
 				PKI_log_err("Can not create HSM in FIPS mode");
 				HSM_free(hsm);
-				return NULL;
+				hsm = NULL;
+				goto ret;
 			}
 	}
 	else
@@ -197,6 +193,11 @@
 		PKI_log_debug("HSM created in non-FIPS mode");
 	}
 
+ret:
+	if (conf) PKI_CONFIG_free ( conf );
+	if (url_s) PKI_Free ( url_s );
+	if (type) PKI_Free(type);
+
 	return (hsm);
 }
 
@@ -262,9 +263,10 @@
 	if( !hsm || !hsm->callbacks ) return (PKI_ERR);
 
 	/* Call the init function provided by the hsm itself */
+	PKI_log_debug("Init called for (%s)", hsm->description);
 	if( hsm->callbacks->init )
 	{
-		return (hsm->callbacks->init ( hsm->driver, hsm->config ));
+		return (hsm->callbacks->init ( hsm, hsm->config ));
 	}
 	else
 	{
@@ -298,7 +300,7 @@
 	if (!hsm) return (PKI_ERR);
 
 	if ( hsm->callbacks->login ) {
-		return ( hsm->callbacks->login( hsm->driver, cred ));
+		return ( hsm->callbacks->login( hsm, cred ));
 	} else {
 		/* No login required by the HSM */
 		PKI_log_debug("No login function for selected HSM");
@@ -312,7 +314,7 @@
 	if (!hsm || !hsm->callbacks ) return (PKI_ERR);
 
 	if ( hsm->callbacks && hsm->callbacks->logout ) {
-		return ( hsm->callbacks->logout( hsm->driver ));
+		return ( hsm->callbacks->logout( hsm ));
 	} else {
 		/* No login required by the HSM */
 		PKI_log_debug("No login function for selected HSM");
@@ -637,6 +639,8 @@
 	// Uses the default algorithm if none was provided
 	if ( !alg ) alg = PKI_DIGEST_ALG_DEFAULT;
 
+	hsm = key->hsm;
+
 	// If no HSM is provided, let's get the default one
 	if (!(hsm && hsm->callbacks && hsm->callbacks->sign))
 		hsm = (HSM *) HSM_get_default();
@@ -694,6 +698,7 @@
 
 	PKI_STRING *sig_value = NULL;
 	PKI_ALGOR *alg = NULL;
+	PKI_ALGOR_ID alg_id = 0;
 
 	PKI_init_all();
 
@@ -740,7 +745,34 @@
 
 	// PKI_log_debug(">>> GOT SIG [%p - size=%d]", sig, sig->size );
 
-	if (hsm && hsm->callbacks && hsm->callbacks->verify)
+	if( (alg_id = PKI_ALGOR_get_id(alg)) == PKI_ALGOR_UNKNOWN)
+	{
+		PKI_log_err("Can not get Signature algorithm!");
+		PKI_MEM_free ( sig );
+		PKI_MEM_free ( data );
+		return PKI_ERR;
+	}
+
+	/* For PSS we need special handling.
+	   For verification we use directly the existing OpenSSL functions */
+	if(alg_id == PKI_ALGOR_RSA_PSS)
+	{
+		switch(x->type)
+		{
+			case PKI_DATATYPE_X509_CRL:
+				if(!X509_CRL_verify((X509_CRL *)x->value, (EVP_PKEY *)key->value))
+				{
+					PKI_log_err("X509_CRL_verify() failed");
+				}
+				else
+					ret = PKI_OK;
+				break;
+			default:
+				PKI_log_err("PKI datatype not supported for PSS signature (id = %d)", x->type);
+				break;
+		}
+	}
+	else if (hsm && hsm->callbacks && hsm->callbacks->verify)
 	{
 		PKI_log_debug( "HSM verify() callback called " );
 		ret = hsm->callbacks->verify( data, sig, alg, key ); 
diff -ur libpki-0.8.9-orig/src/drivers/openssl/openssl_hsm.c libpki-0.8.9/src/drivers/openssl/openssl_hsm.c
--- libpki-0.8.9-orig/src/drivers/openssl/openssl_hsm.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/openssl/openssl_hsm.c	2023-07-14 16:39:36.320164738 +0200
@@ -214,21 +214,21 @@
 	return( hsm );
 }
 
-int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf ) {
+int HSM_OPENSSL_free ( HSM *hsm, PKI_CONFIG *conf ) {
 
-	if( driver == NULL ) return (PKI_OK);
+	if( hsm == NULL ) return (PKI_OK);
 
 	return (PKI_ERR);
 }
 
-int HSM_OPENSSL_init( HSM *driver, PKI_CONFIG *conf ) {
+int HSM_OPENSSL_init( HSM *hsm, PKI_CONFIG *conf ) {
 
-	if( driver == NULL ) return (PKI_ERR);
+	if( hsm == NULL ) return (PKI_ERR);
 
 	/* Checks the FIPS mode */
 	if (PKI_is_fips_mode() == PKI_OK)
 	{
-		if (HSM_OPENSSL_set_fips_mode(driver, 1) == PKI_ERR)
+		if (HSM_OPENSSL_set_fips_mode(hsm, 1) == PKI_ERR)
 			return PKI_ERR;
 	}
 
@@ -240,7 +240,7 @@
  * \brief Sets the fips operation mode when the parameter is != 0,
  * otherwise it sets the HSM in non-fips mode
  */
-int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k)
+int HSM_OPENSSL_set_fips_mode(const HSM *hsm, int k)
 {
 #ifdef OPENSSL_FIPS
 	return FIPS_mode_set(k);
@@ -253,7 +253,7 @@
  * \brief Returns 0 if HSM is operating in non-FIPS mode, true (!0) if FIPS
  * mode is enabled.
  */
-int HSM_OPENSSL_is_fips_mode(const HSM *driver)
+int HSM_OPENSSL_is_fips_mode(const HSM *hsm)
 {
 #ifdef OPENSSL_FIPS
 	return FIPS_mode();
diff -ur libpki-0.8.9-orig/src/drivers/openssl/openssl_hsm_pkey.c libpki-0.8.9/src/drivers/openssl/openssl_hsm_pkey.c
--- libpki-0.8.9-orig/src/drivers/openssl/openssl_hsm_pkey.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/openssl/openssl_hsm_pkey.c	2023-07-14 16:39:36.320164738 +0200
@@ -294,7 +294,7 @@
 
 
 PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new( PKI_KEYPARAMS *kp, 
-		URL *url, PKI_CRED *cred, HSM *driver ) {
+		URL *url, PKI_CRED *cred, HSM *hsm ) {
 
 	PKI_X509_KEYPAIR *ret = NULL;
 	PKI_RSA_KEY *rsa = NULL;
diff -ur libpki-0.8.9-orig/src/drivers/pkcs11/pkcs11_hsm.c libpki-0.8.9/src/drivers/pkcs11/pkcs11_hsm.c
--- libpki-0.8.9-orig/src/drivers/pkcs11/pkcs11_hsm.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/pkcs11/pkcs11_hsm.c	2023-07-14 16:39:36.320164738 +0200
@@ -5,6 +5,11 @@
 #include <libpki/hsm_st.h>
 #include <dlfcn.h>
 
+static int already_initialized = 0;
+
+static int HSM_PKCS11_init( HSM *hsm, PKI_CONFIG *conf );
+static int HSM_PKCS11_free ( HSM *hsm, PKI_CONFIG *conf );
+
 /* Callbacks for Software OpenSSL HSM */
 HSM_CALLBACKS pkcs11_hsm_callbacks = {
 		/* Errno */
@@ -43,12 +48,12 @@
 		HSM_PKCS11_OBJSK_add_url,
 		/* Object stack Del (remove) Function */
 		HSM_PKCS11_OBJSK_del_url,
-        	/* Get the number of available Slots */
+		/* Get the number of available Slots */
 		HSM_PKCS11_SLOT_num,
 		/* Get Slot info */
-        	HSM_PKCS11_SLOT_INFO_get,
+		HSM_PKCS11_SLOT_INFO_get,
 		/* Free Slot info */
-        	HSM_PKCS11_SLOT_INFO_free,
+		HSM_PKCS11_SLOT_INFO_free,
 		/* Set the current slot */
 		HSM_PKCS11_SLOT_select,
 		/* Cleans up the current slot */
@@ -99,7 +104,9 @@
 	HSM *hsm = NULL;
 	char *cryptoki_id = NULL;
 
-	hsm = (HSM *) PKI_Malloc ( sizeof( HSM ));
+	if( (hsm = (HSM *) PKI_Malloc ( sizeof( HSM )) ) == NULL)
+		return(NULL);
+
 	memcpy( hsm, &pkcs11_hsm, sizeof( HSM));
 
 	/* Not really needed! */
@@ -111,73 +118,74 @@
 	/* Let's get the ID for the HSM */
 	if((cryptoki_id = PKI_CONFIG_get_value( conf, "/hsm/id" )) == NULL ) {
 		PKI_log_debug("ERROR, Can not get ENGINE id from conf!\n");
-		PKI_Free ( hsm );
-		return( NULL );
+		goto err;
 	}
 
 	if((hsm->id = URL_new ( cryptoki_id )) == NULL ) {
 		PKI_log_debug("ERROR, Can not convert id into URI (%s)", 
 								cryptoki_id);
 		PKI_Free ( cryptoki_id );
-		PKI_Free ( hsm );
-		return (NULL);
+		goto err;
 	}
 
 	/* cryptoki_id is no more of use, let's free the memory */
 	PKI_Free ( cryptoki_id );
-	
+
 	if((hsm->driver = (void *)
-			_pki_pkcs11_load_module( hsm->id->addr, conf))==NULL) {
+		_pki_pkcs11_load_module( hsm->id->addr, conf))==NULL) {
 		PKI_log_err("Can not init PKCS11 lib");
-		PKI_Free ( hsm );
-		return (NULL);
+		goto err;
 	}
 
 	/* The PKCS11 interface need to be initialized */
-	if(( HSM_PKCS11_init ( hsm->driver, conf )) == PKI_ERR ) {
+	if(( HSM_PKCS11_init ( hsm, conf )) == PKI_ERR ) {
 		PKI_log_err("Can not initialize PKCS11 (%s)", hsm->id->addr );
-		HSM_PKCS11_free ( hsm->driver, conf );
-		PKI_Free( hsm );
-		return( NULL );
+		goto err;
 	};
 
 	if((hsm->session = (void *) PKI_Malloc ( sizeof (CK_SESSION_HANDLE)))
 								== NULL ) {
 		PKI_log_err("HSM_PKCS11_new()::Memory Allocation error for"
 				"CK_SESSION_HANDLE");
-		HSM_PKCS11_free ( hsm->driver, conf );
-		PKI_Free ( hsm );
-		return ( NULL );
+		goto err;
 	}
 
 	return( hsm );
+
+err:
+	if(hsm) {
+		HSM_PKCS11_free ( hsm, conf );
+	}
+	return(NULL);
 }
 
-int HSM_PKCS11_free ( HSM *driver, PKI_CONFIG *conf ) {
+static int HSM_PKCS11_free ( HSM *hsm, PKI_CONFIG *conf ) {
 
 	PKCS11_HANDLER *handle = NULL;
 	CK_RV rv = CKR_OK;
 	int ret = PKI_OK;
 
-	if( driver == NULL ) return (PKI_OK);
+	if( hsm == NULL ) return (PKI_OK);
 
-	ret = HSM_PKCS11_logout( driver );
+	ret = HSM_PKCS11_logout( hsm );
 	if (ret != PKI_OK)
 	{
 		/* This is a non-fatal error, so let's just log it and continue */
-		PKI_log_debug("HHSM_PKCS11_free()::Failed to logout from the HSM");
+		PKI_log_debug("HSM_PKCS11_free()::Failed to logout from the HSM");
 	}
 
-	if((handle = _hsm_get_pkcs11_handler ( driver )) == NULL ) {
-                PKI_log_debug("HSM_PKCS11_free():: Can't get handler!");
-                return ( PKI_ERR );
-        }
+	if((handle = _hsm_get_pkcs11_handler ( hsm )) == NULL )
+	{
+		PKI_log_debug("HSM_PKCS11_free():: Can't get handler!");
+		return ( PKI_ERR );
+	}
 
 	/* Check if the Finalize function is available */
 	if (handle->callbacks && handle->callbacks->C_Finalize)
 	{
 		rv = handle->callbacks->C_Finalize( NULL_PTR );
-		if (!rv) PKI_log_debug("HSM_PKCS11_free()::Failed to call C_Finalize");
+		if (rv != CKR_OK)
+			PKI_log_debug("HSM_PKCS11_free()::Failed to call C_Finalize (0X%8.8X)", rv);
 	}
 
 	/* Close reference to shared lib */
@@ -188,17 +196,28 @@
 		// PKI_Free ( handle->callbacks );
 	}
 
+	/* Free list of machanisms */
+	if( handle->mech_list ) {
+		PKI_Free ( handle->mech_list );
+	}
+
 	/* Set the mutex to an invalid value */
 	pthread_mutex_destroy ( &handle->pkcs11_mutex );
 	pthread_cond_destroy ( &handle->pkcs11_cond );
 
 	/* Free the Memory */
 	PKI_Free ( handle );
-	
+  
+	if(hsm->session)  PKI_Free ( hsm->session );
+	if(hsm->id)       URL_free(hsm->id);
+	PKI_Free ( hsm );
+
+	already_initialized = 0;
+
 	return (PKI_OK);
 }
 
-int HSM_PKCS11_login ( HSM *driver, PKI_CRED *cred ) {
+int HSM_PKCS11_login ( HSM *hsm, PKI_CRED *cred ) {
 
 	PKCS11_HANDLER *lib = NULL;
 	CK_RV rv;
@@ -206,11 +225,11 @@
 	unsigned char *pwd = NULL;
 	// unsigned char *usr = NULL;
 
-	if (!driver) return ( PKI_OK );
+	if (!hsm) return ( PKI_OK );
 
 	PKI_log_debug ( "HSM_PKCS11_login()::Started");
 
-	if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL )
+	if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL )
 	{
 		PKI_log_debug("HSM_PKCS11_login():: Can't get handler!");
 		return ( PKI_ERR );
@@ -252,6 +271,10 @@
 	{
 		pwd = (unsigned char *) getpass("Please enter your password: ");
 	}
+	else if ((pwd = (unsigned char * ) cred->password ) == NULL )
+	{
+		PKI_log_debug("No Password Provided for Login");
+	}
 
 	if (pwd && strlen((const char*) pwd) > 0)
 	{
@@ -286,23 +309,23 @@
 	return ( PKI_OK );
 }
 
-int HSM_PKCS11_logout ( HSM *driver ) {
+int HSM_PKCS11_logout ( HSM *hsm ) {
 
 	PKCS11_HANDLER *lib = NULL;
 	CK_RV rv;
 
-	if ( !driver ) return ( PKI_OK );
+	if ( !hsm ) return ( PKI_OK );
 
         PKI_log_debug("HSM_PKCS11_logout()::Start!");
 
-        if((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) {
-                PKI_log_debug("HSM_PKCS11_login():: Can't get handler!");
+        if((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) {
+                PKI_log_debug("HSM_PKCS11_logout():: Can't get handler!");
                 return ( PKI_ERR );
         }
 
 	rv = lib->callbacks->C_Logout( lib->session );
 	if( rv && rv != CKR_SESSION_CLOSED && rv != CKR_SESSION_HANDLE_INVALID
-			&& rv != CKR_USER_NOT_LOGGED_IN ) {
+			&& rv != CKR_USER_NOT_LOGGED_IN && rv != CKR_CRYPTOKI_NOT_INITIALIZED ) {
 		PKI_log_err(  "can't logout from current session (0x%8.8X)", 
 								rv );
 
@@ -314,7 +337,7 @@
 	return ( PKI_OK );
 }
 
-int HSM_PKCS11_init( HSM *driver, PKI_CONFIG *conf ) {
+static int HSM_PKCS11_init( HSM *hsm, PKI_CONFIG *conf ) {
 
 	CK_RV rv = CKR_OK;
 	PKCS11_HANDLER *handle = NULL;
@@ -322,15 +345,18 @@
 
 	char *tmp = NULL;
 
+	if(already_initialized)
+		return(PKI_OK);
+
 	PKI_log_debug("HSM_PKCS11_init()::Start");
 
-	if( driver == NULL ) {
+	if( hsm == NULL ) {
 		PKI_log_debug("%s:%d::Missing Driver argument",
 				__FILE__, __LINE__ );
 		return ( PKI_ERR );
 	}
 
-	handle = (PKCS11_HANDLER *) driver;
+	handle = (PKCS11_HANDLER *) hsm->driver;
 
 	/* Initialize MUTEX for non-atomic operations */
 	if(pthread_mutex_init( &handle->pkcs11_mutex, NULL ) != 0 ) {
@@ -412,6 +438,8 @@
 					handle->hsm_info.lib_version_major, 
 					handle->hsm_info.lib_version_minor );
 
+	already_initialized = 1;
+
 	return( PKI_OK);
 }
 
@@ -535,12 +563,12 @@
 	return ( ret );
 }
 
-int HSM_PKCS11_set_fips_mode(const HSM *driver, int k)
+int HSM_PKCS11_set_fips_mode(const HSM *hsm, int k)
 {
 	PKCS11_HANDLER *lib = NULL;
-	if (!driver) return PKI_ERR;
+	if (!hsm) return PKI_ERR;
 
-	if ((lib = _hsm_get_pkcs11_handler ((HSM *)driver)) == NULL)
+	if ((lib = _hsm_get_pkcs11_handler ((HSM *)hsm)) == NULL)
 	{
 		PKI_log_err("HSM_PKCS11_set_fips_mode()::Can't get a valid "
 			"PKCS11 handler from driver!");
@@ -551,12 +579,12 @@
 	return PKI_ERR;
 }
 
-int HSM_PKCS11_is_fips_mode(const HSM *driver)
+int HSM_PKCS11_is_fips_mode(const HSM *hsm)
 {
 	PKCS11_HANDLER *lib = NULL;
-	if (!driver) return PKI_ERR;
+	if (!hsm) return PKI_ERR;
 
-	if ((lib = _hsm_get_pkcs11_handler((HSM *)driver)) == NULL)
+	if ((lib = _hsm_get_pkcs11_handler((HSM *)hsm)) == NULL)
 	{
 		PKI_log_err("HSM_PKCS11_set_fips_mode()::Can't get a valid "
 			"PKCS11 handler from driver!");
@@ -576,7 +604,7 @@
 				PKI_STRING *bit,
 				PKI_X509_KEYPAIR *key, 
 				PKI_DIGEST_ALG *digest, 
-				HSM *driver ) {
+				HSM *hsm ) {
 
 	int ret = 0;
 	ASN1_ITEM *it = NULL;
@@ -780,7 +808,7 @@
 	slot_num = (CK_ULONG) num;
 	if((rv = lib->callbacks->C_GetSlotInfo(slot_num, &info)) != CKR_OK ) {
 		PKI_log_debug("Can not get Info from PKCS11 library" );
-		PKI_log_debug("Returned Value is %d (OK is %d)", rv, CKR_OK );
+		PKI_log_debug("Returned Value is (0X%8.8X) (OK is (0X%8.8X))", rv, CKR_OK );
 		return ( PKI_ERR );
 	};
 	
@@ -945,7 +973,7 @@
 	rv = lib->callbacks->C_GetMechanismList(lib->slot_id,
 						lib->mech_list, &lib->mech_num);
 	if( rv != CKR_OK ) {
-		PKI_log_debug("C_GetMechanismList::Failed (%d::%d)", 
+		PKI_log_debug("C_GetMechanismList::Failed (%d::0X%8.8X)", 
 				lib->slot_id, rv );
 		goto end;
 	}
@@ -954,7 +982,7 @@
 	return ( PKI_OK );
 }
 
-int HSM_PKCS11_SLOT_clear (unsigned long slot_id, PKI_CRED *cred, HSM *driver){
+int HSM_PKCS11_SLOT_clear (unsigned long slot_id, PKI_CRED *cred, HSM *hsm){
 
 	PKCS11_HANDLER *lib = NULL;
 
@@ -965,9 +993,9 @@
 
 	CK_SESSION_HANDLE *session = NULL;
 
-	if( !driver ) return (PKI_ERR);
+	if( !hsm ) return (PKI_ERR);
 
-	if(( lib = _hsm_get_pkcs11_handler ( driver)) == NULL ) {
+	if(( lib = _hsm_get_pkcs11_handler ( hsm)) == NULL ) {
 		return ( PKI_ERR );
 	}
 
@@ -978,7 +1006,7 @@
 
 	session = &lib->session;
 
-	if ( HSM_PKCS11_login ( driver, cred ) == PKI_ERR )  {
+	if ( HSM_PKCS11_login ( hsm, cred ) == PKI_ERR )  {
 		return ( PKI_ERR );
 	}
 
@@ -1028,7 +1056,7 @@
 }
 
 int HSM_PKCS11_SLOT_elements (unsigned long slot_id, PKI_CRED *cred, 
-							HSM *driver){
+							HSM *hsm){
 
 	PKCS11_HANDLER *lib = NULL;
 
@@ -1040,9 +1068,9 @@
 	CK_SESSION_HANDLE *session = NULL;
 	int count = 0;
 
-	if( !driver ) return (PKI_ERR);
+	if( !hsm ) return (PKI_ERR);
 
-	if(( lib = _hsm_get_pkcs11_handler ( driver)) == NULL ) {
+	if(( lib = _hsm_get_pkcs11_handler ( hsm)) == NULL ) {
 		return ( PKI_ERR );
 	}
 
@@ -1053,7 +1081,7 @@
 
 	session = &lib->session;
 
-	if ( HSM_PKCS11_login ( driver, cred ) == PKI_ERR )  {
+	if ( HSM_PKCS11_login ( hsm, cred ) == PKI_ERR )  {
 		return ( PKI_ERR );
 	}
 
diff -ur libpki-0.8.9-orig/src/drivers/pkcs11/pkcs11_hsm_obj.c libpki-0.8.9/src/drivers/pkcs11/pkcs11_hsm_obj.c
--- libpki-0.8.9-orig/src/drivers/pkcs11/pkcs11_hsm_obj.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/pkcs11/pkcs11_hsm_obj.c	2023-07-14 16:39:36.320164738 +0200
@@ -494,7 +494,7 @@
 
 	/* Login into the device - do nothing if we are already logged in */
 	/*
-	if(( HSM_PKCS11_login ( driver, cred )) == PKI_ERR ) {
+	if(( HSM_PKCS11_login ( hsm, cred )) == PKI_ERR ) {
 		PKI_log_debug("HSM_PKCS11_KEYPAIR_get_url()::ERROR, can not "
 					"login to device!");
 		return ( NULL );
@@ -592,14 +592,14 @@
 		}
 		
 		/* Let's get the Attributes from the Keypair and store into the
-        	   key's pointer */
-        	RSA_set_method( rsa, HSM_PKCS11_get_rsa_method());
-        	rsa->flags |= RSA_FLAG_SIGN_VER;
-
-        	/* Push the priv and pub key handlers to the rsa->ex_data */
-        	RSA_set_ex_data( rsa, KEYPAIR_DRIVER_HANDLER_IDX, hsm );
-        	RSA_set_ex_data( rsa, KEYPAIR_PRIVKEY_HANDLER_IDX, privKey );
-        	RSA_set_ex_data( rsa, KEYPAIR_PUBKEY_HANDLER_IDX, pubKey );
+		   key's pointer */
+		RSA_set_method( rsa, HSM_PKCS11_get_rsa_method());
+		rsa->flags |= RSA_FLAG_SIGN_VER;
+
+		/* Push the priv and pub key handlers to the rsa->ex_data */
+		RSA_set_ex_data( rsa, KEYPAIR_DRIVER_HANDLER_IDX, hsm );
+		RSA_set_ex_data( rsa, KEYPAIR_PRIVKEY_HANDLER_IDX, privKey );
+		RSA_set_ex_data( rsa, KEYPAIR_PUBKEY_HANDLER_IDX, pubKey );
 
 		if((val = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) {
 			PKI_log_debug ( "Memory Error");
@@ -644,7 +644,7 @@
 
 	PKI_log_debug( "HSM_PKCS11_KEYPAIR_get_url()::Keypair loaded success!");
 
-        return ( ret_sk );
+	return ( ret_sk );
 }
 
 /*
@@ -655,11 +655,11 @@
 
 	if( !url ) return ( NULL );
 
-	if(( key_sk = HSM_PKCS11_KEYPAIR_get_url( url, cred, driver )) == NULL){
+	if(( key_sk = HSM_PKCS11_KEYPAIR_get_url( url, cred, hsm )) == NULL){
 		return ( NULL );
 	}
 
-	return ( HSM_PKCS11_KEYPAIR_STACK_wrap ( key_sk, cred, driver ) );
+	return ( HSM_PKCS11_KEYPAIR_STACK_wrap ( key_sk, cred, hsm ) );
 }
 
 PKI_STACK * HSM_PKCS11_KEYPAIR_STACK_wrap ( PKI_KEYPAIR_STACK *sk, 
@@ -770,7 +770,7 @@
 	}
 
 	if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) {
-		PKI_log_debug ("HSM_PKCS11_KEYPAIR_get_url()::No handler");
+		PKI_log_debug ("HSM_PKCS11_STACK_get_url()::No handler");
 		return NULL;
 	}
 
@@ -843,7 +843,7 @@
 	}
 
 	idx = 0;
-	HSM_PKCS11_set_attr_int(CKA_CLASS,(int) objClass,&templ[idx++]);
+	HSM_PKCS11_set_attr_int(CKA_CLASS, objClass, &templ[idx++]);
 	HSM_PKCS11_set_attr_sn(CKA_LABEL, myLabel, strlen(myLabel), 
 							&templ[idx++]);	
 	HSM_PKCS11_set_attr_sn(CKA_APPLICATION, myLabel, strlen(myLabel), 
diff -ur libpki-0.8.9-orig/src/drivers/pkcs11/pkcs11_hsm_pkey.c libpki-0.8.9/src/drivers/pkcs11/pkcs11_hsm_pkey.c
--- libpki-0.8.9-orig/src/drivers/pkcs11/pkcs11_hsm_pkey.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/pkcs11/pkcs11_hsm_pkey.c	2023-07-14 16:39:36.320164738 +0200
@@ -20,17 +20,17 @@
 
 #define RSA_SIGNATURE_MAX_SIZE		8192
 
-PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url,
-					PKCS11_HANDLER *lib, void *driver );
+static PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url,
+					PKCS11_HANDLER *lib, void *hsm );
 
-PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url, 
-					PKCS11_HANDLER *lib, void *driver );
+static PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url, 
+					PKCS11_HANDLER *lib, void *hsm );
 #ifdef ENABLE_ECDSA
-PKI_EC_KEY * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp,
-			URL *url, PKCS11_HANDLER *lib, void *driver );
+static PKI_EC_KEY * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp,
+			URL *url, PKCS11_HANDLER *lib, void *hsm );
 #else
 void * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp,
-			URL *url, PKCS11_HANDLER *lib, void *driver );
+			URL *url, PKCS11_HANDLER *lib, void *hsm );
 #endif
 
 int _pki_pkcs11_rand_init( void );
@@ -51,39 +51,8 @@
 	return(1);
 }
 
-/*
-size_t _get_key_id ( char *id, size_t size ) {
-
-	unsigned char id_rand[1024];
-	int rand_len = 0;
-	int n = 0;
-
-	BIGNUM *bn;
-
-	if( BN_hex2bn(&bn, id) == 0 ) {
-                return ( 0 );
-        }
-
-	if( RAND_bytes( id_rand, rand_len) == 0 ) {
-		return ( 0 );
-	}
-
-	memset( id, 0x0, size );
-	for( n = 0; n < rand_len; n++ ) {
-		char * dest = NULL;
-
-		dest = (char *) id + n*2 + n;
-		sprintf(dest, "%2.2x", (CK_BYTE) id_rand[n] );
-
-		if( n < sizeof(id_rand)-1 ) dest[2] = ':';
-	}
-
-	return ( strlen(id) );
-}
-*/
-
-PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url,
-					PKCS11_HANDLER *lib, void *driver) {
+static PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url,
+					PKCS11_HANDLER *lib, void *hsm) {
 
 	PKI_RSA_KEY *ret = NULL;
 
@@ -126,7 +95,10 @@
 	if ( kp ) {
 		if( kp->bits < PKI_RSA_KEY_MIN_SIZE ) {
 			PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL);
-		};
+			return ( NULL );
+		} else {
+			bits = kp->bits;
+		}
 	} else {
 		bits = PKI_RSA_KEY_DEFAULT_SIZE;
 	}
@@ -172,7 +144,7 @@
 	n = 0;
 	//HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &pubTemp[n++]);
 	//HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &pubTemp[n++]);
-	HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &pubTemp[n++]);
+	HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, (CK_ULONG)bits, &pubTemp[n++]);
 
 	HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &pubTemp[n++]);
 	HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &pubTemp[n++]);
@@ -270,7 +242,7 @@
 	ret->flags |= RSA_FLAG_SIGN_VER;
 
 	/* Push the priv and pub key handlers to the rsa->ex_data */
-	RSA_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver );
+	RSA_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, hsm );
 	RSA_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey );
 	RSA_set_ex_data( ret, KEYPAIR_PUBKEY_HANDLER_IDX, handler_pubkey );
 
@@ -308,8 +280,8 @@
 
 }
 
-PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url,
-					PKCS11_HANDLER *lib, void *driver ) {
+static PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url,
+					PKCS11_HANDLER *lib, void *hsm ) {
 	PKI_DSA_KEY *k = NULL;
 	// unsigned char seed[20];
 
@@ -319,8 +291,8 @@
 }
 
 #ifdef ENABLE_ECDSA
-PKI_EC_KEY * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp,
-			URL *url, PKCS11_HANDLER *lib, void *driver ) {
+static PKI_EC_KEY * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp,
+			URL *url, PKCS11_HANDLER *lib, void *hsm ) {
 
 	PKI_EC_KEY *k = NULL;
 
@@ -332,7 +304,7 @@
 #else /* EVP_PKEY_EC */
 
 void * _pki_pkcs11_ecdsakey_new( PKI_KEYPARAMS *kp,
-			URL *url, PKCS11_HANDLER *lib, void *driver ) {
+			URL *url, PKCS11_HANDLER *lib, void *hsm ) {
 	PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL);
 	return ( NULL );
 }
@@ -341,7 +313,7 @@
 
 
 PKI_X509_KEYPAIR *HSM_PKCS11_KEYPAIR_new( PKI_KEYPARAMS *kp,
-			URL *url, PKI_CRED *cred, HSM *driver ) {
+			URL *url, PKI_CRED *cred, HSM *hsm ) {
 
 	PKCS11_HANDLER *lib = NULL;
 	int type = PKI_SCHEME_DEFAULT;
@@ -371,7 +343,7 @@
 
 	PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Start!");
 
-	if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) {
+	if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) {
 		PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Can not get handler");
 		return NULL;
 	}
@@ -412,44 +384,11 @@
 		return ( NULL );
 	};
 
-	/*
-	PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Opening new R/W key session");
-	if((rv = lib->callbacks->C_OpenSession (lib->slot_id, 
-			CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, 
-						&(lib->session))) != CKR_OK ) {
-		PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Failed in opening a "
-				"new session (R/W) with the token" );
-		return ( NULL );
-	}
-	*/
-
-	if( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) {
+	if( HSM_PKCS11_login ( hsm, cred ) == PKI_ERR ) {
 		HSM_PKCS11_session_close ( &lib->session, lib );
 		return ( PKI_ERR );
 	}
 
-	/*
-	PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Logging in" );
-	rv = lib->callbacks->C_Login(lib->session, CKU_USER, 
-		(CK_UTF8CHAR *) cred->password, 
-			cred->password ? strlen(cred->password) : 0);
-	*/
-
-	/*
-	if ( rv == CKR_USER_ALREADY_LOGGED_IN ) {
-		PKI_log_debug( "HSM_PKCS11_SLOT_select()::User Already logged "
-								"in!");
-	} else if( rv == CKR_PIN_INCORRECT ) {
-		PKI_log_err ( "HSM_PKCS11_SLOT_select()::Can not login "
-			"- Pin Incorrect (0X%8.8X) [%s]", rv, cred->password);
-		return ( PKI_ERR );
-	} else if ( rv != CKR_OK ) {
-		PKI_log_err ( "HSM_PKCS11_SLOT_select()::Can not login "
-			"- General Error (0X%8.8X)", rv);
-		return ( PKI_ERR );
-	}
-	*/
-
 	/* Generate the EVP_PKEY that will allow it to make use of it */
 	if((val = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) {
 		HSM_PKCS11_session_close ( &lib->session, lib );
@@ -461,7 +400,7 @@
 
 		case PKI_SCHEME_RSA:
 			if ((rsa = _pki_pkcs11_rsakey_new ( kp, url, 
-					lib, driver)) == NULL ) {
+					lib, hsm)) == NULL ) {
 				HSM_PKCS11_session_close ( &lib->session, lib );
 				return ( NULL );
 			};
@@ -476,7 +415,7 @@
 
 		case PKI_SCHEME_DSA:
 			if ((dsa = _pki_pkcs11_dsakey_new ( kp, url, 
-					lib, driver)) == NULL ) {
+					lib, hsm)) == NULL ) {
 				HSM_PKCS11_session_close ( &lib->session, lib );
 				return ( NULL );
 			};
@@ -492,7 +431,7 @@
 #ifdef ENABLE_ECDSA
 		case PKI_SCHEME_ECDSA:
 			if ((ecdsa = _pki_pkcs11_ecdsakey_new ( kp, url, 
-					lib, driver)) == NULL ) {
+					lib, hsm)) == NULL ) {
 				HSM_PKCS11_session_close ( &lib->session, lib );
 				return ( NULL );
 			};
@@ -514,7 +453,7 @@
 
 	HSM_PKCS11_session_close ( &lib->session, lib );
 
-	if (( ret = PKI_X509_new ( PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL){
+	if (( ret = PKI_X509_new ( PKI_DATATYPE_X509_KEYPAIR, hsm)) == NULL){
 			PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL );
 			if ( val ) EVP_PKEY_free ( (EVP_PKEY *) val );
 		if ( val ) EVP_PKEY_free ( val );
@@ -562,7 +501,7 @@
 
 	PKCS11_HANDLER *lib = NULL;
 	CK_OBJECT_HANDLE *pHandle = NULL;
-	HSM *driver = NULL;
+	HSM *hsm = NULL;
 
 	CK_MECHANISM RSA_MECH = {
 		CKM_RSA_PKCS, NULL_PTR, 0 };
@@ -586,6 +525,11 @@
 	CK_RV rv = CKR_OK;
 
 	unsigned char *buf = NULL;
+#ifdef TIMED_DEBUG
+	struct timeval      start;        // timestamp when the request arives
+	struct timeval      stop;        // timestamp when the request arives
+	unsigned int duration = 0;
+#endif
 
 	PKI_log_debug("RSA::SIGN::PKCS#11::START");
 
@@ -594,7 +538,7 @@
 			return (0 /* 0 = PKI_ERR in OpenSSL */ );
 
 	/* Retrieves the reference to the hsm */
-	if((driver = (HSM *) RSA_get_ex_data (rsa, KEYPAIR_DRIVER_HANDLER_IDX))
+	if((hsm = (HSM *) RSA_get_ex_data (rsa, KEYPAIR_DRIVER_HANDLER_IDX))
 								== NULL ) {
 		PKI_log_err ("HSM_PKCS11_rsa_sign()::Can't get Driver Handle");
 		return ( 0 /* 0 = PKI_ERR in OpenSSL */ );
@@ -607,36 +551,15 @@
 		return ( 0 /* 0 = PKI_ERR in OpenSSL */ );
 	}
 
-	if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) {
+	if ((lib = _hsm_get_pkcs11_handler ( hsm )) == NULL ) {
                 PKI_log_err("HSM_PKCS11_rsa_sign()::Can not get lib handler");
                 return ( 0 /* 0 = PKI_ERR in OpenSSL */ );
         }
 
-	/*
-	rv = lib->callbacks->C_CloseSession( lib->session );
-	*/
-
-	/*
-	if(( rv = lib->callbacks->C_GetSessionInfo(lib->session, 
-					&session_info)) != CKR_OK ) {
-		PKI_log_debug("HSM_PKCS11_rsa_sign()::SessionInfo error "
-							"(0x%8.8X)", rv );
-
-		PKI_log_debug("HSM_PKCS11_rsa_sign()::Opening new session");
-		if((rv = lib->callbacks->C_OpenSession (lib->slot_id, 
-				CKF_SERIAL_SESSION, NULL, NULL, 
-						&(lib->session))) != CKR_OK ) {
-			PKI_log_debug("HSM_PKCS11_rsa_sign()::Failed opening a "
-				"new sign session (R) with the token" );
-			return ( 0 );
-		}
-	}
-	*/
-
 	if(( HSM_PKCS11_session_new( lib->slot_id, &lib->session,
 				CKF_SERIAL_SESSION, lib )) == PKI_ERR ) {
 
-		PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Failed in opening a "
+		PKI_log_debug("HSM_PKCS11_rsa_sign()::Failed in opening a "
 				"new session (R/W) with the token" );
 		return ( 0 );
 	};
@@ -684,39 +607,12 @@
 	i2d_X509_SIG( &sig, &p );
 	s = tmps;
 
-	/*
-	if(( size = i2d_X509_SIG(&digest_info, NULL)) == 0 ) {
-		PKI_log_debug("HSM_PKCS11_rsa_sign()::size is 0");
-		return ( 0 );
-	}
-
-	PKI_log_debug("HSM_PKCS11_rsa_sign()::KEY size is %d", keysize);
-
-	sigsize = keysize;
-	*/
-
-	/* We should check that the size + padding < size of the key */
-	/*
-	if( size + RSA_PKCS1_PADDING_SIZE > keysize ) {
-		PKI_log_debug("HSM_PKCS11_rsa_sign()::size + pad > keysize");
-		return ( 0 );
-	}
-
-	if((encoded = (unsigned char *) PKI_Malloc (sigsize)) == NULL ) {
-		PKI_log_debug("HSM_PKCS11_rsa_sign()::Memory alloc err ");
-		return ( 0 );
-	} else {
-		unsigned char *tmp = encoded;
-
-		i2d_X509_SIG( &digest_info, &tmp );
-		m = encoded;
-		m_len = size;
-	}
-	*/
-
 	rc = pthread_mutex_lock( &lib->pkcs11_mutex );
 	PKI_log_debug( "pthread_mutex_lock()::RC=%d", rc );
 
+#ifdef TIMED_DEBUG
+	gettimeofday(&start, NULL);
+#endif
 	while(( rv = lib->callbacks->C_SignInit(lib->session, 
 			&RSA_MECH, *pHandle)) == CKR_OPERATION_ACTIVE ) {
 		int rc = 0;
@@ -734,50 +630,11 @@
 		return ( 0 /* 0 = PKI_ERR in OpenSSL */ );
 	}
 
-/*
-		while (rv == CKR_OPERATION_ACTIVE ) {
-			pthread_mutex_lock( &lib->pkcs11_mutex );
-			mutex_acquired = 1;
-			if((rv = lib->callbacks->C_SignInit(lib->session, 
-					&RSA_MECH, *pHandle)) 
-						!= CKR_OPERATION_ACTIVE ) {
-
-				PKI_log_debug("HSM_PKCS11_rsa_sign()::SignInit "
-					"(2) failed with code 0x%8.8X", rv );
-				break;
-			}
-
-			pthread_cond_signal( &lib->pkcs11_cond );
-			pthread_mutex_unlock( &lib->pkcs11_mutex );
-			mutex_acquired = 0;
-
-		} 
-
-		if( rv != CKR_OK ) {
-			PKI_log_debug("HSM_PKCS11_rsa_sign()::SignInit failed "
-					"with code 0x%8.8X", rv );
-
-			pthread_cond_signal( &lib->pkcs11_cond );
-			pthread_mutex_unlock( &lib->pkcs11_mutex );
-			mutex_acquired = 0;
-
-			return ( 0 );
-		}
-*/
-
-	ck_sigsize = *siglen;
-	PKI_log_debug("HSM_PKCS11_rsa_sign()::i = %d, siglen = %d, "
-		"sigret = %d (%p)", i, ck_sigsize, sizeof(sigret), sigret );
-
 	/* Let's exagerate for now... */
 	buf = PKI_Malloc (RSA_SIGNATURE_MAX_SIZE);
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 
 	ck_sigsize = RSA_SIGNATURE_MAX_SIZE;
 
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
-	// if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) m, 
-	// 			m_len, sigret, &ck_sigsize)) != CKR_OK ) {
 	if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) s, 
 				(CK_ULONG) i, buf, &ck_sigsize)) != CKR_OK ) {
 		PKI_log_err("HSM_PKCS11_rsa_sign()::Sign failed with 0x%8.8X",
@@ -792,29 +649,25 @@
 		pthread_cond_signal( &lib->pkcs11_cond );
 		pthread_mutex_unlock( &lib->pkcs11_mutex );
 
-		PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 		if( buf ) PKI_Free ( buf );
 
-		PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
-
 		return ( 0 /* 0 = PKI_ERR in OpenSSL */ );
 	}
+#ifdef TIMED_DEBUG
+	gettimeofday(&stop, NULL);
+	duration = (unsigned int)((stop.tv_sec - start.tv_sec) * 1000 + (stop.tv_usec - start.tv_usec) / 1000);
+	PKI_log_debug("Duration: %d ms", duration);
+#endif
 
 	pthread_cond_signal( &lib->pkcs11_cond );
 	pthread_mutex_unlock( &lib->pkcs11_mutex );
 
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 	*siglen = (unsigned int) ck_sigsize;
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: BUF Written = %d", ck_sigsize );
 	memcpy( sigret, buf, *siglen );
 
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 	if( tmps ) PKI_Free ( tmps );
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 	if( buf ) PKI_Free ( buf );
-	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
 
 	return ( 1 /* 1 = PKI_OK in OpenSSL */ );
 }
diff -ur libpki-0.8.9-orig/src/drivers/pkcs11/utils/pkcs11_init.c libpki-0.8.9/src/drivers/pkcs11/utils/pkcs11_init.c
--- libpki-0.8.9-orig/src/drivers/pkcs11/utils/pkcs11_init.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/drivers/pkcs11/utils/pkcs11_init.c	2023-07-14 16:39:36.320164738 +0200
@@ -295,7 +295,7 @@
 }
 
 int HSM_PKCS11_get_contents_info( unsigned long slot_id, PKI_CRED *cred,
-							void *driver ) {
+							void *hsm ) {
 
 	PKCS11_HANDLER *lib = NULL;
 
@@ -317,9 +317,9 @@
 
 	int objID = 0;
 
-	if( !driver ) return (PKI_ERR);
+	if( !hsm ) return (PKI_ERR);
 
-	if(( lib = _hsm_get_pkcs11_handler ( driver)) == NULL ) {
+	if(( lib = _hsm_get_pkcs11_handler ( hsm)) == NULL ) {
 		return ( PKI_ERR );
 	}
 
@@ -329,7 +329,7 @@
 		return ( PKI_ERR );
 	}
 
-	if( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) {
+	if( HSM_PKCS11_login ( hsm, cred ) == PKI_ERR ) {
 		return ( PKI_ERR );
 	}
 
@@ -567,13 +567,19 @@
 	
 	if ( flags == 0 ) flags = CKF_SERIAL_SESSION;
 
+	memset(&session_info, 0, sizeof(CK_SESSION_INFO));
+
 	if(( rv = lib->callbacks->C_GetSessionInfo(*hSession, &session_info)) 
 								== CKR_OK ) {
 
 		if ( session_info.flags == flags ) {
 			return ( PKI_OK );
 		}
+		PKI_log_debug("HSM_PKCS11_session new ():: Session flags returned from C_GetSessionInfo() differ "
+			"to given argument: Prev=0x%08x, Curr=0x%08x", session_info.flags, flags );
 	}
+	else
+		PKI_log_debug("HSM_PKCS11_session new ()::C_GetSessionInfo failed: Error: [0x%8.8X]", rv );
 
 
 	/* If we reach this point, then the current session is either
@@ -581,7 +587,7 @@
 	if((rv = lib->callbacks->C_OpenSession (slot_id, 
 			(CK_FLAGS) flags, NULL, NULL, hSession)) != CKR_OK ) {
 		PKI_log_debug("HSM_PKCS11_session new ()::Failed opening a "
-			"new session 0x%x with the token (%d) [0x%8.8X]",
+			"new session (flags=0x%x) with the token (slot=%d): Error: [0x%8.8X]",
 					flags, slot_id, rv );
 		return ( PKI_ERR );
 	}
@@ -788,14 +794,9 @@
 		*val = BN_bin2bn( data, (int) size, NULL );
 	}
 
-	/*
 	if( data ) {
-		for ( i = size; i < sizeof(CK_ULONG); i++ ) {
-			*data = 0x0;
-		}
-		*val = *data;
+		PKI_Free ( data );
 	}
-	*/
 
 	return ( PKI_OK );
 }
@@ -852,12 +853,12 @@
 }
 
 int HSM_PKCS11_set_attr_int ( CK_ATTRIBUTE_TYPE type,
-				int value, CK_ATTRIBUTE *attribute ) {
+				CK_ULONG value, CK_ATTRIBUTE *attribute ) {
 
 	if ( !attribute ) return ( PKI_ERR );
 
 	attribute->type = type;
-	attribute->pValue = (void *) PKI_Malloc ( sizeof(int));
+	attribute->pValue = (void *) PKI_Malloc ( sizeof(CK_ULONG));
 	memcpy(attribute->pValue, &value, sizeof(value));
 	attribute->ulValueLen = sizeof( value );
 
diff -ur libpki-0.8.9-orig/src/extensions.c libpki-0.8.9/src/extensions.c
--- libpki-0.8.9-orig/src/extensions.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/extensions.c	2023-07-14 16:39:36.320164738 +0200
@@ -27,7 +27,7 @@
 		}
 		else
 		{
-			PKI_log_debug ("Can not create EXTENSION number %d", i);
+			PKI_log_err ("Can not create EXTENSION number %d", i);
 		}
 	}
 
diff -ur libpki-0.8.9-orig/src/libpki/drivers/engine/engine_hsm.h libpki-0.8.9/src/libpki/drivers/engine/engine_hsm.h
--- libpki-0.8.9-orig/src/libpki/drivers/engine/engine_hsm.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/engine/engine_hsm.h	2023-07-14 16:39:36.328164739 +0200
@@ -14,8 +14,8 @@
 char * HSM_ENGINE_get_errdesc ( unsigned long err, char *str, size_t size );
 
 HSM *HSM_ENGINE_new ( PKI_CONFIG *conf );
-int HSM_ENGINE_free ( HSM *driver, PKI_CONFIG *conf );
-int HSM_ENGINE_init( HSM *driver, PKI_CONFIG *conf );
+int HSM_ENGINE_free ( HSM *hsm, PKI_CONFIG *conf );
+int HSM_ENGINE_init( HSM *hsm, PKI_CONFIG *conf );
 
 /* ---------------------- Sign/Verify functions ----------------------- */
 
diff -ur libpki-0.8.9-orig/src/libpki/drivers/engine/engine_hsm_pkey.h libpki-0.8.9/src/libpki/drivers/engine/engine_hsm_pkey.h
--- libpki-0.8.9-orig/src/libpki/drivers/engine/engine_hsm_pkey.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/engine/engine_hsm_pkey.h	2023-07-14 16:39:36.328164739 +0200
@@ -7,7 +7,7 @@
 
 /* New keypair */
 PKI_X509_KEYPAIR *HSM_ENGINE_X509_KEYPAIR_new( PKI_KEYPARAMS *pk,
-				URL *url, PKI_CRED *cred, HSM *driver );
+				URL *url, PKI_CRED *cred, HSM *hsm );
 
 /* Key Free function */
 void HSM_ENGINE_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey );
diff -ur libpki-0.8.9-orig/src/libpki/drivers/hsm_keypair.h libpki-0.8.9/src/libpki/drivers/hsm_keypair.h
--- libpki-0.8.9-orig/src/libpki/drivers/hsm_keypair.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/hsm_keypair.h	2023-07-14 16:39:36.328164739 +0200
@@ -10,7 +10,7 @@
                                         PKI_CRED *cred, HSM *hsm );
 
 PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new_url( PKI_KEYPARAMS *params, URL *url,
-                                        PKI_CRED *cred, HSM *driver );
+                                        PKI_CRED *cred, HSM *hsm );
 
 /* Free the memory associated to a keypair */
 /*
diff -ur libpki-0.8.9-orig/src/libpki/drivers/openssl/openssl_hsm.h libpki-0.8.9/src/libpki/drivers/openssl/openssl_hsm.h
--- libpki-0.8.9-orig/src/libpki/drivers/openssl/openssl_hsm.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/openssl/openssl_hsm.h	2023-07-14 16:39:36.332164739 +0200
@@ -9,11 +9,11 @@
 HSM * HSM_OPENSSL_new( PKI_CONFIG *conf );
 const HSM * HSM_OPENSSL_get_default( void );
 
-int HSM_OPENSSL_free ( HSM *driver, PKI_CONFIG *conf );
-int HSM_OPENSSL_init ( HSM *driver, PKI_CONFIG *conf );
+int HSM_OPENSSL_free ( HSM *hsm, PKI_CONFIG *conf );
+int HSM_OPENSSL_init ( HSM *hsm, PKI_CONFIG *conf );
 
-int HSM_OPENSSL_set_fips_mode(const HSM *driver, int k);
-int HSM_OPENSSL_is_fips_mode(const HSM *driver);
+int HSM_OPENSSL_set_fips_mode(const HSM *hsm, int k);
+int HSM_OPENSSL_is_fips_mode(const HSM *hsm);
 
 /* ---------------------- Sign/Verify functions ----------------------- */
 
diff -ur libpki-0.8.9-orig/src/libpki/drivers/openssl/openssl_hsm_pkey.h libpki-0.8.9/src/libpki/drivers/openssl/openssl_hsm_pkey.h
--- libpki-0.8.9-orig/src/libpki/drivers/openssl/openssl_hsm_pkey.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/openssl/openssl_hsm_pkey.h	2023-07-14 16:39:36.332164739 +0200
@@ -7,7 +7,7 @@
 /* ------------------- Keypair Functions --------------------- */
 
 PKI_X509_KEYPAIR *HSM_OPENSSL_X509_KEYPAIR_new( PKI_KEYPARAMS *pk, 
-		URL *url, PKI_CRED *cred, HSM *driver );
+		URL *url, PKI_CRED *cred, HSM *hsm );
 void HSM_OPENSSL_X509_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey );
 
 int OPENSSL_HSM_write_bio_PrivateKey (BIO *bp, EVP_PKEY *x, 
diff -ur libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_hsm.h libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_hsm.h
--- libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_hsm.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_hsm.h	2023-07-14 16:39:36.332164739 +0200
@@ -48,16 +48,16 @@
 } PKCS11_HANDLER;
 
 HSM * HSM_PKCS11_new( PKI_CONFIG *conf );
-int HSM_PKCS11_free ( HSM *driver, PKI_CONFIG *conf );
+//int HSM_PKCS11_free ( HSM *hsm, PKI_CONFIG *conf );
 
-int HSM_PKCS11_login ( HSM *driver, PKI_CRED *cred );
-int HSM_PKCS11_logout ( HSM *driver );
+int HSM_PKCS11_login ( HSM *hsm, PKI_CRED *cred );
+int HSM_PKCS11_logout ( HSM *hsm );
 
-int HSM_PKCS11_init ( HSM *driver, PKI_CONFIG *conf );
-int HSM_PKCS11_algor_set ( HSM *driver, PKI_ALGOR *alg);
+//int HSM_PKCS11_init ( HSM *hsm, PKI_CONFIG *conf );
+int HSM_PKCS11_algor_set ( HSM *hsm, PKI_ALGOR *alg);
 
-int HSM_PKCS11_set_fips_mode ( const HSM *driver, int k);
-int HSM_PKCS11_is_fips_mode( const HSM *driver );
+int HSM_PKCS11_set_fips_mode ( const HSM *hsm, int k);
+int HSM_PKCS11_is_fips_mode( const HSM *hsm );
 
 /*
 PKI_MEM * HSM_PKCS11_sign (PKI_MEM *der, PKI_X509_KEYPAIR *key,
@@ -69,7 +69,7 @@
 				PKI_STRING *bit,
 				PKI_X509_KEYPAIR *key, 
 				PKI_DIGEST_ALG *digest, 
-				HSM *driver );
+				HSM *hsm );
 */
 
 int HSM_PKCS11_verify ( PKI_OBJTYPE type, void *x, 
@@ -79,6 +79,6 @@
 HSM_SLOT_INFO * HSM_PKCS11_SLOT_INFO_get ( unsigned long num, HSM *hsm );
 void HSM_PKCS11_SLOT_INFO_free ( HSM_SLOT_INFO *sl_info, HSM *hsm );
 int HSM_PKCS11_SLOT_select ( unsigned long num, PKI_CRED *cred, HSM *hsm);
-int HSM_PKCS11_SLOT_clear (unsigned long slot_id, PKI_CRED *cred, HSM *driver);
+int HSM_PKCS11_SLOT_clear (unsigned long slot_id, PKI_CRED *cred, HSM *hsm);
 
 #endif
diff -ur libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_hsm_obj.h libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_hsm_obj.h
--- libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_hsm_obj.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_hsm_obj.h	2023-07-14 16:39:36.332164739 +0200
@@ -20,7 +20,7 @@
 
 /* --------------------- Internal Functions --------------------------- */
 PKI_X509_STACK *HSM_PKCS11_STACK_get_url( PKI_DATATYPE type, URL *url, 
-					PKI_CRED *cred, HSM *driver );
+					PKI_CRED *cred, HSM *hsm );
 int HSM_PKCS11_STACK_add_url( PKI_X509_STACK *sk, URL *url, 
 					PKI_CRED *cred, HSM *hsm );
 
@@ -32,14 +32,14 @@
 PKI_X509_KEYPAIR_STACK * HSM_PKCS11_KEYPAIR_get_url (URL *url, PKI_CRED *cred, 
 								HSM *hsm);
 PKI_STACK * HSM_PKCS11_KEYPAIR_wrap_url ( URL *url, PKI_CRED *cred, 
-								HSM *driver );
+								HSM *hsm );
 PKI_STACK * HSM_PKCS11_KEYPAIR_STACK_wrap ( PKI_X509_KEYPAIR_STACK *sk, 
-						PKI_CRED *cred, HSM *driver );
+						PKI_CRED *cred, HSM *hsm );
 /* ------------------------ add KEYPAIR functions ------------------------- */
 int HSM_PKCS11_KEYPAIR_add_url ( PKI_X509_KEYPAIR *pk, URL *url, PKI_CRED *cred,
-							HSM *driver );
+							HSM *hsm );
 int HSM_PKCS11_KEYPAIR_STACK_add_url ( PKI_STACK *sk, URL *url, PKI_CRED *cred,
-							HSM *driver );
+							HSM *hsm );
 /* ------------------------ Find functions ------------------------------ */
 
 CK_OBJECT_HANDLE * HSM_PKCS11_X509_CERT_find_private_key ( PKI_X509_CERT *x,
diff -ur libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_hsm_pkey.h libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_hsm_pkey.h
--- libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_hsm_pkey.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_hsm_pkey.h	2023-07-14 16:39:36.332164739 +0200
@@ -5,7 +5,7 @@
 
 /* ------------------------ Key Management Functions --------------------- */
 PKI_X509_KEYPAIR *HSM_PKCS11_KEYPAIR_new( PKI_KEYPARAMS *kp,
-				URL *url, PKI_CRED *cred, HSM *driver );
+				URL *url, PKI_CRED *cred, HSM *hsm );
 
 void HSM_PKCS11_KEYPAIR_free ( PKI_X509_KEYPAIR *pkey );
 
diff -ur libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_utils.h libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_utils.h
--- libpki-0.8.9-orig/src/libpki/drivers/pkcs11/pkcs11_utils.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/drivers/pkcs11/pkcs11_utils.h	2023-07-14 16:39:36.332164739 +0200
@@ -57,7 +57,7 @@
 int HSM_PKCS11_set_attr_bool (CK_ATTRIBUTE_TYPE type,
 				CK_BBOOL value, CK_ATTRIBUTE *attribute );
 int HSM_PKCS11_set_attr_int ( CK_ATTRIBUTE_TYPE type,
-				int value, CK_ATTRIBUTE *attribute );
+				CK_ULONG value, CK_ATTRIBUTE *attribute );
 int HSM_PKCS11_set_attr_sn ( CK_ATTRIBUTE_TYPE type, char *value, 
 					size_t len,CK_ATTRIBUTE *attribute);
 int HSM_PKCS11_set_attr_bn ( CK_ATTRIBUTE_TYPE type, BIGNUM *bn, 
diff -ur libpki-0.8.9-orig/src/libpki/errors.h libpki-0.8.9/src/libpki/errors.h
--- libpki-0.8.9-orig/src/libpki/errors.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/errors.h	2024-06-27 14:27:17.400030806 +0200
@@ -148,7 +148,7 @@
 	{ PKI_ERR_POINTER_NULL, "Null Memory Pointer" },
 	{ PKI_ERR_PARAM_NULL, "Null Parameter" },
 	{ PKI_ERR_CALLBACK_NULL, "Missing or Null Callback" },
-	{ PKI_ERR_PARAM_TYPE, "Wrong Paramenter Type" },
+	{ PKI_ERR_PARAM_TYPE, "Wrong Parameter Type" },
 	{ PKI_ERR_PKI_FORMAT_UNKNOW, "Unknow PKI Format" },
 	{ PKI_ERR_DATA_FORMAT_UNKNOWN, "Unknown Data Format" },
 	/* PKI MEM Errors */
@@ -273,4 +273,6 @@
 #define PKI_ERROR_crypto_get_errno() HSM_get_errno(NULL)
 #define PKI_ERROR_crypto_get_errdesc() HSM_get_errdesc(HSM_get_errno(NULL),NULL)
 
+void PKI_strerror(int errnum, char *buf, size_t buflen);
+
 #endif
diff -ur libpki-0.8.9-orig/src/libpki/hsm_st.h libpki-0.8.9/src/libpki/hsm_st.h
--- libpki-0.8.9-orig/src/libpki/hsm_st.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/hsm_st.h	2023-07-14 16:39:36.336164739 +0200
@@ -138,25 +138,25 @@
 	char * (*get_errdesc)( unsigned long err, char *str, size_t size );
 
 	/* HSM initialization function */
-	int (*init) (struct hsm_st *driver, PKI_CONFIG *);
+	int (*init) (struct hsm_st *hsm, PKI_CONFIG *);
 
 	/* HSM free function */
-	int (*free) (struct hsm_st *driver, PKI_CONFIG *);
+	int (*free) (struct hsm_st *hsm, PKI_CONFIG *);
 
 	/* HSM login */
-	int (*login)(struct hsm_st *driver, PKI_CRED *cred);
+	int (*login)(struct hsm_st *hsm, PKI_CRED *cred);
 
 	/* HSM logout */
-	int (*logout)(struct hsm_st *driver);
+	int (*logout)(struct hsm_st *hsm);
 
 	/* HSM set algor function */
-	int (*select_algor) (struct hsm_st *driver, PKI_ALGOR *algor);
+	int (*select_algor) (struct hsm_st *hsm, PKI_ALGOR *algor);
 
 	/* HSM set fips mode */
-	int (*set_fips_mode) (const struct hsm_st *driver, int k);
+	int (*set_fips_mode) (const struct hsm_st *hsm, int k);
 
 	/* HSM gets fips operation mode */
-	int (*is_fips_mode) (const struct hsm_st *driver);
+	int (*is_fips_mode) (const struct hsm_st *hsm);
 
 	/* ------------- Signing functions --------------- */
 	/* General Signing function */
diff -ur libpki-0.8.9-orig/src/libpki/net/pki_mysql.h libpki-0.8.9/src/libpki/net/pki_mysql.h
--- libpki-0.8.9-orig/src/libpki/net/pki_mysql.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/net/pki_mysql.h	2023-07-14 16:39:36.344164740 +0200
@@ -12,13 +12,19 @@
 
 #endif /* HAVE_MYSQL */
 
+#define DB_MYSQL_PERSISTENT 1
+
+int db_init ( unsigned int flags );
+
 char *parse_url_table ( URL * url );
 char *parse_url_dbname ( URL *url );
 
 PKI_MEM_STACK *URL_get_data_mysql ( char *url_s, ssize_t size );
 PKI_MEM_STACK *URL_get_data_mysql_url ( URL *url, ssize_t size );
+PKI_MEM_STACK *URL_get_data_mysql_url_ex ( URL *url, ssize_t size, unsigned int timeout, int *error );
 
 int URL_put_data_mysql ( char *url_s, PKI_MEM *data );
 int URL_put_data_mysql_url ( URL *url, PKI_MEM *data );
+int URL_put_data_mysql_url_ex ( URL *url, PKI_MEM *data, unsigned int timeout, int *error );
 
 #endif /* _LIBPKI_URL_MYSQL_H */
diff -ur libpki-0.8.9-orig/src/libpki/net/url.h libpki-0.8.9/src/libpki/net/url.h
--- libpki-0.8.9-orig/src/libpki/net/url.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/net/url.h	2023-07-14 16:39:36.344164740 +0200
@@ -128,8 +128,12 @@
 /* ----------------------- URL wrapping functions ---------------------- */
 PKI_MEM_STACK *URL_get_data ( char *url_s, int timeout, 
 				ssize_t max_size, PKI_SSL *ssl );
+PKI_MEM_STACK *URL_get_data_ex ( char *url_s, int timeout, 
+				ssize_t max_size, PKI_SSL *ssl, int *error );
 PKI_MEM_STACK *URL_get_data_url ( URL *url, int timeout, 
 				ssize_t max_size, PKI_SSL *ssl );
+PKI_MEM_STACK *URL_get_data_url_ex ( URL *url, int timeout, 
+				ssize_t max_size, PKI_SSL *ssl, int *error );
 PKI_MEM_STACK *URL_get_data_socket ( PKI_SOCKET *sock, int timeout, 
 				ssize_t size );
 
@@ -141,6 +145,10 @@
 			PKI_MEM_STACK **ret_sk, int timeout, ssize_t max_size, 
 				PKI_SSL *ssl );
 
+int URL_put_data_url_ex ( URL *url, PKI_MEM *data, char *contType,
+			PKI_MEM_STACK **ret_sk, int timeout, ssize_t max_size, 
+				PKI_SSL *ssl, int *error );
+
 int URL_put_data_socket (PKI_SOCKET *sock, PKI_MEM *data, char *contType, 
 		PKI_MEM_STACK **ret_sk, int timeout, ssize_t max_size );
 
diff -ur libpki-0.8.9-orig/src/libpki/openssl/data_st.h libpki-0.8.9/src/libpki/openssl/data_st.h
--- libpki-0.8.9-orig/src/libpki/openssl/data_st.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/openssl/data_st.h	2023-07-14 16:39:36.344164740 +0200
@@ -162,6 +162,13 @@
 #define ENABLE_RSA_SHA_2
 #endif
 
+#ifdef NID_rsassaPss
+#define ENABLE_RSA_PSS
+#define PKI_ALGOR_RSA_PSS NID_rsassaPss
+#else
+#define PKI_ALGOR_RSA_PSS NID_undef
+#endif
+
 #ifdef ENABLE_SHA224
 #define PKI_ALGOR_RSA_SHA224	NID_sha224WithRSAEncryption
 #else
diff -ur libpki-0.8.9-orig/src/libpki/pki_init.h libpki-0.8.9/src/libpki/pki_init.h
--- libpki-0.8.9-orig/src/libpki/pki_init.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/pki_init.h	2023-07-14 16:39:36.352164740 +0200
@@ -7,6 +7,7 @@
 #define PKI_STATUS_INIT					1
 
 int PKI_init_all( void );
+void PKI_final_thread( void );
 void PKI_final_all ( void );
 
 int PKI_get_init_status ( void );
diff -ur libpki-0.8.9-orig/src/libpki/pki_log.h libpki-0.8.9/src/libpki/pki_log.h
--- libpki-0.8.9-orig/src/libpki/pki_log.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/pki_log.h	2023-07-14 16:39:36.352164740 +0200
@@ -65,6 +65,8 @@
 				PKI_LOG_FLAGS flags, PKI_TOKEN *tk );
 
 void PKI_log( int level, const char *fmt, ... );
+void PKI_log_ossl(void);
+void PKI_log_hexdump(int level, char *p_txt, int len, void *p_data);
 
 /* Macro To Automatically add [__FILE__:__LINE__] to the message */
 #define PKI_log_line(a, b, args...) \
diff -ur libpki-0.8.9-orig/src/libpki/pki_ocsp_resp.h libpki-0.8.9/src/libpki/pki_ocsp_resp.h
--- libpki-0.8.9-orig/src/libpki/pki_ocsp_resp.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/pki_ocsp_resp.h	2023-07-14 16:39:36.352164740 +0200
@@ -9,6 +9,7 @@
 #define PKI_X509_OCSP_RESP_mem_pem(a) \
         PKI_MEM_new_func( (void *) a, PEM_write_bio_OCSP_RESP )
 
+
 /* ---------------------------- Memory Management ----------------------- */
 
 PKI_OCSP_RESP *PKI_OCSP_RESP_new ( void );
@@ -22,8 +23,17 @@
 
 /* ---------------------------- Response Manipulation ------------------- */
 
+X509_EXTENSION *PKI_X509_OCSP_CERT_HASH_new(const EVP_MD *hashAlgo, int l_hash, unsigned char *p_hash);
+
 int PKI_X509_OCSP_RESP_set_status ( PKI_X509_OCSP_RESP *x, 
 					PKI_X509_OCSP_RESP_STATUS status );
+int PKI_X509_OCSP_RESP_add_ex ( PKI_X509_OCSP_RESP *resp, 
+			OCSP_CERTID *cid, PKI_OCSP_CERTSTATUS status,
+			PKI_TIME *revokeTime, PKI_TIME *thisUpdate,
+			PKI_TIME *nextUpdate, 
+			PKI_X509_CRL_REASON reason,
+			PKI_X509_EXTENSION *invalidityDate,
+			STACK_OF(X509_EXTENSION) *sk_ex );
 int PKI_X509_OCSP_RESP_add ( PKI_X509_OCSP_RESP *r, 
 			OCSP_CERTID *cid, PKI_OCSP_CERTSTATUS status,
 			PKI_TIME *revokeTime, PKI_TIME *thisUpdate,
diff -ur libpki-0.8.9-orig/src/libpki/pki_x509_data_st.h libpki-0.8.9/src/libpki/pki_x509_data_st.h
--- libpki-0.8.9-orig/src/libpki/pki_x509_data_st.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/pki_x509_data_st.h	2023-07-14 16:39:36.352164740 +0200
@@ -83,6 +83,10 @@
 	/* Callbacks */
 	const PKI_X509_CALLBACKS *cb;
 
+	/* Index for TYPE_*ex_ex_data functions inside OpenSSL */
+	/* Currently only one index is supported */
+	int idx;
+
 } PKI_X509;
 
 /* End of _LIBPKI_PKI_X509_DATA_ST_H */
diff -ur libpki-0.8.9-orig/src/libpki/token_st.h libpki-0.8.9/src/libpki/token_st.h
--- libpki-0.8.9-orig/src/libpki/token_st.h	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/libpki/token_st.h	2023-07-14 16:39:36.360164740 +0200
@@ -74,6 +74,9 @@
 	/*! Identifier for selected Key */
 	char *key_id;
 
+	/*! Signature options */
+	STACK_OF(OPENSSL_STRING) *sigopts;
+
 	/*! Identifier for selected Certificate */
 	char *cert_id;
 
diff -ur libpki-0.8.9-orig/src/net/http_s.c libpki-0.8.9/src/net/http_s.c
--- libpki-0.8.9-orig/src/net/http_s.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/net/http_s.c	2023-07-14 16:39:36.360164740 +0200
@@ -10,6 +10,8 @@
 
 #define HTTP_BUF_SIZE	65535
 
+#define MAX_LOG_TRACE_SIZE	128
+
 /* ----------------------------- AUXILLARY FUNCS ------------------------------ */
 
 
@@ -17,20 +19,25 @@
  * Returns the pointer to the end of the header, if found. Starts searching
  * from the provided offset or from the beginning if offset is < 0
  */
-char * __find_end_of_header(PKI_MEM *m, int offset)
+char * __find_end_of_header(PKI_MEM *m, ssize_t offset)
 {
 	ssize_t idx = 0;
+	ssize_t size = 0;
 	char * ret = NULL;
 	static char bytes[4] = { '\r', '\n', '\r', '\n' };
 
 	// Input check
 	if (!m || offset >= m->size) return NULL;
 
+	if (m->size <= 4) return NULL;
+
+	size = (ssize_t)m->size;
+
 	// Fix the offset if it is < 0
 	if (offset < 0) offset = 0;
 
 	// Looks for the eoh
-	for (idx = m->size - 4; idx >= offset; idx--)
+	for (idx = size - 4; idx >= offset; idx--)
 	{
 		int i, found;
 
@@ -57,9 +64,6 @@
  */
 int __parse_http_header(PKI_HTTP *msg)
 {
-	// Return Object container
-	int rv = PKI_OK;
-
     // Let's parse the first line of the HTTP message
     char *eol = NULL;
     char *method = NULL;
@@ -156,7 +160,6 @@
   	  else if(sscanf(http_version,"HTTP/%f", &msg->version) < 1)
   	  {
   		  PKI_log_debug("ERROR Parsing HTTP Version");
-  		  PKI_Free(http_version);
   		  PKI_Free(line);
 
   		  return PKI_ERR;
@@ -164,7 +167,7 @@
     }
     else
     {
-    	PKI_log_err("Unsupported HTTP Method detected (%s)", method);
+    	PKI_log_debug("Unsupported HTTP Method detected (%s)", method);
     	PKI_Free(line);
 
     	return PKI_ERR;
@@ -324,27 +327,22 @@
   {
 	  // Allocates a new MEM object
 	  m = PKI_MEM_new(max_size + 1);
-	  if (m == NULL)
-	  {
-		  PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
-		  return NULL;
-	  }
-
-	  // Let's make sure there is a 0 at the end of the buffer
-	  m->data[max_size] = '\x0';
-
-	  // Sets the free space in the buffer
-	  free = (ssize_t) max_size;
   }
   else
   {
 	  // Allocates the default buffer for HTTP messages
-	  m = PKI_MEM_new(HTTP_BUF_SIZE);
-
-	  // Sets the free space in the buffer
-	  free = (ssize_t) m->size;
+	  m = PKI_MEM_new(HTTP_BUF_SIZE + 1);
   }
 
+	if (m == NULL)
+	{
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+		return NULL;
+	}
+
+	// Sets the free space in the buffer
+	free = (ssize_t) m->size - 1;
+
   // Let's retrieve the data from the socket. Note that this for
   // always read at most 'free' bytes which carries the amount of
   // free space in the buffer -> safe
@@ -404,6 +402,7 @@
     		  {
     			  content_length = atoll(cnt_len_s);
     			  PKI_Free(cnt_len_s);
+    			  PKI_log_debug ( "HTTP Content-Length: %d bytes", content_length);
     		  }
     	  }
       } // End of if (!eoh) ...
@@ -417,16 +416,44 @@
     	  // We expand the mem if the buffer has less than 2K free
     	  if (free < 2048)
     	  {
+    			ssize_t ofs = 0;
+
+    		  if(body)
+    		  {
+    		    ofs = (ssize_t)(body - (char *)m->data);
+          
+    		    if(ofs < 0)
+    		    {
+    		      PKI_log_debug ( "Invalid offset for HTTP body: Start: %p - Body: %p", m->data, body);
+    		      PKI_ERROR(PKI_ERR_URI_READ, NULL);
+    		      goto err;
+    		    }
+    		  }
+
     		  // Grow the memory for the HTTP message
-    		  if (PKI_MEM_grow(m, HTTP_BUF_SIZE) != PKI_OK)
+    		  if(content_length > 0 && body && m->size < (size_t)(content_length + ofs))
     		  {
-    			  PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
-    			  break;
+            size_t len = ((size_t)(content_length + ofs) - m->size);
+
+    		    if (PKI_MEM_grow(m, len + 1) == PKI_ERR)
+    		    {
+    		      PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+    		      goto err;
+    		    }
+    		    free += (ssize_t)len;
+    		  }
+    		  else
+    		  {
+    		    if (PKI_MEM_grow(m, HTTP_BUF_SIZE) == PKI_ERR)
+    		    {
+    		      PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+    		      goto err;
+    		    }
+    		    free += HTTP_BUF_SIZE;
     		  }
 
-    		  // Let's update the free space by adding the newly
-    		  // allocated space
-    		  free += HTTP_BUF_SIZE;
+    		  // Let's update the pointer to the body
+    		  if(body) body = (char *)m->data + ofs;
     	  }
       }
 
@@ -450,7 +477,15 @@
   // an error and we return the malformed request message
   if (!eoh)
   {
-	  PKI_ERROR(PKI_ERR_URI_READ, NULL);
+	  // Only report when something was read
+	  if(idx != 0 || read > 0)
+	  {
+		  PKI_log (PKI_LOG_INFO, "Read data (so far): %d bytes - Last read: %d bytes", idx, read);
+			if(idx > MAX_LOG_TRACE_SIZE)
+				PKI_log_hexdump(PKI_LOG_INFO, "HTTP data read (truncated)", MAX_LOG_TRACE_SIZE, m->data);
+			else
+				PKI_log_hexdump(PKI_LOG_INFO, "HTTP data read", (int) idx, m->data);
+	  }
 	  goto err;
   }
 
@@ -460,17 +495,25 @@
 
   if (ret->method != PKI_HTTP_METHOD_GET && content_length > 0 && body)
   {
-	  size_t body_start = body - (char *)m->data;
-	  size_t body_size = idx - body_start;
-	  
+	  ssize_t body_start = (ssize_t)(body - (char *)m->data);
+	  ssize_t body_size = idx - body_start;
+
+	  if(body_start < 0 || body_size < 0)
+	  {
+		  PKI_log_err ( "Invalid offset for HTTP body - body_start: %d bytes - body_size: %d bytes", body_start, body_size);
+		  PKI_ERROR(PKI_ERR_URI_READ, NULL);
+		  goto err;
+	  }
+ 
 	  //Check if Content-Length > 0 but body_size is 0
 	  if (body_size == 0) goto err; 
 	  // Let's allocate the body for the HTTP message (if any)
-	  ret->body = PKI_MEM_new_data(body_size, (unsigned char *)body);
-
-	  // Let's cheat and add a final NULL char (but not reflected in the size reported
-	  // by the object (i.e., it will not be copied using the normal dup functions)
-	  ret->body->data[body_size] = '\x0';
+	  ret->body = PKI_MEM_new_data((size_t)body_size+1, (unsigned char *)body);
+		if(ret->body == NULL)
+		{
+			PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+			goto err;
+		}
 	  ret->body->size = (size_t) body_size;
   }
   else
@@ -566,14 +609,6 @@
 			"Content-Length: %d\r\n"
 			"%s";
 
-	char *head_http =
-			"HTTP/%f %d\r\n"
-			"Host: %s\r\n"
-			"Connection: close\r\n"
-			"Content-type: %s\r\n"
-			"Content-Length: %d\r\n"
-			"%s";
-
 	char *head = NULL;
 
 	if ( timeout < 0 ) timeout = 0;
@@ -588,7 +623,7 @@
 
 		// Special case for when a usr/pwd was specified in the URL
 		auth_tmp = PKI_Malloc(len);
-		auth_len = snprintf(auth_tmp, len, "Authentication: user %s:%s\r\n\r\n", sock->url->usr, sock->url->pwd);
+		auth_len = (size_t)snprintf(auth_tmp, len, "Authentication: user %s:%s\r\n\r\n", sock->url->usr, sock->url->pwd);
 	}
 	else
 	{
diff -ur libpki-0.8.9-orig/src/net/mysql.c libpki-0.8.9/src/net/mysql.c
--- libpki-0.8.9-orig/src/net/mysql.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/net/mysql.c	2025-09-17 18:04:37.834295403 +0200
@@ -7,6 +7,18 @@
  
  
 #include <libpki/pki.h>
+#include <mysql/errmsg.h>
+
+static int db_persistent = 0;
+static pthread_mutex_t mysql_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int db_init ( unsigned int flags )
+{
+	if(flags & DB_MYSQL_PERSISTENT)
+		db_persistent = 1;
+
+	return(0);
+}
 
 char *parse_url_query ( URL * url ) {
 
@@ -37,6 +49,7 @@
 	}
 
 	if((buf = PKI_MEM_new_null()) == NULL ) {
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		return ( NULL );
 	}
 
@@ -72,18 +85,12 @@
 	} fprintf( stderr, "\n");
 */
 
-		/*
-		strncat( buf, col, BUFF_MAX_SIZE - strlen(buf) );
-		strncat( buf, "='", BUFF_MAX_SIZE - strlen(buf) );
-		strncat( buf, val, BUFF_MAX_SIZE - strlen(buf) );
-		strncat( buf, "'", BUFF_MAX_SIZE - strlen(buf) );
-		*/
-
 		/* This triggers the adding of AND on the next iteration */
 		add_and = 1;
 	}
 
 	if( (ret = PKI_Malloc (buf->size+1)) == NULL ) {
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		PKI_MEM_free ( buf );
 		return( NULL );
 	}
@@ -131,6 +138,7 @@
 	}
 
 	if((buf = PKI_MEM_new_null()) == NULL ) {
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		return ( NULL );
 	}
 
@@ -185,20 +193,14 @@
 		PKI_MEM_add( buf, val, strlen( val ));
 		PKI_MEM_add( buf, "' ", 2 );
 
-		/*
-		strncat( buf, col, BUFF_MAX_SIZE - strlen(buf) );
-		strncat( buf, "='", BUFF_MAX_SIZE - strlen(buf) );
-		strncat( buf, val, BUFF_MAX_SIZE - strlen(buf) );
-		strncat( buf, "'", BUFF_MAX_SIZE - strlen(buf) );
-		*/
-
 		/* This triggers the adding of AND on the next iteration */
 		add_and = 1;
 	}
 
 	PKI_Free (table);
 
-	if( (ret = PKI_Malloc(buf->size) + 1) == NULL ) {
+	if( (ret = PKI_Malloc(buf->size + 1)) == NULL ) {
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		if( buf ) PKI_MEM_free ( buf );
 		return( NULL );
 	}
@@ -233,6 +235,7 @@
 	}
 
 	if((ret = PKI_Malloc ( size + 1 )) == NULL ) {
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		return(NULL);
 	}
 
@@ -251,11 +254,13 @@
 	if( !url || !url->path ) return (NULL);
 
 	if((tmp_s = strchr( url->path, '/')) == NULL ) {
+		PKI_log_err("Can not parse dbname in URL: %s", url->path);
 		return (NULL);
 	}
 
 	size = (size_t) (tmp_s - url->path);
 	if((ret = PKI_Malloc ( size + 1 )) == NULL ) {
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		return(NULL);
 	}
 
@@ -267,35 +272,54 @@
 
 #ifdef HAVE_MYSQL
 
-MYSQL *db_connect ( URL *url ) {
+static MYSQL *db_connect_ex ( URL *url, unsigned int timeout, int *error ) {
 
 	MYSQL *sql = NULL;
-	char * table = NULL;
 	char * dbname = NULL;
+	static int failed = 0;
+
+
+	if( (dbname = parse_url_dbname ( url )) == NULL) {
+		return NULL;
+	}
 
 	if( (sql = mysql_init( NULL )) == NULL ) {
+		PKI_log_err("Initializing MySQL failed.");
 		return NULL;
 	}
 
-	dbname = parse_url_dbname ( url );
-	table = parse_url_table ( url );
+	if(timeout != 0) {
+		if(mysql_options(sql, MYSQL_OPT_CONNECT_TIMEOUT, (const void *)&timeout)) {
+			PKI_log_err("Setting MYSQL_OPT_CONNECT_TIMEOUT(%d seconds) failed", timeout);
+			if( dbname ) PKI_Free ( dbname );
+			db_close( sql );
+			return NULL;
+    }
+	}
 
-	/* The old mysql_connect is no more supported, it seems! */
-	/* mysql_connect( sql, url->addr, url->usr, url->pwd ); */
 	if((mysql_real_connect(sql, url->addr, url->usr, url->pwd,
 			dbname, (unsigned int) url->port, NULL, 0 )) == NULL ) {
 		if( dbname ) PKI_Free ( dbname );
+		if(!failed) PKI_log_err("Connecting to MySQL DB failed: %s",  mysql_error(sql));
+		if(error) *error = (int)mysql_errno(sql);
 		db_close( sql );
+		failed = 1;
 		return( NULL );
 	}
+	failed = 0;
 
 	if( dbname ) PKI_Free (dbname);
-	if( table ) PKI_Free (table);
 
 	return( sql );
 
 }
 
+MYSQL *db_connect ( URL *url ) {
+
+	return(db_connect_ex(url, 0, NULL));
+
+}
+
 int db_close ( MYSQL *sql ) {
 
 	if( !sql ) return (PKI_ERR);
@@ -343,7 +367,7 @@
 	return ret;
 }
 
-PKI_MEM_STACK *URL_get_data_mysql_url ( URL *url, ssize_t size ) {
+PKI_MEM_STACK *URL_get_data_mysql_url_ex ( URL *url, ssize_t size, unsigned int timeout, int *error ) {
 
 #ifdef HAVE_MYSQL
 	MYSQL_ROW row;
@@ -351,9 +375,10 @@
 	MYSQL_FIELD *fields = NULL;
 	MYSQL_RES *res = NULL;
 
+	int err;
 	unsigned long *lengths = NULL;
 	long long n_rows = 0;
-	int n_fields = 0;
+	unsigned int n_fields = 0;
 
 	PKI_MEM *tmp_mem = NULL;
 	PKI_MEM_STACK *sk = NULL;
@@ -362,7 +387,7 @@
 
 	if( !url ) return (NULL);
 
-	if((sql = db_connect ( url )) == NULL )
+	if((sql = db_connect_ex ( url, timeout, error )) == NULL )
 	{
 		return NULL;
 	}
@@ -372,26 +397,103 @@
 		PKI_log_err("Can not parse URL query");
 		goto end;
 	}
-	else mysql_query(sql, query);
 
-	/* Get the Data */
-	if((res = mysql_store_result( sql )) == NULL)
+	//PKI_log_debug("SQL QUERY: %s\n", query);
+
+
+	if(db_persistent)
+	{
+		int retry = 2;
+
+
+retry:
+		pthread_mutex_lock(&mysql_mutex);
+
+		if(( err = mysql_query(sql, query )) != 0 )
+		{
+			pthread_mutex_unlock(&mysql_mutex);
+
+			switch(err)
+			{
+				case CR_SERVER_GONE_ERROR:
+				case CR_SERVER_LOST:
+					PKI_log_err("mysql_query failed: [%d] %s - try again", err, mysql_error(sql));
+					db_close( sql );
+					if((sql = db_connect_ex ( url, timeout, error )) != 0 )
+					{
+						PKI_log_err("db_connect() retry failed");
+						goto end;
+					}
+
+					if(retry)
+					{
+						retry--;
+						goto retry;
+					}
+					else
+					{
+						PKI_log_err("db_connect() retry failed");
+						goto end;
+					}
+
+				default:
+					PKI_log_err("mysql_query failed: [%d] %s", err, mysql_error(sql));
+					goto end;
+			}
+		}
+
+		/* Get the Data */
+		res = mysql_store_result( sql );
+
+		pthread_mutex_unlock(&mysql_mutex);
+	}
+	else
+	{
+		if(( err = mysql_query(sql, query )) != 0 )
+		{
+			PKI_log_err("mysql_query failed: [%d] %s", err, mysql_error(sql));
+			goto end;
+		}
+
+		/* Get the Data */
+		res = mysql_store_result( sql );
+	}
+
+	err = -1; // use variable as error indicator
+
+	if(res == NULL)
 	{
 		PKI_log_err("Can not retrieve SQL data");
 		goto end;
 	}
 
-	if( ((n_rows = (long long) mysql_num_rows( res )) < 1 ) || 
-			((sk = PKI_STACK_MEM_new()) == NULL))
+	if( (n_rows = (long long) mysql_num_rows( res )) < 1 )
+	{
+		PKI_log_debug("No returned rows found");
+		goto end;
+	}
+
+	PKI_log_debug("URL_get_data_mysql_url(): Number of returned rows: %d", n_rows);
+
+	if( (sk = PKI_STACK_MEM_new()) == NULL)
+	{
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+		goto end;
+	}
+
+	if( (n_fields = mysql_num_fields( res ) ) == 0)
 	{
-		PKI_log_err("No returned rows found");
+		PKI_log_err("URL_get_data_mysql_url(): mysql_num_fields() returned no columns from the result set");
 		goto end;
 	}
 
 	while((row = mysql_fetch_row(res)) != NULL )
 	{
+		unsigned int i;
+
 		/* Count the number of fields retrieved */
-		n_fields = (int) mysql_num_fields( res );
+		PKI_log_debug("SQL QUERY: Number of returned fields: %d", n_fields);
+
 		lengths = mysql_fetch_lengths( res );
 		fields = mysql_fetch_fields( res );
 		if (!fields)
@@ -400,24 +502,44 @@
 			break;
 		}
 
-		if (n_fields > 0)
+
+		for(i = 0; i < n_fields; i++)
 		{
-			tmp_mem = PKI_MEM_new_null();
-			if (size == 0 || (( size > 0 ) && ( lengths[0] < size)))
+			if (size == 0 || (( size > 0 ) && ( lengths[i] < size)))
 			{
-				PKI_MEM_add(tmp_mem,row[0],lengths[0]);
+				if( (tmp_mem = PKI_MEM_new_null()) == NULL)
+				{
+					PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+					goto end;
+				}
+			}
+
+			PKI_log_hexdump(PKI_LOG_INFO, "QUERY RESULT:", (int)lengths[i], row[i]);
 
-				/* For now, let's only deal with one 
-				   field at the time */
-				PKI_STACK_push( sk, tmp_mem );
+			if(lengths[i] != 0 && PKI_MEM_add(tmp_mem, row[i], lengths[i]) != PKI_OK)
+			{
+				PKI_log_err("URL_get_data_mysql_url(): PKI_MEM_add() failed");
+				goto end;
+			}
+    
+			if(!PKI_STACK_push( sk, tmp_mem ))
+			{
+				PKI_log_err("URL_get_data_mysql_url(): PKI_STACK_push() failed");
+				goto end;
 			}
 		}
 	}
 
+	err = 0;
 end:
 
+	if(err) {
+		PKI_STACK_MEM_free_all(sk);
+		sk = NULL;
+	}
 	if (query) PKI_Free (query);
-	db_close ( sql );
+	if(!db_persistent) db_close( sql );
+	if(res) mysql_free_result(res);
 
 	return ( sk );
 
@@ -426,6 +548,11 @@
 #endif
 }
 
+PKI_MEM_STACK *URL_get_data_mysql_url ( URL *url, ssize_t size ) {
+	return(URL_get_data_mysql_url_ex(url, size, 0, NULL));
+}
+
+
 int URL_put_data_mysql ( char *url_s, PKI_MEM *data ) {
 
 	int ret = 0;
@@ -463,7 +590,7 @@
 	return ret;
 }
 
-int URL_put_data_mysql_url ( URL *url, PKI_MEM *data ) {
+int URL_put_data_mysql_url_ex ( URL *url, PKI_MEM *data, unsigned int timeout, int *error ) {
 
 #ifdef HAVE_MYSQL
 	MYSQL * sql = NULL;
@@ -476,20 +603,23 @@
 		return( PKI_ERR );
 	}
 
-	if((sql = db_connect ( url )) == NULL ) {
+	if((sql = db_connect_ex ( url, timeout, error )) == NULL ) {
 		PKI_Free( query );
 		return(PKI_ERR);
 	}
 
+	PKI_log_debug("SQL query: %s", query);
+
 	if(mysql_query(sql, query ) != 0 ) {
+		PKI_log_err("mysql_query failed: %s", mysql_error(sql));
 		PKI_Free ( query );
-		db_close( sql );
+		if(!db_persistent) db_close( sql );
 
 		return( PKI_ERR );
 	}
 
 	PKI_Free (query);
-	db_close ( sql );
+	if(!db_persistent) db_close( sql );
 
 	return ( PKI_OK );
 
@@ -497,3 +627,10 @@
 	return ( PKI_ERR );
 #endif
 }
+
+
+int URL_put_data_mysql_url ( URL *url, PKI_MEM *data ) {
+
+	return ( URL_put_data_mysql_url_ex ( url, data, 0, NULL ));
+}
+
diff -ur libpki-0.8.9-orig/src/net/pki_socket.c libpki-0.8.9/src/net/pki_socket.c
--- libpki-0.8.9-orig/src/net/pki_socket.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/net/pki_socket.c	2023-07-14 16:39:36.360164740 +0200
@@ -125,8 +125,11 @@
 	}
 	else
 	{
+		char err_str[128];
+
+		PKI_strerror ( errno, err_str, sizeof(err_str));
 		PKI_log_err ( "Can not connect to %s:%d (%s)",
-			url->addr, url->port, strerror (errno));
+			url->addr, url->port, err_str);
 		return PKI_ERR;
 	}
 
diff -ur libpki-0.8.9-orig/src/net/sock.c libpki-0.8.9/src/net/sock.c
--- libpki-0.8.9-orig/src/net/sock.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/net/sock.c	2023-07-14 16:39:36.360164740 +0200
@@ -17,9 +17,14 @@
 
 int _Socket (int family, int type, int protocol) {
 	int n;
+	char err_str[128];
+
 	if ( (n = socket(family,type,protocol)) < 0)
-		PKI_log( PKI_LOG_ERR, "Can not Init Socket (%s)",
-			hstrerror(h_errno));
+	{
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log( PKI_LOG_ERR, "Can not initialize socket: [%d] %s", errno, err_str);
+	}
+
 	return n;
 }
 
@@ -29,6 +34,7 @@
 	int fd = 0;
 	int reuse_addr = 1;
 	int ret = 0;
+	char err_str[128];
 
 	struct addrinfo *res, *rp;
 	struct addrinfo hints;
@@ -72,8 +78,8 @@
 
 		if(setsockopt(fd, SOL_SOCKET,  SO_REUSEADDR,  &reuse_addr, 
 					sizeof(reuse_addr)) == -1 ) {
-			// PKI_log( PKI_LOG_ERR, "Can not Set Socket Options [%s]",
-			// 	hstrerror(h_errno));
+			PKI_strerror ( errno, err_str, sizeof(err_str));
+			PKI_log( PKI_LOG_ERR, "Can not set socket option (SO_REUSEADDR): [%d] %s", errno, err_str);
 			close(fd);
 			continue;
 		}
@@ -90,8 +96,8 @@
 
 	if (bind(fd, rp->ai_addr, rp->ai_addrlen) == -1 )
 	{
-		PKI_log_err("Can not bind to %s:%d (%s)", hostname, port,
-			hstrerror(h_errno));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log_err("Can not bind to %s:%d [%d] %s", hostname, port, errno, err_str);
 		close ( fd );
 		freeaddrinfo ( res );
 		return ( -1 );
@@ -105,7 +111,8 @@
 	/* Here we listen on the fd */
 	if (listen(fd, LISTENQ) == -1)
 	{
-		PKI_log_err("Can not listen to fd (%s)", hstrerror(h_errno));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log_err("Can not listen to socket: [%d] %s", errno, err_str);
 		close ( fd );
 		return(-1);
 	}
@@ -140,10 +147,9 @@
 		if (INTERRUPTED_BY_SIGNAL)
 			goto again;
 
-		PKI_log(PKI_LOG_ERR,"[%d:%ld:%d] Error while (ACCEPT) [%s:%s]",
-			n, h_errno, errno, hstrerror( h_errno ), 
-				strerror(errno));
-  	}
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log(PKI_LOG_ERR,"Error while (ACCEPT): [%d] %s]", errno, err_str);
+	}
 	return(n);
 }
 */
@@ -151,6 +157,7 @@
 ssize_t _Read (int fd, void *bufptr, size_t nbytes) {
 
 	ssize_t n;
+	char err_str[128];
 
 again:
 	if ((n = read(fd,bufptr,nbytes)) < 0)
@@ -161,8 +168,8 @@
 		}
 		else
 		{
-			PKI_log(PKI_LOG_ERR, "Socket Read failed [%d:%s]",
-					h_errno, hstrerror(h_errno));
+			PKI_strerror ( errno, err_str, sizeof(err_str));
+			PKI_log(PKI_LOG_ERR, "Socket read failed [%d:%s]", errno, err_str);
 		}
 	}
 	return(n);
@@ -171,6 +178,7 @@
 ssize_t _Write (int fd, void *bufptr, size_t nbytes) {
 
 	ssize_t n;
+	char err_str[128];
 
 again:
 	if ((n = write(fd,bufptr,nbytes)) < 0)
@@ -181,53 +189,68 @@
 		}
 		else
 		{
-			PKI_log_err( "Socket Write failed [%d:%s]!", h_errno, hstrerror(h_errno));
+			PKI_strerror ( errno, err_str, sizeof(err_str));
+			PKI_log(PKI_LOG_INFO, "Socket write failed [%d:%s]!", errno, err_str);
 		}
 	}
 	return(n);
 }
 
 int _Select (int maxfdp1, fd_set *readset, fd_set *writeset, 
-			fd_set *exceptset, struct timeval *timeout) {
-
+			fd_set *exceptset, struct timeval *timeout)
+{
 	int n;
+	char err_str[128];
+
 again:
 	if ( (n = select (maxfdp1, readset, writeset, 
-				exceptset, timeout)) < 0) {
+				exceptset, timeout)) < 0)
+	{
 		if (INTERRUPTED_BY_SIGNAL)
 			goto again;
-		else
-			PKI_log( PKI_LOG_ERR, "Select failed!");
-  	}
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log( PKI_LOG_ERR, "Select failed: [%d] %s", errno, err_str);
+	}
 	return(n);
 }
 
 int _Connect (int sockfd, const SA *srvaddr, socklen_t addrlen)
 {
+	char err_str[128];
+
 	if (connect(sockfd, srvaddr, addrlen) != 0)
 	{
-		PKI_log(PKI_LOG_ERR, "Socket Connect failed (%s)!", 
-			hstrerror(h_errno));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log(PKI_LOG_ERR, "Socket connect failed: [%d] %s", errno, err_str);
 		return(PKI_ERR);
 	}
 	return ( PKI_OK );
 }
 
 
-int _Close (int fd) {
-  	if (close(fd) != 0) {
-		PKI_log(PKI_LOG_ERR, "Socket Close failed (%s)!", 
-			hstrerror(h_errno));
+int _Close (int fd)
+{
+	char err_str[128];
+
+	if (close(fd) != 0)
+	{
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log(PKI_LOG_ERR, "Socket close failed: [%d] %s", errno, err_str);
 		return(0);
 	}
 	return( 1 );
 }
 
 
-void _Shutdown (int fd, int howto) {
+void _Shutdown (int fd, int howto)
+{
+	char err_str[128];
+
 	if (shutdown(fd,howto) != 0)
-		PKI_log(PKI_LOG_ERR, "Socket Shutdown failed (%s)!", 
-			hstrerror(h_errno));
+	{
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log(PKI_LOG_ERR, "Socket Shutdown failed: [%d] %s)", errno, err_str);
+	}
 
 	return;
 }
@@ -248,6 +271,7 @@
 
 	int sockfd;
 	int ret = 0;
+	char err_str[128];
 
 	struct addrinfo *res, *rp;
 	struct addrinfo hints;
@@ -286,8 +310,8 @@
 
 	/* try to connect */
 	if(( ret = _Connect(sockfd, rp->ai_addr, rp->ai_addrlen )) == PKI_ERR ) {
-		PKI_log( PKI_LOG_ERR, "Socket _Connect failed (%s)",
-							hstrerror( h_errno ));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log( PKI_LOG_ERR, "Socket _Connect failed: [%d] %s", errno, err_str);
 
 		_Close ( sockfd );
 		freeaddrinfo ( res );
@@ -349,14 +373,15 @@
 	struct timeval *time_out_pnt = NULL;
 	fd_set          readset;
 	int             sel_ret;
+	char            err_str[128];
 
 	// Initialization
 	len=sizeof( struct sockaddr );
 
 	// Set the nonblocking status
 	if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
-		PKI_log_err("PKI_NET_accept()::Cannot set non-blocking "
-					"socket [%s]", hstrerror( h_errno));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log_err("PKI_NET_accept()::Cannot set non-blocking socket: [%d] %s", errno, err_str);
 		return -1;
 	}
 
@@ -374,29 +399,24 @@
 		} else {
 			time_out_pnt = &time_out;
 			time_out.tv_sec = timeout;
-        		time_out.tv_usec = 0;
+			time_out.tv_usec = 0;
 		};
 
 		sel_ret = select(sock+1, &readset, NULL, NULL, time_out_pnt);
 
-		if (sel_ret == -1 && errno == EINTR) {
-			char buf[512];
-			if(strerror_r ( errno, buf, sizeof(buf)) == 0 ) {
-				PKI_log_debug("Select Recoverable [%s]",
-					buf);
+		if (sel_ret < 0) {
+			PKI_strerror ( errno, err_str, sizeof(err_str));
+			if(errno == EINTR) {
+				PKI_log_debug("Select failed (recoverable): [%d] %s", errno, err_str);
+				continue;
 			} else {
-				PKI_log_debug("Select Recoverable");
-			};
-			continue;
+				PKI_log_debug("Select failed: [%d] %s", errno, err_str);
+				return -1;
+			}
 		}
 
-		if( sel_ret < 0 ) {
-			PKI_log_debug("ERROR, Select %s", strerror(errno));
-			return -1;
-		};
-
 		if( (timeout > 0 ) && ( sel_ret == 0 ) ) {
-			PKI_log_debug("ERROR, Socket connection t-out");
+			PKI_log_err("socket connection timed out after %d seconds", timeout);
 			return -1;
 		};
  
@@ -409,9 +429,8 @@
 					continue;
 				};
 
-				PKI_log(PKI_LOG_ERR,"[%d:%ld:%d] Error while (ACCEPT) [%s:%s]",
-					n, h_errno, errno, hstrerror( h_errno ), 
-					strerror(errno));
+				PKI_strerror ( errno, err_str, sizeof(err_str));
+				PKI_log(PKI_LOG_ERR, "Error while (ACCEPT): [%d] %s]", errno, err_str);
 			}
 			break;
 		}
@@ -448,10 +467,11 @@
 	struct timeval *time_out_pnt = NULL;
 	fd_set          readset;
 	int             sel_ret;
+	char            err_str[128];
 	
 	if (fcntl( fd, F_SETFL, O_NONBLOCK) < 0) {
-		PKI_log_err("PKI_NET_accept()::Cannot set non-blocking "
-			"socket [%s]", hstrerror( h_errno));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log_err("PKI_NET_read()::Cannot set non-blocking socket: [%d] %s", errno, err_str);
 		return -1;
 	}
 
@@ -472,18 +492,19 @@
 
 		sel_ret = select(fd+1, &readset, NULL, NULL, time_out_pnt);
 
-		if (sel_ret == -1 && errno == EINTR) {
-			PKI_log_debug("ERROR, Select Recoverable [%s]", strerror(errno));
-			continue;
+		if (sel_ret < 0) {
+			PKI_strerror ( errno, err_str, sizeof(err_str));
+			if(errno == EINTR) {
+				PKI_log_debug("Select failed (recoverable): [%d] %s", errno, err_str);
+				continue;
+			} else {
+				PKI_log_debug("Select failed: [%d] %s", errno, err_str);
+				return -1;
+			}
 		}
 
-		if( sel_ret < 0 ) {
-			PKI_log_debug("ERROR, Select %s", strerror(errno));
-			return -1;
-		};
-
 		if( (timeout > 0 ) && (sel_ret == 0) ) {
-			PKI_log_debug("ERROR, Socket connection t-out");
+			PKI_log(PKI_LOG_INFO, "PKI_NET_read::socket connection timed out after %d seconds", timeout);
 			return -1;
 		}
 
@@ -497,6 +518,8 @@
 					PKI_log_debug("Network error, EWOULDBLOCK");
 					continue;
 				}
+				PKI_strerror ( errno, err_str, sizeof(err_str));
+				PKI_log(PKI_LOG_INFO, "PKI_NET_read::recv() failed: [%d] %s", errno, err_str);
 				break;
 			} else {
 				//PKI_log_debug("Read %d bytes from socket", n);
diff -ur libpki-0.8.9-orig/src/net/ssl.c libpki-0.8.9/src/net/ssl.c
--- libpki-0.8.9-orig/src/net/ssl.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/net/ssl.c	2023-07-14 16:39:36.360164740 +0200
@@ -656,7 +656,7 @@
 		ret->algor = PKI_SSL_CLIENT_ALGOR_DEFAULT;
 	}
 
-	if ((ret->ssl_ctx = SSL_CTX_new(ret->algor)) == 0) 
+	if ((ret->ssl_ctx = SSL_CTX_new((SSL_METHOD *)ret->algor)) == 0) 
 	{
 		PKI_log_debug("Can not create a new PKI_SSL object (%s)",
 				ERR_error_string(ERR_get_error(), NULL ));
diff -ur libpki-0.8.9-orig/src/net/url.c libpki-0.8.9/src/net/url.c
--- libpki-0.8.9-orig/src/net/url.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/net/url.c	2023-07-14 16:39:36.360164740 +0200
@@ -42,7 +42,7 @@
 	{ URI_PROTO_PG, "pg"},
 	{ URI_PROTO_PKCS11, "pkcs11" },
 	{ URI_PROTO_SOCK, "sock" },
-	{ URI_PROTO_SOCK, "dns" },
+	{ URI_PROTO_DNS, "dns" },
 	{ 0, NULL }
 };
 
@@ -185,11 +185,14 @@
 	PKI_MEM * obj = NULL;
 	off_t file_size = 0;
 	int fd = 0;
+	char err_str[128];
 
 	if( !url ) return (NULL);
 	if( url->proto != URI_PROTO_FILE ) return (NULL);
 
 	if((fd = open( url->addr, O_RDONLY)) == -1 ) {
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_log_debug( "URL_get_data_file(): open file %s failed: [%d] %s", url->addr, errno, err_str);
 		return (NULL);
 	}
 
@@ -237,8 +240,8 @@
  * In case of failure NULL is returned.
  */
 
-PKI_MEM_STACK *URL_get_data ( char *url_s, int timeout, 
-					ssize_t size, PKI_SSL *ssl ) {
+PKI_MEM_STACK *URL_get_data_ex ( char *url_s, int timeout, 
+					ssize_t size, PKI_SSL *ssl, int *error ) {
 
 	URL *url = NULL;
 	PKI_MEM_STACK *ret = NULL;
@@ -248,12 +251,17 @@
 		return (NULL);
 	}
 
-	ret = URL_get_data_url( url, timeout, size, ssl );
+	ret = URL_get_data_url_ex( url, timeout, size, ssl, error );
 
 	if( url ) URL_free ( url );
 	return ret;
 }
 
+PKI_MEM_STACK *URL_get_data ( char *url_s, int timeout, 
+					ssize_t size, PKI_SSL *ssl ) {
+	return(URL_get_data_ex(url_s, timeout, size, ssl, NULL));
+}
+
 /*!
  * \brief Returns a PKI_MEM_STACK filled with data from the passed URL object
  *
@@ -269,8 +277,8 @@
  * URI_PROTO_PKCS11, URI_PROTO_ID.
  */
 
-PKI_MEM_STACK *URL_get_data_url ( URL *url, int timeout, 
-				ssize_t size, PKI_SSL *ssl ) {
+PKI_MEM_STACK *URL_get_data_url_ex ( URL *url, int timeout, 
+				ssize_t size, PKI_SSL *ssl, int *error ) {
 
 	PKI_MEM_STACK * ret = NULL;
 
@@ -297,7 +305,7 @@
 #endif
 #ifdef HAVE_MYSQL
 		case URI_PROTO_MYSQL:
-			ret = URL_get_data_mysql_url( url, size );
+			ret = URL_get_data_mysql_url_ex( url, size, (unsigned int)timeout, error );
 			break;
 #endif
 #ifdef HAVE_PG
@@ -323,6 +331,12 @@
 	return ( ret );
 }
 
+PKI_MEM_STACK *URL_get_data_url ( URL *url, int timeout, 
+				ssize_t size, PKI_SSL *ssl ) {
+
+	return (URL_get_data_url_ex(url, timeout, size, ssl, NULL));
+}
+
 /*!
  * \brief Returns a PKI_MEM_STACK filled with data from a PKI_SOCKET 
  *
@@ -426,13 +440,15 @@
 int URL_put_data_fd ( URL *url, PKI_MEM *data ) {
 
 	int fd = 0;
+	char err_str[128];
 
 	if( !url || !data || url->port < 1 ) return ( PKI_ERR );
 
 	fd = url->port;
 
 	if(_Write( fd, data->data, data->size ) < 0 ) {
-		PKI_ERROR(PKI_ERR_GENERAL, strerror(errno));
+		PKI_strerror ( errno, err_str, sizeof(err_str));
+		PKI_ERROR(PKI_ERR_GENERAL, err_str);
 		return ( PKI_ERR );
 	}
 
@@ -461,9 +477,9 @@
 	
 }
 
-int URL_put_data_url (URL *url, PKI_MEM *data, char *contType, 
+int URL_put_data_url_ex (URL *url, PKI_MEM *data, char *contType, 
 		PKI_MEM_STACK **ret_sk, int timeout, ssize_t max_size,
-			PKI_SSL *ssl ) {
+			PKI_SSL *ssl, int *error ) {
 
 	int ret = PKI_OK;
 
@@ -491,7 +507,7 @@
 		// 	break;
 #ifdef HAVE_MYSQL
 		case URI_PROTO_MYSQL:
-			ret = URL_put_data_mysql_url( url, data );
+			ret = URL_put_data_mysql_url_ex( url, data, (unsigned int)timeout, error );
 			break;
 #endif
 #ifdef HAVE_PG
@@ -512,6 +528,12 @@
 	return ( ret );
 }
 
+int URL_put_data_url (URL *url, PKI_MEM *data, char *contType, 
+		PKI_MEM_STACK **ret_sk, int timeout, ssize_t max_size,
+			PKI_SSL *ssl ) {
+
+	return ( URL_put_data_url_ex (url, data, contType, ret_sk, timeout, max_size, ssl, NULL ));
+}
 
 int URL_put_data_socket (PKI_SOCKET *sock, PKI_MEM *data, char *contType, 
 		PKI_MEM_STACK **ret_sk, int timeout, ssize_t max_size ) {
@@ -873,14 +895,12 @@
 
 					if( (tmp_s5 = strchr(tmp_s3, ')')) 
 								== NULL) {
-						URL_free( ret );
-						return(NULL);
+						goto err;
 					}
 					tmp_s3++;
 					tmp_s6 = strchr(tmp_s3, '=');
 					if( tmp_s6 > tmp_s5 ) {
-						URL_free( ret );
-						return(NULL);
+						goto err;
 					}
 					tmp_s6 = (char *) malloc ( tmp_s5 - tmp_s3+1);
 					memset( tmp_s6, 0, tmp_s5 - tmp_s3 + 1);
@@ -1026,14 +1046,12 @@
 
 					if( (tmp_s5 = strchr(tmp_s3, ')')) 
 								== NULL) {
-						URL_free( ret );
-						return(NULL);
+						goto err;
 					}
 					tmp_s3++;
 					tmp_s6 = strchr(tmp_s3, '=');
 					if( tmp_s6 > tmp_s5 ) {
-						URL_free( ret );
-						return(NULL);
+						goto err;
 					}
 					tmp_s6 = (char *) malloc ( tmp_s5 - tmp_s3+1);
 					memset( tmp_s6, 0, tmp_s5 - tmp_s3 + 1);
@@ -1196,7 +1214,7 @@
 				tmp_s2 = strchr( tmp_s, ':' );
 
 				if( !tmp_s2 || (tmp_s3 < tmp_s2)) {
-					return (NULL);
+					goto err;
 				}
 				len = (int) ( (long) tmp_s2 - (long) tmp_s );
 				ret->usr = (char *) malloc (len+1);
@@ -1231,8 +1249,7 @@
 			ret->port = atoi( tmp_s );
 			if( ret->port == 0 ) {
 				Error in parsing the port number!
-				URL_free ( ret );
-				return(NULL);
+				goto err;
 			}
 
 			if( (tmp_s2 = strchr( tmp_s, '/' )) != NULL ) {
diff -ur libpki-0.8.9-orig/src/openssl/pki_algor.c libpki-0.8.9/src/openssl/pki_algor.c
--- libpki-0.8.9-orig/src/openssl/pki_algor.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/openssl/pki_algor.c	2023-07-14 16:39:36.360164740 +0200
@@ -236,6 +236,9 @@
 		case PKI_ALGOR_ECDSA_SHA384:
 		case PKI_ALGOR_ECDSA_SHA512:
 #endif
+#ifdef ENABLE_RSA_PSS
+    case PKI_ALGOR_RSA_PSS:
+#endif
 			break;
 
 		default:
@@ -382,7 +385,7 @@
 			break;
 #endif
 		default:
-			PKI_log_debug( "PKI_ALGOR_get_digest() -> hit UNKNOWN!");
+			PKI_log_debug( "PKI_ALGOR_get_digest() -> hit UNKNOWN (id = %d!", id);
 
 			ret = PKI_DIGEST_ALG_UNKNOWN;
 	}
diff -ur libpki-0.8.9-orig/src/openssl/pki_keypair.c libpki-0.8.9/src/openssl/pki_keypair.c
--- libpki-0.8.9-orig/src/openssl/pki_keypair.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/openssl/pki_keypair.c	2023-07-14 16:39:36.364164741 +0200
@@ -304,25 +304,28 @@
 	if(!X509_PUBKEY_set(&xpk, pkey )) {
 		PKI_log_debug("PKI_X509_KEYPAIR_pub_digest()::Error building X509 "
 			"PUBKEY data");
-		return NULL;
+		goto end;
 	}
 	if((key = xpk->public_key ) == NULL ) {
 		PKI_log_debug("PKI_X509_KEYPAIR_pub_digest()::No pubkey found!");
-		return ( NULL );
+		goto end;
 	}
 
 	if( key->length < 1 ) {
 		PKI_log_debug("PKI_X509_KEYPAIR_pub_digest()::Pubkey len is 0!");
-		return ( NULL );
+		goto end;
 	}
 
 	if(( ret = PKI_DIGEST_new( md, key->data, 
 					(size_t) key->length )) == NULL ) {
 		PKI_log_debug("PKI_X509_KEYPAIR_pub_digest()::%s",
 			ERR_error_string( ERR_get_error(), NULL ));
-		return ( NULL );
+		goto end;
 	}
 
+end:
+	if(xpk) X509_PUBKEY_free(xpk);
+
 	return ( ret );
 }
 
diff -ur libpki-0.8.9-orig/src/openssl/pki_ocsp_resp.c libpki-0.8.9/src/openssl/pki_ocsp_resp.c
--- libpki-0.8.9-orig/src/openssl/pki_ocsp_resp.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/openssl/pki_ocsp_resp.c	2025-08-26 16:52:38.159092209 +0200
@@ -2,6 +2,30 @@
 
 #include <libpki/pki.h>
 
+/*
+	CertHash ::= SEQUENCE {
+		hashAlgorithm AlgorithmIdentifier,  -- The identifier of the algorithm that has been used the hash value below.
+		certificateHash OCTET STRING }      -- A hash over the DER-encoding of the entire PKC or AC (i.e. NOT a hash over tbsCertificate).
+
+	AlgorithmIdentifier ::= SEQUENCE {
+		algorithm OBJECT IDENTIFIER,
+		parameters ANY DEFINED BY algorithm OPTIONAL }
+*/
+typedef struct ocsp_cert_hash_st {
+	X509_ALGOR *hashAlgorithm;
+	ASN1_OCTET_STRING *certificateHash;
+} OCSP_CERT_HASH;
+
+DECLARE_ASN1_FUNCTIONS(OCSP_CERT_HASH)
+
+ASN1_SEQUENCE(OCSP_CERT_HASH) = {
+	ASN1_SIMPLE(OCSP_CERT_HASH, hashAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(OCSP_CERT_HASH, certificateHash, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(OCSP_CERT_HASH)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERT_HASH)
+
+
 /* ---------------------------- Memory Management ----------------------- */
 
 /*! \brief Generates an empty OCSP request  */
@@ -147,18 +171,91 @@
 	return PKI_OK;
 }
 
+/*! \brief Creates an X509 Extension for the OCSP response.
+ *         Derived from Common PKI (as positive statement) */
+
+X509_EXTENSION *PKI_X509_OCSP_CERT_HASH_new(const EVP_MD *hashAlgo, int l_hash, unsigned char *p_hash) {
+
+	OCSP_CERT_HASH    *ocspCertHash = NULL;
+	X509_EXTENSION    *x            = NULL;
+	unsigned char     *certHash     = NULL;
+	int               l_certHash    = 0;
+	static int        nid           = NID_undef;
+	ASN1_OCTET_STRING *oct          = NULL;
+
+
+	if( (ocspCertHash = OCSP_CERT_HASH_new() ) == NULL) {
+		PKI_log_err ("OCSP_CERT_HASH_new() failed!");
+		return(NULL);
+	}
+
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	(void)X509_ALGOR_set_md(ocspCertHash->hashAlgorithm, hashAlgo);
+#else
+	//X509_ALGOR_set0(ocspCertHash->hashAlgorithm, OBJ_nid2obj(EVP_MD_type(hashAlgo)), V_ASN1_UNDEF, NULL);
+	X509_ALGOR_set0(ocspCertHash->hashAlgorithm, OBJ_nid2obj(EVP_MD_type(hashAlgo)), V_ASN1_NULL, NULL);
+#endif
+
+	if(!ASN1_OCTET_STRING_set(ocspCertHash->certificateHash, p_hash, l_hash)) {
+		PKI_log_err ("ASN1_OCTET_STRING_set() failed!");
+		goto err;
+	}
+
+	if( (l_certHash = i2d_OCSP_CERT_HASH(ocspCertHash, &certHash) ) < 0) {
+		PKI_log_err ("i2d_OCSP_CERT_HASH() failed!");
+		goto err;
+	}
+
+	if( (oct = ASN1_OCTET_STRING_new() ) == NULL) {
+		PKI_log_err ("ASN1_OCTET_STRING_new() failed!");
+		goto err;
+	}
+
+	if(!ASN1_OCTET_STRING_set(oct, certHash, l_certHash)) {
+		PKI_log_err ("ASN1_OCTET_STRING_set() failed!");
+		goto err;
+	}
+
+	if ( (x = X509_EXTENSION_new()) == NULL) {
+		PKI_log_err ("X509_EXTENSION_new() failed!");
+		goto err;
+	}
+
+	if(nid == NID_undef) {
+		if( (nid = OBJ_txt2nid("certHash") ) == NID_undef) {
+			PKI_log_err ("OBJ_txt2nid(certHash) failed!");
+			goto err;
+		}
+	}
+
+	if(X509_EXTENSION_create_by_NID(&x, nid, 0, oct) == NULL) {
+		PKI_log_err ("X509_EXTENSION_create_by_NID() failed!");
+		X509_EXTENSION_free(x);
+		x = NULL;
+	}
+
+err:
+	OCSP_CERT_HASH_free(ocspCertHash);
+	if(certHash)  OPENSSL_free(certHash);
+	if(oct)       ASN1_OCTET_STRING_free(oct);
+
+	return x;
+}
+
 /*! \brief Adds one basic request (one certificate) to the request by using
  *         the passed PKI_INTEGER as the serial number of the certificate */
 
-int PKI_X509_OCSP_RESP_add ( PKI_X509_OCSP_RESP *resp, 
+int PKI_X509_OCSP_RESP_add_ex ( PKI_X509_OCSP_RESP *resp, 
 			OCSP_CERTID *cid, PKI_OCSP_CERTSTATUS status,
 			PKI_TIME *revokeTime, PKI_TIME *thisUpdate,
 			PKI_TIME *nextUpdate, 
 			PKI_X509_CRL_REASON reason,
-			PKI_X509_EXTENSION *invalidityDate ) {
+			PKI_X509_EXTENSION *invalidityDate,
+			STACK_OF(X509_EXTENSION) *sk_ex ) {
 
 	OCSP_SINGLERESP *single = NULL;
 	PKI_TIME *myThisUpdate = NULL;
+	int i;
 
 	PKI_OCSP_RESP *r = NULL;
 
@@ -179,34 +276,95 @@
 	if (thisUpdate == NULL )
 	{
 		myThisUpdate = X509_gmtime_adj(NULL,0);
+
+		if(!myThisUpdate)
+			return ( PKI_ERR );
+
+		single = OCSP_basic_add1_status(r->bs, cid, status, reason, revokeTime,
+						myThisUpdate, nextUpdate);
+
+		PKI_TIME_free(myThisUpdate);
+
+		if(!single)
+    {
+			PKI_log_err ("Can not create basic entry for response!");
+			return ( PKI_ERR );
+		}
 	}
 	else
 	{
-		myThisUpdate = PKI_TIME_dup(thisUpdate);
-	}
-
-	if((single = OCSP_basic_add1_status(r->bs, cid,
-			status, reason, revokeTime, myThisUpdate, nextUpdate))== NULL)
-	{
-		PKI_log_err ("Can not create basic entry!");
-		return ( PKI_ERR );
+		if((single = OCSP_basic_add1_status(r->bs, cid,
+			status, reason, revokeTime, thisUpdate, nextUpdate))== NULL)
+		{
+			PKI_log_err ("Can not create basic entry for response!");
+			return ( PKI_ERR );
+		}
 	}
 
-	if (myThisUpdate) PKI_TIME_free(myThisUpdate);
-
 	if (invalidityDate)
 	{
 		if (!OCSP_SINGLERESP_add1_ext_i2d(single,
-                		NID_invalidity_date, invalidityDate, 0, 0))
+			NID_invalidity_date, invalidityDate, 0, 0))
 		{
 			PKI_log_err("Can not create extension entry for response!");
 			return PKI_ERR;
 		}
 	}
 
+	if(sk_ex)
+	{
+		for(i = 0; i < sk_X509_EXTENSION_num(sk_ex); i++)
+		{
+			X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk_ex, i);
+
+			if(!ex)
+			{
+				PKI_log_err("Missing extension for OCSP SingleResponse!");
+				return PKI_ERR;
+			}
+
+			if(!OCSP_SINGLERESP_add_ext(single, ex, -1))
+			{
+				PKI_log_err("Can not add extension to an OCSP SingleResponse!");
+				return PKI_ERR;
+			}
+		}
+	}
+
 	return PKI_OK;
 }
 
+int PKI_X509_OCSP_RESP_add ( PKI_X509_OCSP_RESP *resp, 
+			OCSP_CERTID *cid, PKI_OCSP_CERTSTATUS status,
+			PKI_TIME *revokeTime, PKI_TIME *thisUpdate,
+			PKI_TIME *nextUpdate, 
+			PKI_X509_CRL_REASON reason,
+			PKI_X509_EXTENSION *invalidityDate ) {
+
+	return(PKI_X509_OCSP_RESP_add_ex(resp, cid, status, revokeTime, thisUpdate,
+				nextUpdate, reason, invalidityDate, NULL));
+}
+
+#if !defined OCSP_BASICRESP_sign_ctx
+#  define OCSP_BASICRESP_sign_ctx(o,ctx,d) \
+        ASN1_item_sign_ctx(ASN1_ITEM_rptr(OCSP_RESPDATA),(o)->signatureAlgorithm,\
+                NULL,(o)->signature,(o)->tbsResponseData,ctx)
+#endif
+/*
+int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+                       void *asn, EVP_MD_CTX *ctx);
+
+typedef struct ocsp_basic_response_st {
+    OCSP_RESPDATA *tbsResponseData;
+    X509_ALGOR *signatureAlgorithm;
+    ASN1_BIT_STRING *signature;
+    STACK_OF(X509) *certs;
+} OCSP_BASICRESP;
+
+*/
+
+
 int PKI_X509_OCSP_RESP_DATA_sign (PKI_X509_OCSP_RESP *resp, 
 				PKI_X509_KEYPAIR *k, PKI_DIGEST_ALG *md ) {
 
@@ -214,6 +372,9 @@
 	OCSP_BASICRESP *bsrp = NULL;
 	PKI_X509_OCSP_RESP_VALUE *resp_val = NULL;
 	PKI_OCSP_RESP *r = NULL;
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	EVP_PKEY *pkey = NULL;
+#endif
 
 	if (!resp || !resp->value || !k || !k->value) 
 	{
@@ -242,18 +403,81 @@
 	}
 	*/
 
-	// Using the generic signing function
-	ret = PKI_X509_sign(resp, md, k);
-	if (ret == PKI_ERR)
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	// Private Key
+	pkey = k->value;
+#endif
+
+	// Basic Response
+	bsrp = r->bs;
+
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	if(k->idx != -1 && pkey->type == EVP_PKEY_RSA)
 	{
-		PKI_ERROR(PKI_ERR_OCSP_RESP_SIGN, ERR_error_string(ERR_get_error(), NULL));
+		int i, ret;
+		char *sigopt, *vtmp, *stmp;
+		STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+		EVP_MD_CTX ctx;
+		EVP_PKEY_CTX *pkctx = NULL;
 
-		r->bs->signature = NULL;
-		return PKI_ERR;
+
+		EVP_MD_CTX_init ( &ctx );
+		if (!EVP_DigestSignInit(&ctx, &pkctx, md, NULL, pkey))
+		{
+			PKI_ERROR( PKI_ERR_GENERAL, "EVP_DigestSignInit() failed)");
+			return PKI_ERR;
+		}
+  
+		if( (sigopts = RSA_get_ex_data(pkey->pkey.rsa, k->idx) ) != NULL)
+		{
+			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+			{
+				if( (sigopt = sk_OPENSSL_STRING_value(sigopts, i) ) != NULL)
+				{
+					if( (stmp = BUF_strdup(sigopt) ) == NULL)
+					{
+						PKI_ERROR( PKI_ERR_MEMORY_ALLOC, "BUF_strdup() failed");
+						return PKI_ERR;
+					}
+          
+					if( (vtmp = strchr(stmp, ':') ) != NULL)
+						*vtmp++ = 0;
+        
+					ret = EVP_PKEY_CTX_ctrl_str(pkctx, stmp, vtmp);
+					OPENSSL_free(stmp);
+        
+					if(ret <= 0)
+					{
+						PKI_ERROR( PKI_ERR_GENERAL, "Setting sigopt control string failed");
+						return PKI_ERR;
+					}
+				}
+			}
+		}
+
+		ret = OCSP_BASICRESP_sign_ctx(bsrp, &ctx, 0);
+
+		if(ret <= 0)
+		{
+			PKI_ERROR( PKI_ERR_GENERAL, "OCSP_BASICRESP_sign_ctx() failed");
+			return PKI_ERR;
+		}
+	}
+	else
+#endif
+	{
+		// Using the generic signing function
+		ret = PKI_X509_sign(resp, md, k);
+		if (ret == PKI_ERR)
+		{
+			PKI_ERROR(PKI_ERR_OCSP_RESP_SIGN, ERR_error_string(ERR_get_error(), NULL));
+
+			r->bs->signature = NULL;
+			return PKI_ERR;
+		}
 	}
 
 	resp_val = r->resp;
-	bsrp = r->bs;
 
 	// In case the responseBytes are not already set, let's generate them ourselves
 	if (!resp_val->responseBytes)
@@ -481,6 +705,29 @@
 		case PKI_X509_DATA_NOTAFTER:
 			break;
 
+		case PKI_X509_DATA_THISUPDATE:
+			{
+				ASN1_GENERALIZEDTIME *thisupd = NULL;
+				OCSP_SINGLERESP *single = OCSP_resp_get0(tmp_x, 0);
+
+				OCSP_single_get0_status(single, NULL, NULL, &thisupd, NULL);
+				ret = thisupd;
+			}
+			break;
+
+		case PKI_X509_DATA_LASTUPDATE:
+			break;
+
+		case PKI_X509_DATA_NEXTUPDATE:
+			{
+				ASN1_GENERALIZEDTIME *nextupd = NULL;
+				OCSP_SINGLERESP *single = OCSP_resp_get0(tmp_x, 0);
+
+				OCSP_single_get0_status(single, NULL, NULL, NULL, &nextupd);
+				ret = nextupd;
+			}
+			break;
+
 		case PKI_X509_DATA_SIGNATURE:
 			if ( tmp_x && tmp_x->signature ) {
 				ret = tmp_x->signature;
diff -ur libpki-0.8.9-orig/src/openssl/pki_time.c libpki-0.8.9/src/openssl/pki_time.c
--- libpki-0.8.9-orig/src/openssl/pki_time.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/openssl/pki_time.c	2025-08-28 14:25:50.312648481 +0200
@@ -2,6 +2,15 @@
 
 #include <libpki/pki.h>
 
+#if OPENSSL_VERSION_NUMBER < 0x10101001L
+/*
+ * Correct output of HTTP-date requires ASN1_TIME_to_tm which was introduced
+ * in OpenSSL 1.1.1.  The function body and prerequisites are below, at the
+ * end of the file.  They have been lifted straight from openssl-1.1.1w.
+ */
+static int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm);
+#endif
+
 /*!
  * \brief Returns a new PKI_TIME with offset (secs) from current time
  */
@@ -79,22 +88,19 @@
 
 char *PKI_TIME_get_parsed ( PKI_TIME *t ) {
 
-	BUF_MEM *bm = NULL;
-	BIO *mem = NULL;
+	struct tm stm;
 	char *ret = NULL;
 
 	if( !t ) return (NULL);
-	if ((mem = BIO_new(BIO_s_mem())) == NULL) return(NULL);
-
-	ASN1_TIME_print(mem, (ASN1_TIME *)t);
-	BIO_get_mem_ptr(mem, &bm);
+	ASN1_TIME_to_tm(t, &stm);
 
-	if(( ret = PKI_Malloc( (size_t) (bm->length + 1) )) != NULL ) {
-		memcpy((char *)ret, bm->data, (size_t) bm->length);
-		ret[bm->length] = '\x0';
+	if(( ret = PKI_Malloc( 30 )) != NULL ) {
+		/*
+		 * This format corresponds to HTTP-date as defined in RFC 7231.
+		 */
+		strftime(ret, 30, "%a, %d %b %Y %T GMT", &stm);
 	}
 
-	BIO_free( mem );
 	return( ret );
 
 }
@@ -135,3 +141,415 @@
 	return (PKI_OK);
 }
 
+
+#if OPENSSL_VERSION_NUMBER < 0x10101001L
+/*
+ * The below code has been lifted directly from openssl-1.1.1w and all
+ * functions made static.  ASN1_TIME_to_tm is required for PKI_TIME_get_parsed
+ * to output a correctly formatted HTTP-date for ocspd's headers.
+ *
+ * - crypto/asn1/a_time.c
+ * - crypto/ctype.c
+ * - crypto/o_time.c
+ * - include/openssl/asn1.h
+ */
+
+#define ASN1_STRING_FLAG_X509_TIME 0x100
+#define SECS_PER_DAY (24 * 60 * 60)
+
+static int ascii_isdigit(const char inchar) {
+    if (inchar > 0x2F && inchar < 0x3A)
+        return 1;
+    return 0;
+}
+
+static int leap_year(const int year)
+{
+    if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
+        return 1;
+    return 0;
+}
+
+/*
+ * Compute the day of the week and the day of the year from the year, month
+ * and day.  The day of the year is straightforward, the day of the week uses
+ * a form of Zeller's congruence.  For this months start with March and are
+ * numbered 4 through 15.
+ */
+static void determine_days(struct tm *tm)
+{
+    static const int ydays[12] = {
+        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+    };
+    int y = tm->tm_year + 1900;
+    int m = tm->tm_mon;
+    int d = tm->tm_mday;
+    int c;
+
+    tm->tm_yday = ydays[m] + d - 1;
+    if (m >= 2) {
+        /* March and onwards can be one day further into the year */
+        tm->tm_yday += leap_year(y);
+        m += 2;
+    } else {
+        /* Treat January and February as part of the previous year */
+        m += 14;
+        y--;
+    }
+    c = y / 100;
+    y %= 100;
+    /* Zeller's congruence */
+    tm->tm_wday = (d + (13 * m) / 5 + y + y / 4 + c / 4 + 5 * c + 6) % 7;
+}
+
+/*
+ * Convert date to and from julian day Uses Fliegel & Van Flandern algorithm
+ */
+static long date_to_julian(int y, int m, int d)
+{
+    return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
+        (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
+        (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075;
+}
+
+/* Convert tm structure and offset into julian day and seconds */
+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
+                      long *pday, int *psec)
+{
+    int offset_hms;
+    long offset_day, time_jd;
+    int time_year, time_month, time_day;
+    /* split offset into days and day seconds */
+    offset_day = offset_sec / SECS_PER_DAY;
+    /* Avoid sign issues with % operator */
+    offset_hms = (int)(offset_sec - (offset_day * SECS_PER_DAY));
+    offset_day += off_day;
+    /* Add current time seconds to offset */
+    offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+    /* Adjust day seconds if overflow */
+    if (offset_hms >= SECS_PER_DAY) {
+        offset_day++;
+        offset_hms -= SECS_PER_DAY;
+    } else if (offset_hms < 0) {
+        offset_day--;
+        offset_hms += SECS_PER_DAY;
+    }
+
+    /*
+     * Convert date of time structure into a Julian day number.
+     */
+
+    time_year = tm->tm_year + 1900;
+    time_month = tm->tm_mon + 1;
+    time_day = tm->tm_mday;
+
+    time_jd = date_to_julian(time_year, time_month, time_day);
+
+    /* Work out Julian day of new date */
+    time_jd += offset_day;
+
+    if (time_jd < 0)
+        return 0;
+
+    *pday = time_jd;
+    *psec = offset_hms;
+    return 1;
+}
+
+static void julian_to_date(long jd, int *y, int *m, int *d)
+{
+    long L = jd + 68569;
+    long n = (4 * L) / 146097;
+    long i, j;
+
+    L = L - (146097 * n + 3) / 4;
+    i = (4000 * (L + 1)) / 1461001;
+    L = L - (1461 * i) / 4 + 31;
+    j = (80 * L) / 2447;
+    *d = (int)(L - (2447 * j) / 80);
+    L = j / 11;
+    *m = (int)(j + 2 - (12 * L));
+    *y = (int)(100 * (n - 49) + i + L);
+}
+
+static int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
+{
+    int time_sec, time_year, time_month, time_day;
+    long time_jd;
+
+    /* Convert time and offset into Julian day and seconds */
+    if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec))
+        return 0;
+
+    /* Convert Julian day back to date */
+
+    julian_to_date(time_jd, &time_year, &time_month, &time_day);
+
+    if (time_year < 1900 || time_year > 9999)
+        return 0;
+
+    /* Update tm structure */
+
+    tm->tm_year = time_year - 1900;
+    tm->tm_mon = time_month - 1;
+    tm->tm_mday = time_day;
+
+    tm->tm_hour = time_sec / 3600;
+    tm->tm_min = (time_sec / 60) % 60;
+    tm->tm_sec = time_sec % 60;
+
+    return 1;
+
+}
+
+static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
+{
+    static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+    static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+    static const int mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+    char *a;
+    int n, i, i2, l, o, min_l = 11, strict = 0, end = 6, btz = 5, md;
+    struct tm tmp;
+#if defined(CHARSET_EBCDIC)
+    const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B;
+#else
+    const char upper_z = 'Z', num_zero = '0', period = '.', minus = '-', plus = '+';
+#endif
+    /*
+     * ASN1_STRING_FLAG_X509_TIME is used to enforce RFC 5280
+     * time string format, in which:
+     *
+     * 1. "seconds" is a 'MUST'
+     * 2. "Zulu" timezone is a 'MUST'
+     * 3. "+|-" is not allowed to indicate a time zone
+     */
+    if (d->type == V_ASN1_UTCTIME) {
+        if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
+            min_l = 13;
+            strict = 1;
+        }
+    } else if (d->type == V_ASN1_GENERALIZEDTIME) {
+        end = 7;
+        btz = 6;
+        if (d->flags & ASN1_STRING_FLAG_X509_TIME) {
+            min_l = 15;
+            strict = 1;
+        } else {
+            min_l = 13;
+        }
+    } else {
+        return 0;
+    }
+
+    l = d->length;
+    a = (char *)d->data;
+    o = 0;
+    memset(&tmp, 0, sizeof(tmp));
+
+    /*
+     * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+     * as YYYY. This stuff treats everything as a two digit field so make
+     * first two fields 00 to 99
+     */
+
+    if (l < min_l)
+        goto err;
+    for (i = 0; i < end; i++) {
+        if (!strict && (i == btz) && ((a[o] == upper_z) || (a[o] == plus) || (a[o] == minus))) {
+            i++;
+            break;
+        }
+        if (!ascii_isdigit(a[o]))
+            goto err;
+        n = a[o] - num_zero;
+        /* incomplete 2-digital number */
+        if (++o == l)
+            goto err;
+
+        if (!ascii_isdigit(a[o]))
+            goto err;
+        n = (n * 10) + a[o] - num_zero;
+        /* no more bytes to read, but we haven't seen time-zone yet */
+        if (++o == l)
+            goto err;
+
+        i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i;
+
+        if ((n < min[i2]) || (n > max[i2]))
+            goto err;
+        switch (i2) {
+        case 0:
+            /* UTC will never be here */
+            tmp.tm_year = n * 100 - 1900;
+            break;
+        case 1:
+            if (d->type == V_ASN1_UTCTIME)
+                tmp.tm_year = n < 50 ? n + 100 : n;
+            else
+                tmp.tm_year += n;
+            break;
+        case 2:
+            tmp.tm_mon = n - 1;
+            break;
+        case 3:
+            /* check if tm_mday is valid in tm_mon */
+            if (tmp.tm_mon == 1) {
+                /* it's February */
+                md = mdays[1] + leap_year(tmp.tm_year + 1900);
+            } else {
+                md = mdays[tmp.tm_mon];
+            }
+            if (n > md)
+                goto err;
+            tmp.tm_mday = n;
+            determine_days(&tmp);
+            break;
+        case 4:
+            tmp.tm_hour = n;
+            break;
+        case 5:
+            tmp.tm_min = n;
+            break;
+        case 6:
+            tmp.tm_sec = n;
+            break;
+        }
+    }
+
+    /*
+     * Optional fractional seconds: decimal point followed by one or more
+     * digits.
+     */
+    if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == period) {
+        if (strict)
+            /* RFC 5280 forbids fractional seconds */
+            goto err;
+        if (++o == l)
+            goto err;
+        i = o;
+        while ((o < l) && ascii_isdigit(a[o]))
+            o++;
+        /* Must have at least one digit after decimal point */
+        if (i == o)
+            goto err;
+        /* no more bytes to read, but we haven't seen time-zone yet */
+        if (o == l)
+            goto err;
+    }
+
+    /*
+     * 'o' will never point to '\0' at this point, the only chance
+     * 'o' can point to '\0' is either the subsequent if or the first
+     * else if is true.
+     */
+    if (a[o] == upper_z) {
+        o++;
+    } else if (!strict && ((a[o] == plus) || (a[o] == minus))) {
+        int offsign = a[o] == minus ? 1 : -1;
+        int offset = 0;
+
+        o++;
+        /*
+         * if not equal, no need to do subsequent checks
+         * since the following for-loop will add 'o' by 4
+         * and the final return statement will check if 'l'
+         * and 'o' are equal.
+         */
+        if (o + 4 != l)
+            goto err;
+        for (i = end; i < end + 2; i++) {
+            if (!ascii_isdigit(a[o]))
+                goto err;
+            n = a[o] - num_zero;
+            o++;
+            if (!ascii_isdigit(a[o]))
+                goto err;
+            n = (n * 10) + a[o] - num_zero;
+            i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i;
+            if ((n < min[i2]) || (n > max[i2]))
+                goto err;
+            /* if tm is NULL, no need to adjust */
+            if (tm != NULL) {
+                if (i == end)
+                    offset = n * 3600;
+                else if (i == end + 1)
+                    offset += n * 60;
+            }
+            o++;
+        }
+        if (offset && !OPENSSL_gmtime_adj(&tmp, 0, offset * offsign))
+            goto err;
+    } else {
+        /* not Z, or not +/- in non-strict mode */
+        goto err;
+    }
+    if (o == l) {
+        /* success, check if tm should be filled */
+        if (tm != NULL)
+            *tm = tmp;
+        return 1;
+    }
+ err:
+    return 0;
+}
+
+static struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
+{
+    struct tm *ts = NULL;
+
+#if defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_VMS)
+    {
+        /*
+         * On VMS, gmtime_r() takes a 32-bit pointer as second argument.
+         * Since we can't know that |result| is in a space that can easily
+         * translate to a 32-bit pointer, we must store temporarily on stack
+         * and copy the result.  The stack is always reachable with 32-bit
+         * pointers.
+         */
+#if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+        struct tm data, *ts2 = &data;
+#if defined OPENSSL_SYS_VMS && __INITIAL_POINTER_SIZE
+# pragma pointer_size restore
+#endif
+        if (gmtime_r(timer, ts2) == NULL)
+            return NULL;
+        memcpy(result, ts2, sizeof(struct tm));
+        ts = result;
+    }
+#elif defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_MACOSX)
+    if (gmtime_r(timer, result) == NULL)
+        return NULL;
+    ts = result;
+#elif defined (OPENSSL_SYS_WINDOWS) && defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(_WIN32_WCE)
+    if (gmtime_s(result, timer))
+        return NULL;
+    ts = result;
+#else
+    ts = gmtime(timer);
+    if (ts == NULL)
+        return NULL;
+
+    memcpy(result, ts, sizeof(struct tm));
+    ts = result;
+#endif
+    return ts;
+}
+
+static int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm)
+{
+    if (s == NULL) {
+        time_t now_t;
+
+        time(&now_t);
+        memset(tm, 0, sizeof(*tm));
+        if (OPENSSL_gmtime(&now_t, tm) != NULL)
+            return 1;
+        return 0;
+    }
+
+    return asn1_time_to_tm(tm, s);
+}
+#endif
diff -ur libpki-0.8.9-orig/src/openssl/pki_x509_name.c libpki-0.8.9/src/openssl/pki_x509_name.c
--- libpki-0.8.9-orig/src/openssl/pki_x509_name.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/openssl/pki_x509_name.c	2023-07-14 16:39:36.368164741 +0200
@@ -280,7 +280,7 @@
 		ret = PKI_Malloc ( PKI_MEM_get_size( mem ) + 1 );
 		memcpy( ret, PKI_MEM_get_data(mem), PKI_MEM_get_size (mem));
 		ret[PKI_MEM_get_size (mem)] = '\x0';
-
+		PKI_MEM_free(mem);
 	}
 
 	return( ret );
diff -ur libpki-0.8.9-orig/src/pki_config.c libpki-0.8.9/src/pki_config.c
--- libpki-0.8.9-orig/src/pki_config.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_config.c	2023-07-14 16:39:36.368164741 +0200
@@ -1055,7 +1055,7 @@
 	if( found == 1 ) {
 		return (ret);
 	} else {
-		PKI_STACK_CONFIG_free( ret );
+		PKI_STACK_CONFIG_free_all( ret );
 		PKI_log_debug("PKI_CONFIG_load_dir() Failed!\n" );
 		return ( NULL );
 	}
diff -ur libpki-0.8.9-orig/src/pki_err.c libpki-0.8.9/src/pki_err.c
--- libpki-0.8.9-orig/src/pki_err.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_err.c	2023-07-14 16:39:36.368164741 +0200
@@ -29,9 +29,9 @@
  
 	int i, found;
 	PKI_ERR_ST *curr = NULL;
-	char fmt[2048];
+	//char fmt[2048];
 
-	va_list ap;
+	//va_list ap;
 
 	found = -1;
 	for ( i = 0; i < __libpki_err_size ; i++ ) 
@@ -49,8 +49,11 @@
 			} 
 			else 
 			{
-				snprintf(fmt, sizeof(fmt), "[%s:%d] %s => %s", file, line, curr->descr, info );
-				PKI_log_err_simple( fmt, ap);
+				// remove comment: why don't leave it as it was in the previous release?
+				// <ap> is used uninitialized here!!!
+				PKI_log_err_simple( "[%s:%d] %s => %s", file, line, curr->descr, info );
+				//snprintf(fmt, sizeof(fmt), "[%s:%d] %s => %s", file, line, curr->descr, info );
+				//PKI_log_err_simple( fmt, ap);
 			}
 
 			break;
@@ -65,3 +68,38 @@
 #ifdef HAVE_GCC_PRAGMA_POP
 # pragma GCC diagnostic pop
 #endif
+
+void PKI_strerror(int errnum, char *buf, size_t buflen)
+{
+	if(!buf || buflen <= 0)
+		return;
+
+#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
+	{
+		int _errno = errno;
+
+		/* POSIX variant */
+		if (strerror_r(errnum, buf, buflen) != 0)
+		{
+			errno = _errno;
+			if(buflen >= 4)
+				strncpy(buf, "n/a", buflen);
+			else
+				buf[0] = '\0';
+		}
+	}
+#else
+	{
+		char *err_str;
+
+		/* GNU libc strerror_r is non-portable. */
+		err_str = strerror_r(errnum, buf, buflen);
+		if (err_str != buf)
+		{
+			strncpy(buf, err_str, buflen);
+			buf[buflen - 1] = '\0';
+		}
+	}
+#endif
+}
+
diff -ur libpki-0.8.9-orig/src/pki_init.c libpki-0.8.9/src/pki_init.c
--- libpki-0.8.9-orig/src/pki_init.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_init.c	2025-08-26 16:52:38.159092209 +0200
@@ -21,6 +21,7 @@
 	/* OID - {{1.3.6.1.4.1.18227 (OpenCA)} . 50 (Extensions)} */
 	"1.3.6.1.4.1.18227.50.1", "loa", "Level of Assurance",
 	"1.3.6.1.4.1.18227.50.2", "certificateUsage", "Certificate Usage",
+	"1.3.36.8.3.13", "certHash", "Common PKI Certificate Hash (Positive Statement)",
 	NULL, NULL, NULL
 };
 
@@ -153,6 +154,8 @@
 
 	/* Initialize OpenSSL so that it adds all the needed algor and dgst */
 	if( _libpki_init == 0 ) {
+		PKI_log(PKI_LOG_ALWAYS, "OpenCA libpki v%s - loading (%s).", PACKAGE_VERSION, SSLeay_version(SSLEAY_VERSION));
+		PKI_log(PKI_LOG_ALWAYS, "OpenCA libpki adapted by Atos. Version p1.1.4 (26 Aug 2025).");
 		X509V3_add_standard_extensions();
 		OpenSSL_add_all_algorithms();
 		OpenSSL_add_all_digests();
@@ -207,6 +210,24 @@
 	return ( PKI_OK );
 }
 
+ /*!
+ * \brief needs to be called before calling pthread_exit() 
+ */
+
+void PKI_final_thread( void ) {
+#if HAVE_MYSQL
+	mysql_thread_end();
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+	ERR_remove_state(0);
+#else
+	ERR_remove_thread_state(NULL);
+#endif
+
+  return;
+}
+
 /*!
  * \brief Finialization libpki internal structures.
  */
diff -ur libpki-0.8.9-orig/src/pki_log.c libpki-0.8.9/src/pki_log.c
--- libpki-0.8.9-orig/src/pki_log.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_log.c	2025-09-17 18:04:43.922295083 +0200
@@ -80,11 +80,19 @@
 
 int PKI_log_init ( PKI_LOG_TYPE type, PKI_LOG_LEVEL level, char *resource,
 				PKI_LOG_FLAGS flags, PKI_TOKEN *tk ) {
-	
+
 	int ret = PKI_OK;
 
+	/* Preinitialize syslog for initialization messages of libpki */
+	if( type == PKI_LOG_TYPE_SYSLOG)
+		openlog( resource, LOG_PID, LOG_USER );
+
 	PKI_init_all();
 
+	if( type == PKI_LOG_TYPE_SYSLOG)
+		closelog();
+
+
 	/* We should acquire both the log and log_res mutex to
 	   prevent bad programmers to mess with threads and logging */
 	pthread_mutex_lock( &log_res_mutex );
@@ -190,6 +198,11 @@
 	else
 		ret = PKI_OK;
 
+	if( _log_st.resource != NULL ) {
+		PKI_Free( _log_st.resource );
+		_log_st.resource = NULL;
+	}
+
 	pthread_cond_signal ( &log_cond );
 	pthread_mutex_unlock( &log_mutex );
 
@@ -220,6 +233,62 @@
 	return;
 }
 
+/*! \brief Log OpenSSL errors to the log */
+
+static int _ossl_log_cb(const char *str, size_t len, void *fp)
+{
+	PKI_log(PKI_LOG_ERR, "%s", str);
+	return(0);
+}
+
+
+void PKI_log_ossl(void) {
+	ERR_print_errors_cb(_ossl_log_cb, NULL);
+	return;
+}
+
+/*! \brief Add an hex dump in the Debug log */
+
+void PKI_log_hexdump(int level, char *p_txt, int len, void *p_data)
+{
+    int     a;
+    char    *x;
+    char    *dt;
+    int     adr=0;
+    char    buff1[40];
+    char    buff2[20];
+    static  char    hex[]="0123456789abcdef";
+
+
+    if(level == PKI_LOG_DEBUG && (_log_st.flags & PKI_LOG_FLAGS_ENABLE_DEBUG) == 0 )
+      return;
+
+    if(p_txt != NULL) PKI_log(level, "%s:\n", p_txt);
+    dt=(char *)p_data;
+    while(len>0) {
+        x=buff1;
+        for(a=0;a<16 && a<len;a++) {
+            if((a&3)==0) *x++ = ' ';
+            if((a&7)==0) *x++ = ' ';
+            *x++ = hex[(dt[a]>>4)&15];
+            *x++ = hex[dt[a]&15];
+        }
+        *x=0;
+        x=buff2;
+        for(a=0;a<16 && a<len;a++) {
+          if(dt[a]>' ' && dt[a]<0x7f)
+            *x++ = dt[a];
+          else
+            *x++ = ' ';
+        }
+        *x=0;
+        PKI_log(level, "%6x%-38s |%-16s|\n", adr, buff1, buff2);
+        len-=16;
+        dt+=16;
+        adr+=16;
+    }
+}
+
 /*! \brief Add an entry in the Debug log */
 
 void PKI_log_debug_simple( const char *fmt, ... ) {
@@ -234,7 +303,7 @@
 	pthread_mutex_lock( &log_res_mutex );
 
 	va_start (ap, fmt);
-	if( _log_st.add ) _log_st.add ( PKI_LOG_INFO, fmt, ap );
+	if( _log_st.add ) _log_st.add ( PKI_LOG_DEBUG, fmt, ap );
 	va_end (ap);
 
 	pthread_mutex_unlock( &log_res_mutex );
@@ -424,6 +493,7 @@
 
 	int fd = 0;
 	FILE *file = NULL;
+	char *time = NULL;
 
 	PKI_TIME *now = NULL;
 
@@ -442,13 +512,19 @@
 	}
 
 	now = PKI_TIME_new(0);
+	if( (time = PKI_TIME_get_parsed( (PKI_TIME *) now ) ) == NULL) {
+		/* Error!!! */
+		fprintf( stderr, "DEBUG::ERROR, can not generate log timestamp!\n");
+		return;
+	}
+
 	/* Let's print the log entry */
-	fprintf ( file, "%s [%d]: %s: ", 
-		PKI_TIME_get_parsed( (PKI_TIME *) now ), 
+	fprintf ( file, "%s [%d]: %s: ", time, 
 					getpid(), _get_info_string( level ));
 	vfprintf( file, fmt, ap );
 	fprintf ( file, "\n");
 	PKI_TIME_free( now );
+	PKI_Free( time );
 
 	/* Now close the file stream */
 	fclose( file );
diff -ur libpki-0.8.9-orig/src/pki_mem.c libpki-0.8.9/src/pki_mem.c
--- libpki-0.8.9-orig/src/pki_mem.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_mem.c	2023-07-14 16:39:36.368164741 +0200
@@ -192,6 +192,16 @@
 	{
 		new_size = buf->size + data_size;
 		buf->data = realloc(buf->data, new_size);
+
+		if (!buf->data)
+		{
+			PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+			return (PKI_ERR);
+		}
+
+		// zeroize also the memory (like PKI_Malloc does)
+		memset(buf->data + buf->size, 0, data_size);
+
 		buf->size = new_size;
 	}
 
@@ -513,11 +523,9 @@
 	PKI_IO *b64 = NULL;
 	PKI_IO *bio = NULL;
 
-	int i = 0;
 	int n = 0;
 
 	char buf[1024];
-	unsigned char *tmp_ptr;
 
 	if (!(b64 = BIO_new(BIO_f_base64()))) return NULL;
 	if (withNewLines <= 0) BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
@@ -537,7 +545,7 @@
 
 	while ((n = BIO_read(b64, buf, sizeof(buf))) > 0)
 	{
-		PKI_MEM_add(decoded, buf, n);
+		PKI_MEM_add(decoded, buf, (size_t)n);
 	}
 	BIO_free_all(b64);
 
@@ -590,7 +598,7 @@
 		else
 		{
 			// PKI_MEM_add ( encoded, (char *) &(mem->data[i]), 1);
-			enc_buf[enc_idx++] = mem->data[i];
+			enc_buf[enc_idx++] = (char)mem->data[i];
 		}
 
 		// Let's check if it is time to move the buffer contents into the
@@ -598,14 +606,14 @@
 		// index
 		if (enc_idx >= sizeof(enc_buf) - 4)
 		{
-			PKI_MEM_add(encoded, enc_buf, enc_idx);
+			PKI_MEM_add(encoded, enc_buf, (size_t)enc_idx);
 			enc_idx = 0;
 		}
 	}
 
 	// If there is something left in the buffer that needs to be added
 	// we add it
-	if (enc_idx > 0) PKI_MEM_add(encoded, enc_buf, enc_idx);
+	if (enc_idx > 0) PKI_MEM_add(encoded, enc_buf, (size_t)enc_idx);
 
 	// Let's now return the encoded PKI_MEM
 	return encoded;
@@ -620,10 +628,10 @@
 PKI_MEM *PKI_MEM_get_url_decoded(PKI_MEM *mem)
 {
 	PKI_MEM *decoded = NULL;
-	ssize_t data_size = 0;
 	unsigned char *data = NULL;
+	unsigned char *tmp_buf = NULL;
 
-	int i = 0;
+	unsigned int i = 0;
 	int enc_idx = 0;
 
 	if(!mem || !mem->data || (mem->size == 0) )
@@ -640,13 +648,22 @@
 		return NULL;
 	}
 
+	// We have an off by one error within sscanf - therefore copy the input data
+	// to a seperated buffer
+	if ((tmp_buf = PKI_Malloc(mem->size + 1)) == NULL)
+	{
+		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+		return NULL;
+	}
+	memcpy(tmp_buf, mem->data, mem->size);
+
 	// Let's do the decoding
 	for( i = 0; i < mem->size; i++ )
 	{
 		int p;
 		unsigned char k;
 
-		if (sscanf((const char *)&mem->data[i], "%%%2x", &p) > 0)
+		if (sscanf((const char *)&tmp_buf[i], "%%%2x", &p) > 0)
 		{
 			k = (unsigned char) p;
 			data[enc_idx++] = k;
@@ -654,12 +671,12 @@
 		}
 		else
 		{
-			data[enc_idx++] = mem->data[i];
+			data[enc_idx++] = tmp_buf[i];
 		}
 	}
 
 	// Allocates the new PKI_MEM for the decoding operations
-	if((decoded = PKI_MEM_new_data(enc_idx, data)) == NULL)
+	if((decoded = PKI_MEM_new_data((size_t)enc_idx, data)) == NULL)
 	{
 		PKI_Free(data);
 		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
@@ -668,6 +685,7 @@
 
 	// Free the allocated memory
 	PKI_Free(data);
+	PKI_Free(tmp_buf);
 
 	// Returns the newly allocated url-decoded PKI_MEM
 	return decoded;
diff -ur libpki-0.8.9-orig/src/pki_threads_vars.c libpki-0.8.9/src/pki_threads_vars.c
--- libpki-0.8.9-orig/src/pki_threads_vars.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_threads_vars.c	2023-07-14 16:39:36.368164741 +0200
@@ -38,7 +38,6 @@
 	pthread_rwlock_init(l, NULL );
 # else
   pthread_mutex_init(&l->lock_mutex, NULL);
-  pthread_mutex_init(&l->data_mutex, NULL);
   pthread_cond_init(&l->cond_var, NULL);
 
   l->n_readers = 0;
@@ -88,19 +87,8 @@
 		pthread_cond_wait(&l->cond_var, &l->lock_mutex);
 	}
 
-  if (l->n_readers == 0)
-  {
-    pthread_mutex_unlock(&l->lock_mutex);
-    pthread_mutex_lock(&l->data_mutex);
-    pthread_mutex_lock(&l->lock_mutex);
-    l->n_readers++;
-    pthread_mutex_unlock(&l->lock_mutex);
-  }
-  else if (l->n_readers > 0)
-  {
-    l->n_readers++;
-    pthread_mutex_unlock(&l->lock_mutex);
-  }
+  l->n_readers++;
+  pthread_mutex_unlock(&l->lock_mutex);
 # endif /* HAVE_PTHREAD_RWLOCK */
 #endif
 	return PKI_OK;
@@ -121,13 +109,10 @@
   {
     pthread_cond_wait(&l->cond_var, &l->lock_mutex);
   }
-  pthread_mutex_unlock(&l->lock_mutex);
 
-  pthread_mutex_lock(&l->data_mutex);
-  // pthread_mutex_lock(&l->lock_mutex);
   l->n_writers_waiting--;
-  // l->n_writers--;
   l->n_writers++;
+
   pthread_mutex_unlock(&l->lock_mutex);
 
 # endif /* HAVE_PTHREAD_RWLOCK */
@@ -136,8 +121,9 @@
 	return PKI_OK;
 };
 
+// return != 0 on error
 int PKI_RWLOCK_try_read_lock ( PKI_RWLOCK *l ) {
-	if ( !l ) return PKI_ERR;
+	if ( !l ) return -1;
 #if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN)
 	/* Get the current state of the lock */
 	void *state = *(void **) l;
@@ -163,14 +149,15 @@
 #ifdef HAVE_PTHREAD_RWLOCK
 	return pthread_rwlock_tryrdlock( l );
 #else
-	return PKI_ERR;
+	return -1;
 #endif /* HAVE_PTHREAD_RWLOCK */
 
 #endif
 }
 
+// return != 0 on error
 int PKI_RWLOCK_try_write_lock ( PKI_RWLOCK *l ) {
-	if ( !l ) return PKI_ERR;
+	if ( !l ) return -1;
 #if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN)
 	/* Try to grab lock if it has no users */
 	if (!_InterlockedCompareExchangePointer((void *) l, 
@@ -181,16 +168,17 @@
 #ifdef HAVE_PTHREAD_RWLOCK
 	return pthread_rwlock_trywrlock ( l );
 #else
-	return PKI_ERR;
+	return -1;
 #endif /* HAVE_PTHREAD_RWLOCK */
 
 #endif
 }
 
 
+// return != 0 on error
 /*! \brief Release a PKI_RWLOCK */
 int PKI_RWLOCK_release_read ( PKI_RWLOCK *l ) {
-	if ( !l ) return PKI_ERR;
+	if ( !l ) return -1;
 #if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN)
 	PKI_log_debug("PKI_RWLOCK_release()::TO BE DONE");
 #else
@@ -199,17 +187,17 @@
 # else
   pthread_mutex_lock(&l->lock_mutex);
   l->n_readers--;
-  if (l->n_readers == 0) pthread_mutex_unlock(&l->data_mutex);
   pthread_mutex_unlock(&l->lock_mutex);
   pthread_cond_signal(&l->cond_var);
 # endif
 #endif
-  return PKI_OK;
+  return 0;
 }
 
+// return != 0 on error
 /*! \brief Release a PKI_RWLOCK */
 int PKI_RWLOCK_release_write ( PKI_RWLOCK *l ) {
-	if ( !l ) return PKI_ERR;
+	if ( !l ) return -1;
 #if (LIBPKI_OS_CLASS == LIBPKI_OS_WIN)
 	PKI_log_debug("PKI_RWLOCK_release()::TO BE DONE");
 #else
@@ -218,12 +206,11 @@
 # else
   pthread_mutex_lock(&l->lock_mutex);
   l->n_writers--;
-  if (l->n_writers == 0) pthread_mutex_unlock(&l->data_mutex);
   pthread_mutex_unlock(&l->lock_mutex);
   pthread_cond_signal(&l->cond_var);
 # endif
 
-  return PKI_OK;
+  return 0;
 #endif
 }
 
diff -ur libpki-0.8.9-orig/src/pki_x509.c libpki-0.8.9/src/pki_x509.c
--- libpki-0.8.9-orig/src/pki_x509.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_x509.c	2023-07-14 16:39:36.376164741 +0200
@@ -76,6 +76,9 @@
 	// Crypto provider's specific data structure
 	ret->value = NULL;
 
+	// Index for TYPE_*ex_ex_data functions inside OpenSSL (optional)
+	ret->idx = -1;
+
 	return ret;
 }
 
@@ -93,7 +96,39 @@
 	if (x->value)
 	{
 		if (x->cb->free)
+		{
+			if (x->type == PKI_DATATYPE_X509_KEYPAIR)
+			{
+				switch(EVP_PKEY_type(((EVP_PKEY *)x->value)->type))
+				{
+					case EVP_PKEY_RSA:
+					{
+						CK_OBJECT_HANDLE *pubKey = NULL;
+						CK_OBJECT_HANDLE *privKey = NULL;
+						RSA *rsa = EVP_PKEY_get1_RSA( (EVP_PKEY *) x->value );
+
+						if(rsa == NULL )
+							break;
+
+						/* Retrieves the privkey object handler */
+						if((privKey = (CK_OBJECT_HANDLE *) RSA_get_ex_data (rsa, KEYPAIR_PRIVKEY_HANDLER_IDX)) == NULL )
+							PKI_log_debug ("PKI_X509_free()::Can't get privKey Handle");
+						else
+							PKI_Free(privKey);
+
+						/* Retrieves the pubkey object handler */
+						if((pubKey = (CK_OBJECT_HANDLE *) RSA_get_ex_data (rsa, KEYPAIR_PUBKEY_HANDLER_IDX)) == NULL )
+							PKI_log_debug ("PKI_X509_free()::Can't get pubKey Handle");
+						else
+							PKI_Free(pubKey);
+						RSA_free(rsa);
+					}
+					default:
+						break;
+				}
+			}
 			x->cb->free(x->value);
+		}
 		else
 			PKI_Free(x->value);
 	}
diff -ur libpki-0.8.9-orig/src/pki_x509_mem.c libpki-0.8.9/src/pki_x509_mem.c
--- libpki-0.8.9-orig/src/pki_x509_mem.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/pki_x509_mem.c	2023-07-14 16:39:36.376164741 +0200
@@ -55,7 +55,8 @@
 static void * __get_data_callback(PKI_MEM *mem, const PKI_X509_CALLBACKS *cb,
 				PKI_DATA_FORMAT format, PKI_CRED *cred ) {
 
-	PKI_IO *io = NULL;
+	PKI_IO *ro = NULL;
+	PKI_MEM *dup_mem = NULL;
 
 	void *ret = NULL;
 	char *pwd = NULL;
@@ -66,64 +67,48 @@
 	// If we have credentials (password type), let's get a reference to it
 	if ( cred && cred->password ) pwd = (char *) cred->password;
 
-	// Let's now create the PKI_IO required for the function to process
-	// the data correctly
-	if ((io = BIO_new(BIO_s_mem())) == NULL)
+	// Create a read only memory buffer - it's faster than a read/write one
+	if( (ro = BIO_new_mem_buf(mem->data, (int)mem->size)) == NULL)
 	{
-		// Error creating the IO channel, we have to abort
 		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
 		return NULL;
 	}
 
-	// We need to duplicate the buffer as the read functions might
-	// alter the contents of the buffer
-	PKI_MEM *dup_mem = PKI_MEM_dup(mem);
-	if (dup_mem == NULL)
-	{
-		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
-
-		PKI_Free(io);
-		return NULL;
-	}
-
-	// Let's make the internals of the IO point to our PKI_MEM
-	// data and size
-	BUF_MEM *ptr = (BUF_MEM *) io->ptr;
-	ptr->data = (char *) dup_mem->data;
-
-#if ( OPENSSL_VERSION_NUMBER < 0x10000000L )
-	ptr->length = (int) dup_mem->size;
-#else
-	ptr->length = (size_t) dup_mem->size;
-#endif
-
 	switch ( format )
 	{
 		case PKI_DATA_FORMAT_PEM :
 			if( cb->read_pem ) {
-				ret = cb->read_pem (io, NULL, NULL, pwd );
+				ret = cb->read_pem (ro, NULL, NULL, pwd );
 			}
 			break;
 
 		case PKI_DATA_FORMAT_ASN1 :
 			if( cb->read_der ) {
-				ret = cb->read_der ( io, NULL );
+				ret = cb->read_der ( ro, NULL );
 			}
 			break;
 
 		case PKI_DATA_FORMAT_TXT :
 			if ( cb->read_txt ) {
-				ret = cb->read_txt ( io, NULL );
+				ret = cb->read_txt ( ro, NULL );
 			}
 			break;
 
 		case PKI_DATA_FORMAT_B64 :
 			if (cb->read_b64)
 			{
-				ret = cb->read_b64(io, NULL);
+				ret = cb->read_b64(ro, NULL);
 			}
 			else if (cb->read_der)
 			{
+				// We need to duplicate the buffer as PKI_MEM_decode()
+				// alter the contents of the buffer
+				if( (dup_mem = PKI_MEM_dup(mem) ) == NULL)
+				{
+					PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+					break;
+				}
+
 				if (PKI_MEM_decode(dup_mem, PKI_DATA_FORMAT_B64, 1) != PKI_OK &&
 						PKI_MEM_decode(dup_mem, PKI_DATA_FORMAT_B64, 0) != PKI_OK)
 				{
@@ -131,18 +116,23 @@
 					break;
 				}
 
-				// Now we "write" the data into the PKI_IO
-				BIO_write(io, dup_mem->data, (int) dup_mem->size);
+				// Create a read only memory buffer for further usage it's faster than a read/write one
+				BIO_free(ro);
+				if( (ro = BIO_new_mem_buf(dup_mem->data, (int)dup_mem->size)) == NULL)
+				{
+					PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+					break;
+				}
 
 				// And use the DER reader to retrieve the
 				// requested object
-				ret = cb->read_der(io, NULL);
+				ret = cb->read_der(ro, NULL);
 			}
 			break;
 
 		case PKI_DATA_FORMAT_XML :
 			if ( cb->read_xml ) {
-				ret = cb->read_xml ( io, NULL );
+				ret = cb->read_xml ( ro, NULL );
 			}
 			break;
 
@@ -154,19 +144,10 @@
 			break;
 	}
 
-	// We now have to "reset" the internal of the PKI_IO
-	// object and free it
-	if (io)
-	{
-		ptr = io->ptr;
-		ptr->data = NULL;
-		ptr->length = 0;
-
-		BIO_free(io);
-	}
+	if (ro) BIO_free(ro);
 
 	// Let's free the duplicated PKI_MEM structure
-	if (dup_mem) PKI_Free(dup_mem);
+	if (dup_mem) PKI_MEM_free(dup_mem);
 
 	return ret;
 }
@@ -240,6 +221,7 @@
 	// If we reach here, no object was found - let's free the memory
 	// and return null
 	if (x_obj) PKI_X509_free(x_obj);
+	if (sk)    PKI_STACK_X509_free(sk);
 
 	// Let's return null
 	return NULL;
@@ -399,8 +381,6 @@
 
 	if (ret && (format == PKI_DATA_FORMAT_URL))
 	{
-		PKI_MEM *url_encoded = NULL;
-	
 		if (PKI_MEM_encode(ret, PKI_DATA_FORMAT_URL, 1 ) != PKI_OK)
 		{
 			PKI_MEM_free(ret);
diff -ur libpki-0.8.9-orig/src/stack.c libpki-0.8.9/src/stack.c
--- libpki-0.8.9-orig/src/stack.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/stack.c	2023-07-14 16:39:36.376164741 +0200
@@ -64,7 +64,7 @@
 	ret->tail = NULL;
 	ret->elements = 0;
 
-	if (ret->free) ret->free = free;
+	if (free) ret->free = free;
 	else ret->free = PKI_Free;
 
 	return(ret);
diff -ur libpki-0.8.9-orig/src/token.c libpki-0.8.9/src/token.c
--- libpki-0.8.9-orig/src/token.c	2015-05-04 00:18:40.000000000 +0200
+++ libpki-0.8.9/src/token.c	2023-07-14 16:39:36.384164742 +0200
@@ -431,6 +431,18 @@
 		tk->key_id = NULL;
 	}
 
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	if (tk->sigopts)
+	{
+		char *p;
+
+		while( (p = sk_OPENSSL_STRING_pop(tk->sigopts)))
+			free(p);
+		sk_OPENSSL_STRING_free(tk->sigopts);
+		tk->sigopts = NULL;
+	}
+#endif
+
 	if (tk->cert_id)
 	{
 		PKI_Free(tk->cert_id);
@@ -586,6 +598,7 @@
 			if ((tk->hsm = HSM_new ( buff, hsm_name )) == NULL)
 			{
 				PKI_ERROR(PKI_ERR_HSM_INIT, hsm_name);
+				if (hsm_name) PKI_Free(hsm_name);
 				if (tmp_s) PKI_Free(tmp_s);
 
 				// return PKI_ERROR ( PKI_ERR_HSM_INIT, hsm_name );
@@ -597,6 +610,7 @@
 			if ((tk->hsm = HSM_new( NULL, hsm_name)) == NULL)
 			{
 				PKI_ERROR(PKI_ERR_HSM_INIT, hsm_name);
+				if (hsm_name) PKI_Free(hsm_name);
 				if (tmp_s) PKI_Free(tmp_s);
 				goto end;
 			}
@@ -608,6 +622,7 @@
 			" entry found in token config (%s)", tmp_s, config_file);
 	}
 
+	if (hsm_name) PKI_Free ( hsm_name );
 	if (tmp_s) PKI_Free ( tmp_s );
 	tmp_s = NULL;
 
@@ -692,6 +707,53 @@
 	}
 	else PKI_log_debug("TOKEN::Warning::No Key Provided!");
 
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	if ((tmp_s = PKI_CONFIG_get_value( tk->config, "/tokenConfig/sigopts")) != NULL)
+	{
+		char *p1, *p2;
+
+		/* Initialize OpenSSL so that it adds all the needed algor and dgst */
+		if( (tk->sigopts = sk_OPENSSL_STRING_new_null() ) == NULL)
+		{
+			PKI_Free(tmp_s);
+			PKI_log_debug("TOKEN::Error::sk_OPENSSL_STRING_new_null(sigopts) failed!");
+			PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
+			goto end;
+		}
+
+		p1 = tmp_s;
+		do
+		{
+			if( (p2 = strchr(p1, ',') ) )
+			{
+				*p2++ = 0;
+				while( (*p2 == ' ') )
+					p2++;
+			}
+
+			if( (p1 = strdup(p1) ) == NULL)
+			{
+				PKI_Free(tmp_s);
+				PKI_log_debug("TOKEN::Error::strdup(sigopts) failed!");
+				PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "TOKEN::Error::strdup(sigopts) failed!");
+				goto end;
+			}
+
+			if(!sk_OPENSSL_STRING_push(tk->sigopts, p1))
+			{
+				PKI_Free(tmp_s);
+				PKI_log_debug("TOKEN::Error::sk_OPENSSL_STRING_push(sigopts) failed!");
+				PKI_ERROR(PKI_ERR_GENERAL, "TOKEN::ERROR::sigopts");
+				goto end;
+			}
+
+			p1 = p2;
+		} while(p1);
+
+		PKI_Free ( tmp_s );
+	}
+#endif
+
 	if ((tmp_s = PKI_CONFIG_get_value(tk->config, "/tokenConfig/cert")) != NULL)
 	{
 		if ((tk->cert = PKI_X509_CERT_get(tmp_s, tk->cred, tk->hsm)) == NULL)
@@ -706,8 +768,18 @@
 		if (tk->algor) PKI_ALGOR_free(tk->algor);
 
 		// Assign the algorithm from the certificate
-		alg = PKI_X509_CERT_get_data(tk->cert, PKI_X509_DATA_ALGORITHM);
-		if (alg) PKI_TOKEN_set_algor(tk, PKI_ALGOR_get_id(alg));
+		if ((alg = PKI_X509_CERT_get_data(tk->cert, PKI_X509_DATA_ALGORITHM)) == NULL)
+		{
+			PKI_Free(tmp_s);
+			PKI_ERROR(PKI_ERR_TOKEN_GET_ALGOR, NULL);
+			goto end;
+		} 
+
+		if (PKI_TOKEN_set_algor(tk, PKI_ALGOR_get_id(alg)) != PKI_OK)
+		{
+			PKI_Free(tmp_s);
+			goto end;
+		} 
 
 		// tk->algor = PKI_X509_CERT_get_data(tk->cert, PKI_X509_DATA_ALGORITHM);
 	
@@ -731,6 +803,9 @@
 
 	if ((tmp_s = PKI_CONFIG_get_value(tk->config, "/tokenConfig/otherCerts")) != NULL)
 	{
+		if (tk->otherCerts)
+			PKI_STACK_X509_CERT_free( tk->otherCerts );
+
 		tk->otherCerts = PKI_X509_CERT_STACK_get(tmp_s, tk->cred, tk->hsm );
 		if (tk->otherCerts == NULL) PKI_ERROR(PKI_ERR_TOKEN_OTHERCERTS_LOAD, tmp_s);
 
@@ -739,6 +814,9 @@
 
 	if ((tmp_s = PKI_CONFIG_get_value(tk->config, "/tokenConfig/trustedCerts")) != NULL)
 	{
+		if (tk->trustedCerts)
+			PKI_STACK_X509_CERT_free( tk->trustedCerts );
+
 		tk->trustedCerts = PKI_X509_CERT_STACK_get(tmp_s, tk->cred, tk->hsm);
 		if (!tk->trustedCerts) PKI_ERROR(PKI_ERR_TOKEN_TRUSTEDCERTS_LOAD, tmp_s);
 		PKI_Free ( tmp_s );
@@ -1721,13 +1799,30 @@
 	if ((pkey = PKI_X509_KEYPAIR_get_url( url, tk->cred, tk->hsm )) == NULL)
 	{
 		/* Can not load the keypair from the given URL */
-		if (url) URL_free( url );
 		PKI_log_debug("PKI_TOKEN_load_keypair()::Can not load key (%s)", url->url_s);
+		if (url) URL_free( url );
 		tk->status |= PKI_TOKEN_STATUS_LOGIN_ERR;
 
 		return PKI_ERROR(PKI_ERR_TOKEN_KEYPAIR_LOAD, url_string);
 	}
+#if ( OPENSSL_VERSION_NUMBER >= 0x10000000L )
+	else if(pkey->value && tk->sigopts)
+	{
+		EVP_PKEY *evp_pkey = pkey->value;
 
+		if(pkey->idx != -1)
+			return PKI_ERROR(PKI_ERR_GENERAL, "Index (idx=%d) already set for PKI_X509_KEYPAIR struct", pkey->idx);
+
+		if( (pkey->idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, NULL) ) == -1)
+			return PKI_ERROR(PKI_ERR_GENERAL, "RSA_get_ex_new_index(sigopts) failed");
+
+		if(evp_pkey->pkey.ptr != NULL && evp_pkey->type == EVP_PKEY_RSA)
+		{
+			if(!RSA_set_ex_data(evp_pkey->pkey.rsa, pkey->idx, tk->sigopts))
+				return PKI_ERROR(PKI_ERR_GENERAL, "RSA_set_ex_data(sigopts) failed");
+		}
+	}
+#endif
 
 	// Let's free the URL structure's memory
 	if (url) URL_free(url);
@@ -2492,7 +2587,7 @@
 		    			proxySerial, validity, px_tk->req, 
 						proxyProfile_s )) == NULL ) {
                 printf("ERROR, can not issue Proxy Certificate!\n");
-                exit(1);
+                return ( PKI_ERR );
         }
 
 	/* Now We have to copy all the other certs to the new token */
openSUSE Build Service is sponsored by