diff -ur /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf.c crypto/conf/conf.c
--- /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf.c	Wed Dec 23 10:20:54 1998
+++ crypto/conf/conf.c	Tue Jan  5 09:06:22 1999
@@ -62,12 +62,12 @@
 #include "stack.h"
 #include "lhash.h"
 #include "conf.h"
-#include "buffer.h"
 #include "err.h"
 
 #include "conf_lcl.h"
 
 #ifndef NOPROTO
+static void print_conf(CONF_VALUE *cv, char* outc);
 static void value_free_hash(CONF_VALUE *a, LHASH *conf);
 static void value_free_stack(CONF_VALUE *a,LHASH *conf);
 static unsigned long hash(CONF_VALUE *v);
@@ -76,10 +76,12 @@
 static char *eat_alpha_numeric(char *p);
 static void clear_comments(char *p);
 static int str_copy(LHASH *conf,char *section,char **to, char *from);
+static int put_copy(LHASH *conf,char *section,char **to, char *from);
 static char *scan_quote(char *p);
 static CONF_VALUE *new_section(LHASH *conf,char *section);
 static CONF_VALUE *get_section(LHASH *conf,char *section);
 #else
+static void print_conf();
 static void value_free_hash();
 static void value_free_stack();
 static unsigned long hash();
@@ -88,6 +90,7 @@
 static char *eat_alpha_numeric();
 static void clear_comments();
 static int str_copy();
+static int put_copy();
 static char *scan_quote();
 static CONF_VALUE *new_section();
 static CONF_VALUE *get_section();
@@ -103,8 +106,35 @@
 long *line;
 	{
 	LHASH *ret=NULL;
-	FILE *in=NULL;
-#define BUFSIZE	512
+	BIO* in= NULL;
+
+	in=BIO_new(BIO_s_file());
+	if (in == NULL)
+		{
+		CONFerr(CONF_F_CONF_LOAD,ERR_R_BIO_LIB);
+		goto err;
+		}
+
+	if (BIO_read_filename(in,file) <= 0)
+		{
+		CONFerr(CONF_F_CONF_LOAD,ERR_R_BIO_LIB);
+		goto err;
+		}
+
+	ret= CONF_BIO_load(h,in,line);
+
+err:
+	if (in != NULL) BIO_free(in);
+	return(ret);
+	}
+		
+LHASH *CONF_BIO_load(h,in,line)
+LHASH *h;
+BIO *in;
+long *line;
+	{
+	LHASH *ret=NULL;
+#define BUFSIZE	5120
 	char btmp[16];
 	int bufnum=0,i,ii;
 	BUF_MEM *buff=NULL;
@@ -119,24 +149,14 @@
 
 	if ((buff=BUF_MEM_new()) == NULL)
 		{
-		CONFerr(CONF_F_CONF_LOAD,ERR_R_BUF_LIB);
-		goto err;
-		}
-
-	in=fopen(file,"rb");
-	if (in == NULL)
-		{
-		SYSerr(SYS_F_FOPEN,get_last_sys_error());
-		ERR_set_error_data(BUF_strdup(file),
-			ERR_TXT_MALLOCED|ERR_TXT_STRING);
-		CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB);
+		CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_BUF_LIB);
 		goto err;
 		}
 
 	section=(char *)Malloc(10);
 	if (section == NULL)
 		{
-		CONFerr(CONF_F_CONF_LOAD,ERR_R_MALLOC_FAILURE);
+		CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
 	strcpy(section,"default");
@@ -145,7 +165,7 @@
 		{
 		if ((ret=lh_new(hash,cmp)) == NULL)
 			{
-			CONFerr(CONF_F_CONF_LOAD,ERR_R_MALLOC_FAILURE);
+			CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
 		}
@@ -155,7 +175,7 @@
 	sv=new_section(ret,section);
 	if (sv == NULL)
 		{
-		CONFerr(CONF_F_CONF_LOAD,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+		CONFerr(CONF_F_CONF_BIO_LOAD,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
 		goto err;
 		}
 	section_sk=(STACK *)sv->value;
@@ -163,15 +183,15 @@
 	bufnum=0;
 	for (;;)
 		{
-		again=0;
+		again= 0;
 		if (!BUF_MEM_grow(buff,bufnum+BUFSIZE))
 			{
-			CONFerr(CONF_F_CONF_LOAD,ERR_R_BUF_LIB);
+			CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_BUF_LIB);
 			goto err;
 			}
 		p= &(buff->data[bufnum]);
 		*p='\0';
-		fgets(p,BUFSIZE-1,in);
+		BIO_gets(in,p,BUFSIZE-1);
 		p[BUFSIZE-1]='\0';
 		ii=i=strlen(p);
 		if (i == 0) break;
@@ -204,7 +224,7 @@
 			/* If we have bytes and the last char '\\' and
 			 * second last char is not '\\' */
 			p= &(buff->data[bufnum-1]);
-			if (	IS_ESC(p[0]) &&
+			if (    IS_ESC(p[0]) &&
 				((bufnum <= 1) || !IS_ESC(p[-1])))
 				{
 				bufnum--;
@@ -225,7 +245,8 @@
 
 			s++;
 			start=eat_ws(s);
-			ss=start;
+			ss= start;
+
 again:
 			end=eat_alpha_numeric(ss);
 			p=eat_ws(end);
@@ -233,10 +254,10 @@
 				{
 				if (*p != '\0')
 					{
-					ss=p;
+					ss= p;
 					goto again;
 					}
-				CONFerr(CONF_F_CONF_LOAD,CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+				CONFerr(CONF_F_CONF_BIO_LOAD,CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
 				goto err;
 				}
 			*end='\0';
@@ -245,7 +266,7 @@
 				sv=new_section(ret,section);
 			if (sv == NULL)
 				{
-				CONFerr(CONF_F_CONF_LOAD,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+				CONFerr(CONF_F_CONF_BIO_LOAD,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
 				goto err;
 				}
 			section_sk=(STACK *)sv->value;
@@ -267,7 +288,7 @@
 			p=eat_ws(end);
 			if (*p != '=')
 				{
-				CONFerr(CONF_F_CONF_LOAD,CONF_R_MISSING_EQUAL_SIGN);
+				CONFerr(CONF_F_CONF_BIO_LOAD,CONF_R_MISSING_EQUAL_SIGN);
 				goto err;
 				}
 			*end='\0';
@@ -283,7 +304,7 @@
 
 			if ((v=(CONF_VALUE *)Malloc(sizeof(CONF_VALUE))) == NULL)
 				{
-				CONFerr(CONF_F_CONF_LOAD,ERR_R_MALLOC_FAILURE);
+				CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			if (psection == NULL) psection=section;
@@ -291,7 +312,7 @@
 			v->value=NULL;
 			if (v->name == NULL)
 				{
-				CONFerr(CONF_F_CONF_LOAD,ERR_R_MALLOC_FAILURE);
+				CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			strcpy(v->name,pname);
@@ -304,7 +325,7 @@
 					tv=new_section(ret,psection);
 				if (tv == NULL)
 					{
-					CONFerr(CONF_F_CONF_LOAD,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+					CONFerr(CONF_F_CONF_BIO_LOAD,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
 					goto err;
 					}
 				ts=(STACK *)tv->value;
@@ -317,7 +338,7 @@
 			v->section=tv->section;	
 			if (!sk_push(ts,(char *)v))
 				{
-				CONFerr(CONF_F_CONF_LOAD,ERR_R_MALLOC_FAILURE);
+				CONFerr(CONF_F_CONF_BIO_LOAD,ERR_R_MALLOC_FAILURE);
 				goto err;
 				}
 			vv=(CONF_VALUE *)lh_insert(ret,(char *)v);
@@ -333,7 +354,6 @@
 		}
 	if (buff != NULL) BUF_MEM_free(buff);
 	if (section != NULL) Free(section);
-	if (in != NULL) fclose(in);
 	return(ret);
 err:
 	if (buff != NULL) BUF_MEM_free(buff);
@@ -341,7 +361,6 @@
 	if (line != NULL) *line=eline;
 	sprintf(btmp,"%ld",eline);
 	ERR_add_error_data(2,"line ",btmp);
-	if (in != NULL) fclose(in);
 	if ((h != ret) && (ret != NULL)) CONF_free(ret);
 	if (v != NULL)
 		{
@@ -351,7 +370,142 @@
 		}
 	return(NULL);
 	}
-		
+
+int CONF_put_string(conf,section,name,value)
+LHASH *conf;
+char *section;
+char *name;
+char *value;
+	{
+	CONF_VALUE *v,*tv,*vv;
+	STACK *ts;
+	int ret= 1;
+
+	if(conf == NULL || name == NULL || value == NULL) return(ret);
+
+	if ((v=(CONF_VALUE *)Malloc(sizeof(CONF_VALUE))) == NULL)
+		{
+		CONFerr(CONF_F_CONF_PUT_STRING,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (section == NULL) section="default";
+	v->name=(char *)Malloc(strlen(name)+1);
+	v->value=NULL;
+	if (v->name == NULL)
+		{
+		CONFerr(CONF_F_CONF_PUT_STRING,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	strcpy(v->name,name);
+	if (!put_copy(conf,section,&(v->value),value)) goto err;
+
+	if ((tv=get_section(conf,section)) == NULL)
+		tv=new_section(conf,section);
+	if (tv == NULL)
+		{
+		CONFerr(CONF_F_CONF_PUT_STRING,CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+		goto err;
+		}
+	ts=(STACK *)tv->value;
+
+	v->section=tv->section;	
+	if (!sk_push(ts,(char *)v))
+		{
+		CONFerr(CONF_F_CONF_PUT_STRING,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	vv=(CONF_VALUE *)lh_insert(conf,(char *)v);
+	if (vv != NULL)
+		{
+		sk_delete_ptr(ts,(char *)vv);
+		Free(vv->name);
+		Free(vv->value);
+		Free(vv);
+		}
+	v=NULL;
+	ret= 0;
+
+err:
+	if (v != NULL)
+		{
+		if (v->name != NULL) Free(v->name);
+		if (v->value != NULL) Free(v->value);
+		if (v != NULL) Free(v);
+		}
+	return(ret);
+}
+
+int CONF_delete_string(conf,section,name)
+LHASH *conf;
+char *section;
+char *name;
+	{
+	CONF_VALUE *v,*tv,vv;
+	STACK *ts;
+	int i;
+	int ret= 1;
+
+	if(conf == NULL || section == NULL ||
+			strcmp(section, "ENV") == 0)
+		{
+		return(ret);
+		}
+
+	/* get section -- we need it */
+	if((tv=get_section(conf,section)) == NULL) 
+		return (ret);
+	ts= (STACK *)tv->value;
+
+	/* if name != NULL -> delete one value */
+	if(name != NULL){
+		/* first delete it from hash */
+		vv.name=name;
+		vv.section=section;
+
+		/* don't delete return value, cause it's still in stack --
+		it will be freed later */
+		if((v= (CONF_VALUE *)lh_delete(conf,(char *)&vv)) != NULL){
+
+			/* remove v from stack */
+			sk_delete_ptr(ts,(char *)v);
+			Free(v->name);
+			Free(v->value);
+			Free(v);
+			ret= 0;
+		}
+
+	/* if name == NULL delete whole section */
+	}else{
+		/* all entries from stack */
+		for (i=sk_num(ts)-1; i>=0; i--){
+			v=(CONF_VALUE *)sk_delete(ts,i);
+
+			/* delete it from hash */
+			lh_delete(conf,(char *)v);
+
+			/* and free components */
+			Free(v->value);
+			Free(v->name);
+			Free(v);
+		}
+		ret= 0;
+	}
+
+	/* if section stack is empty then remove section */
+	if (sk_num(ts) == 0){
+		/* free stack */
+		sk_free(ts);
+
+		/* remove section from hash */
+		lh_delete(conf,(char *)tv);
+
+		/* and free it */
+		Free(tv->section);
+		Free(tv);
+	}
+	return(ret);
+}
+
 char *CONF_get_string(conf,section,name)
 LHASH *conf;
 char *section;
@@ -449,6 +603,119 @@
 	lh_free(conf);
 	}
 
+int CONF_save(h,file)
+LHASH *h;
+char *file;
+	{
+	BIO* out= NULL;
+	int retval= 1;
+
+	out=BIO_new(BIO_s_file());
+	if (out == NULL)
+		{
+		CONFerr(CONF_F_CONF_SAVE,ERR_R_BIO_LIB);
+		goto err;
+		}
+
+	if (BIO_write_filename(out,file) <= 0)
+		{
+		CONFerr(CONF_F_CONF_SAVE,ERR_R_BIO_LIB);
+		goto err;
+		}
+
+	CONF_BIO_save(h,out);
+	retval= 0;
+
+err:
+	if (out != NULL) BIO_free(out);
+	return(retval);
+	}
+
+void CONF_BIO_save(h,out)
+LHASH *h;
+BIO *out;
+	{
+	lh_doall_arg(h,print_conf,(char *)out);
+	}
+
+LHASH *CONF_create()
+	{
+	return(lh_new(hash,cmp));
+	}
+
+static void print_conf(cv, outc)
+CONF_VALUE *cv;
+char* outc;
+	{
+	int i;
+	CONF_VALUE *v;
+	char *name;
+	char *value;
+	STACK *s;
+	BIO* out= (BIO *)outc;
+
+	/* If it is a single entry, return */
+
+	if (cv->name != NULL) return;
+
+	BIO_printf(out,"[ %s ]\n",cv->section);
+	s=(STACK *)cv->value;
+
+	for (i=0; i<sk_num(s); i++)
+		{
+		char* newval= NULL;
+		char* tmp= NULL;
+		int len;
+		int j;
+
+		v=(CONF_VALUE *)sk_value(s,i);
+		name=(v->name == NULL)?"None":v->name;
+		value=(v->value == NULL)?"None":v->value;
+
+		len= strlen(value);
+		if((newval= (char *)Malloc(len* 2+ 1)) != NULL){
+			tmp= newval;
+			for(j= 0;j < len;j++){
+				if(value[j] == '\\'){
+					*(tmp++)= '\\';
+					*(tmp++)= '\\';
+				}else if(value[j] == '\r'){
+					*(tmp++)= '\\';
+					*(tmp++)= 'r';
+				}else if(value[j] == '\n'){
+					*(tmp++)= '\\';
+					*(tmp++)= 'n';
+				}else if(value[j] == '\b'){
+					*(tmp++)= '\\';
+					*(tmp++)= 'b';
+				}else if(value[j] == '\t'){
+					*(tmp++)= '\\';
+					*(tmp++)= 't';
+				}else if(value[j] == '$'){
+					*(tmp++)= '\\';
+					*(tmp++)= '$';
+				}else if(value[j] == '\"'){
+					*(tmp++)= '\\';
+					*(tmp++)= '\"';
+				}else if(value[j] == '\''){
+					*(tmp++)= '\\';
+					*(tmp++)= '\'';
+				}else if(value[j] == '\`'){
+					*(tmp++)= '\\';
+					*(tmp++)= '\`';
+				}else 
+					*(tmp++)= value[j];
+			}
+			*(tmp++)= '\0';
+			BIO_printf(out,"%s=%s\n",name,newval);
+			Free(newval);
+		}else{
+			BIO_printf(out,"%s=%s\n",name,"out of memory error!");
+		}
+		}
+	BIO_printf(out,"\n");
+	}
+
 static void value_free_hash(a,conf)
 CONF_VALUE *a;
 LHASH *conf;
@@ -738,3 +1005,28 @@
 		}
 	return(v);
 	}
+
+static int put_copy(conf,section,pto,from)
+LHASH *conf;
+char *section;
+char **pto,*from;
+	{
+	int len=0;
+	BUF_MEM *buf;
+
+	if ((buf=BUF_MEM_new()) == NULL) return(0);
+
+	len=strlen(from)+1;
+	if (!BUF_MEM_grow(buf,len)) goto err;
+
+	strcpy(buf->data, from);
+
+	if (*pto != NULL) Free(*pto);
+	*pto=buf->data;
+	Free(buf);
+	return(1);
+err:
+	if (buf != NULL) BUF_MEM_free(buf);
+	return(0);
+	}
+
diff -ur /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf.err crypto/conf/conf.err
--- /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf.err	Mon Dec 21 12:52:29 1998
+++ crypto/conf/conf.err	Tue Jan  5 09:29:11 1999
@@ -1,8 +1,11 @@
 /* Error codes for the CONF functions. */
 
 /* Function codes. */
-#define CONF_F_CONF_LOAD				 100
-#define CONF_F_STR_COPY					 101
+#define CONF_F_CONF_BIO_LOAD				 100
+#define CONF_F_CONF_LOAD				 101
+#define CONF_F_CONF_PUT_STRING				 102
+#define CONF_F_CONF_SAVE				 103
+#define CONF_F_STR_COPY					 104
 
 /* Reason codes. */
 #define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
diff -ur /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf.h crypto/conf/conf.h
--- /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf.h	Mon Dec 21 12:54:51 1998
+++ crypto/conf/conf.h	Tue Jan  5 09:29:16 1999
@@ -65,6 +65,7 @@
 
 #include "stack.h"
 #include "lhash.h"
+#include "bio.h"
 
 typedef struct
 	{
@@ -76,20 +77,32 @@
 #ifndef NOPROTO
 
 LHASH *CONF_load(LHASH *conf,char *file,long *eline);
+LHASH *CONF_BIO_load(LHASH *conf,BIO *in,long *eline);
 STACK *CONF_get_section(LHASH *conf,char *section);
 char *CONF_get_string(LHASH *conf,char *group,char *name);
 long CONF_get_number(LHASH *conf,char *group,char *name);
 void CONF_free(LHASH *conf);
 void ERR_load_CONF_strings(void );
+void CONF_BIO_save(LHASH *h,BIO *out);
+int CONF_put_string(LHASH *conf, char *section, char *name, char *value);
+int CONF_delete_string(LHASH *conf, char *section, char *name);
+int CONF_save(LHASH *h, char *file);
+LHASH *CONF_create(void);
 
 #else
 
 LHASH *CONF_load();
+LHASH *CONF_BIO_load();
 STACK *CONF_get_section();
 char *CONF_get_string();
 long CONF_get_number();
 void CONF_free();
 void ERR_load_CONF_strings();
+void CONF_BIO_save(h,out);
+int CONF_put_string();
+int CONF_delete_string();
+int CONF_save();
+LHASH *CONF_create();
 
 #endif
 
@@ -97,8 +110,11 @@
 /* Error codes for the CONF functions. */
 
 /* Function codes. */
-#define CONF_F_CONF_LOAD				 100
-#define CONF_F_STR_COPY					 101
+#define CONF_F_CONF_BIO_LOAD				 100
+#define CONF_F_CONF_LOAD				 101
+#define CONF_F_CONF_PUT_STRING				 102
+#define CONF_F_CONF_SAVE				 103
+#define CONF_F_STR_COPY					 104
 
 /* Reason codes. */
 #define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
diff -ur /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf_err.c crypto/conf/conf_err.c
--- /export/home/arne/org/openssl-0.9.1c/crypto/conf/conf_err.c	Mon Dec 21 12:59:08 1998
+++ crypto/conf/conf_err.c	Tue Jan  5 09:29:16 1999
@@ -63,7 +63,10 @@
 #ifndef NO_ERR
 static ERR_STRING_DATA CONF_str_functs[]=
 	{
+{ERR_PACK(0,CONF_F_CONF_BIO_LOAD,0),	"CONF_BIO_load"},
 {ERR_PACK(0,CONF_F_CONF_LOAD,0),	"CONF_load"},
+{ERR_PACK(0,CONF_F_CONF_PUT_STRING,0),	"CONF_put_string"},
+{ERR_PACK(0,CONF_F_CONF_SAVE,0),	"CONF_save"},
 {ERR_PACK(0,CONF_F_STR_COPY,0),	"STR_COPY"},
 {0,NULL},
 	};
