Finish off the X509_ATTRIBUTE string stuff.
diff --git a/CHANGES b/CHANGES
index eb85a40..ff4dfc3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses
+     the new code. Add documentation for this stuff.
+     [Steve Henson]
+
   *) Changes to X509_ATTRIBUTE utilities. These have been renamed from
      X509_*() to X509at_*() on the grounds that they don't handle X509
      structures and behave in an analagous way to the X509v3 functions:
@@ -14,10 +18,7 @@
      when passed certificate requests. (TO DO: similar things can be done with
      PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other
      things. Some of these need some d2i or i2d and print functionality
-     because they handle more complex structures. Also need to modify things
-     like 'req' so it actually calls this stuff instead of the evil hacks it
-     currently uses.)
-
+     because they handle more complex structures.)
      [Steve Henson]
 
   *) Add missing #ifndefs that caused missing symbols when building libssl
diff --git a/Configure b/Configure
index 6d9c223..c96d0b2 100755
--- a/Configure
+++ b/Configure
@@ -103,6 +103,7 @@
 "debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown)::BN_LLONG $x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
 "debug-bodo",	"gcc:-DBIO_PAIR_DEBUG -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -m486 -pedantic -Wshadow -Wall::-D_REENTRANT::BN_LLONG $x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
 "debug-ulf",	"gcc:-DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -O2 -m486 -Wall -Werror -Wshadow -pipe::-D_REENTRANT::$x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
+"debug-steve",	"gcc:-DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -DPEDANTIC -g -O2 -m486 -pedantic -Wall -Wshadow -pipe::-D_REENTRANT::$x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
 "dist",		"cc:-O::(unknown):::::",
 
 # Basic configs that should work on any box
diff --git a/TABLE b/TABLE
index 1f8518d..fd08b7c 100644
--- a/TABLE
+++ b/TABLE
@@ -765,9 +765,26 @@
 $rmd160_obj   = 
 $rc5_obj      = 
 
+*** debug-steve
+$cc           = gcc
+$cflags       = -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -DPEDANTIC -g -O2 -m486 -pedantic -Wall -Wshadow -pipe
+$unistd       = 
+$thread_cflag = -D_REENTRANT
+$lflags       = 
+$bn_ops       = DES_PTR DES_RISC1 DES_UNROLL RC4_INDEX MD2_INT
+$bn_obj       = asm/bn86-elf.o asm/co86-elf.o
+$des_obj      = asm/dx86-elf.o asm/yx86-elf.o
+$bf_obj       = asm/bx86-elf.o
+$md5_obj      = asm/mx86-elf.o
+$sha1_obj     = asm/sx86-elf.o
+$cast_obj     = asm/cx86-elf.o
+$rc4_obj      = asm/rx86-elf.o
+$rmd160_obj   = asm/rm86-elf.o
+$rc5_obj      = asm/r586-elf.o
+
 *** debug-ulf
 $cc           = gcc
-$cflags       = -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -DPEDANTIC -g -O2 -m486 -Wall  -pedantic -Wall -Wshadow -pipe
+$cflags       = -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -O2 -m486 -Wall -Werror -Wshadow -pipe
 $unistd       = 
 $thread_cflag = -D_REENTRANT
 $lflags       = 
diff --git a/apps/req.c b/apps/req.c
index 5d40925..ce42611 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -115,7 +115,7 @@
 		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs);
 static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
 				STACK_OF(CONF_VALUE) *attr, int attribs);
-static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text,
+static int add_attribute_object(X509_REQ *req, char *text,
 				char *def, char *value, int nid, int min,
 				int max);
 static int add_DN_object(X509_NAME *n, char *text, char *def, char *value,
@@ -123,7 +123,7 @@
 #ifndef NO_RSA
 static void MS_CALLBACK req_cb(int p,int n,void *arg);
 #endif
-static int req_fix_data(int nid,int *type,int len,int min,int max);
+static int req_check_len(int len,int min,int max);
 static int check_end(char *str, char *end);
 static int add_oid_section(LHASH *conf);
 #ifndef MONOLITH
@@ -940,115 +940,7 @@
 	if(no_prompt) i = auto_info(req, dn_sk, attr_sk, attribs);
 	else i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs);
 	if(!i) goto err;
-#if 0
-	BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
-	BIO_printf(bio_err,"into your certificate request.\n");
-	BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
-	BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
-	BIO_printf(bio_err,"For some fields there will be a default value,\n");
-	BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
-	BIO_printf(bio_err,"-----\n");
 
-
-	if (sk_CONF_VALUE_num(sk))
-		{
-		i= -1;
-start:		for (;;)
-			{
-			i++;
-			if (sk_CONF_VALUE_num(sk) <= i) break;
-
-			v=sk_CONF_VALUE_value(sk,i);
-			p=q=NULL;
-			type=v->name;
-			if(!check_end(type,"_min") || !check_end(type,"_max") ||
-				!check_end(type,"_default") ||
-					 !check_end(type,"_value")) continue;
-			/* Skip past any leading X. X: X, etc to allow for
-			 * multiple instances 
-			 */
-			for(p = v->name; *p ; p++) 
-				if ((*p == ':') || (*p == ',') ||
-							 (*p == '.')) {
-					p++;
-					if(*p) type = p;
-					break;
-				}
-			/* If OBJ not recognised ignore it */
-			if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
-			sprintf(buf,"%s_default",v->name);
-			if ((def=CONF_get_string(req_conf,tmp,buf)) == NULL)
-				def="";
-				
-			sprintf(buf,"%s_value",v->name);
-			if ((value=CONF_get_string(req_conf,tmp,buf)) == NULL)
-				value=NULL;
-
-			sprintf(buf,"%s_min",v->name);
-			min=(int)CONF_get_number(req_conf,tmp,buf);
-
-			sprintf(buf,"%s_max",v->name);
-			max=(int)CONF_get_number(req_conf,tmp,buf);
-
-			if (!add_DN_object(ri->subject,v->value,def,value,nid,
-				min,max))
-				goto err;
-			}
-		if (sk_X509_NAME_ENTRY_num(ri->subject->entries) == 0)
-			{
-			BIO_printf(bio_err,"error, no objects specified in config file\n");
-			goto err;
-			}
-
-		if (attribs)
-			{
-			if ((attr != NULL) && (sk_CONF_VALUE_num(attr) > 0))
-				{
-				BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
-				BIO_printf(bio_err,"to be sent with your certificate request\n");
-				}
-
-			i= -1;
-start2:			for (;;)
-				{
-				i++;
-				if ((attr == NULL) ||
-					    (sk_CONF_VALUE_num(attr) <= i))
-					break;
-
-				v=sk_CONF_VALUE_value(attr,i);
-				type=v->name;
-				if ((nid=OBJ_txt2nid(type)) == NID_undef)
-					goto start2;
-
-				sprintf(buf,"%s_default",type);
-				if ((def=CONF_get_string(req_conf,tmp_attr,buf))
-					== NULL)
-					def="";
-				
-				sprintf(buf,"%s_value",type);
-				if ((value=CONF_get_string(req_conf,tmp_attr,buf))
-					== NULL)
-					value=NULL;
-
-				sprintf(buf,"%s_min",type);
-				min=(int)CONF_get_number(req_conf,tmp_attr,buf);
-
-				sprintf(buf,"%s_max",type);
-				max=(int)CONF_get_number(req_conf,tmp_attr,buf);
-
-				if (!add_attribute_object(ri->attributes,
-					v->value,def,value,nid,min,max))
-					goto err;
-				}
-			}
-		}
-	else
-		{
-		BIO_printf(bio_err,"No template, please set one up.\n");
-		goto err;
-		}
-#endif
 	X509_REQ_set_pubkey(req,pkey);
 
 	ret=1;
@@ -1165,7 +1057,7 @@
 				sprintf(buf,"%s_max",type);
 				max=(int)CONF_get_number(req_conf,attr_sect,buf);
 
-				if (!add_attribute_object(req->req_info->attributes,
+				if (!add_attribute_object(req,
 					v->value,def,value,nid,min,max))
 					return 0;
 				}
@@ -1216,56 +1108,15 @@
 			BIO_printf(bio_err,"error, no objects specified in config file\n");
 			return 0;
 			}
-#if 0
 		if (attribs)
 			{
-			if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0))
+			for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
 				{
-				BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
-				BIO_printf(bio_err,"to be sent with your certificate request\n");
-				}
-
-			i= -1;
-start2:			for (;;)
-				{
-				i++;
-				if ((attr_sk == NULL) ||
-					    (sk_CONF_VALUE_num(attr_sk) <= i))
-					break;
-
 				v=sk_CONF_VALUE_value(attr_sk,i);
-				type=v->name;
-				if ((nid=OBJ_txt2nid(type)) == NID_undef)
-					goto start2;
-
-				sprintf(buf,"%s_default",type);
-				if ((def=CONF_get_string(req_conf,attr_sect,buf))
-					== NULL)
-					def="";
-				
-				sprintf(buf,"%s_value",type);
-				if ((value=CONF_get_string(req_conf,attr_sect,buf))
-					== NULL)
-					value=NULL;
-
-				sprintf(buf,"%s_min",type);
-				min=(int)CONF_get_number(req_conf,attr_sect,buf);
-
-				sprintf(buf,"%s_max",type);
-				max=(int)CONF_get_number(req_conf,attr_sect,buf);
-
-				if (!add_attribute_object(ri->attributes,
-					v->value,def,value,nid,min,max))
-					return 0;
+				if(!X509_REQ_radd_attr_by_txt(req, v->name, MBSTRING_ASC,
+					(unsigned char *)v->value, -1)) return 0;
 				}
 			}
-		}
-	else
-		{
-		BIO_printf(bio_err,"No template, please set one up.\n");
-		return 0;
-		}
-#endif
 	return 1;
 	}
 
@@ -1275,7 +1126,7 @@
 	{
 	int i,ret=0;
 	MS_STATIC char buf[1024];
-
+start:
 	BIO_printf(bio_err,"%s [%s]:",text,def);
 	(void)BIO_flush(bio_err);
 	if (value != NULL)
@@ -1311,7 +1162,7 @@
 #ifdef CHARSET_EBCDIC
 	ebcdic2ascii(buf, buf, i);
 #endif
-	if(!req_fix_data(-1, NULL, i, min, max)) goto err;
+	if(!req_check_len(i, min, max)) goto start;
 	if (!X509_NAME_add_entry_by_NID(n,nid, MBSTRING_ASC,
 				(unsigned char *) buf, -1,-1,0)) goto err;
 	ret=1;
@@ -1319,15 +1170,12 @@
 	return(ret);
 	}
 
-static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text,
+static int add_attribute_object(X509_REQ *req, char *text,
 				char *def, char *value, int nid, int min,
 				int max)
 	{
-	int i,z;
-	X509_ATTRIBUTE *xa=NULL;
+	int i;
 	static char buf[1024];
-	ASN1_BIT_STRING *bs=NULL;
-	ASN1_TYPE *at=NULL;
 
 start:
 	BIO_printf(bio_err,"%s [%s]:",text,def);
@@ -1361,47 +1209,17 @@
 		return(0);
 		}
 	buf[--i]='\0';
+	if(!req_check_len(i, min, max)) goto start;
 
-	/* add object plus value */
-	if ((xa=X509_ATTRIBUTE_new()) == NULL)
+	if(!X509_REQ_radd_attr_by_NID(req, nid, MBSTRING_ASC,
+					(unsigned char *)buf, -1)) {
+		BIO_printf(bio_err, "Error adding attribute\n");
+		ERR_print_errors(bio_err);
 		goto err;
-	if ((xa->value.set=sk_ASN1_TYPE_new_null()) == NULL)
-		goto err;
-	xa->set=1;
+	}
 
-	if (xa->object != NULL) ASN1_OBJECT_free(xa->object);
-	xa->object=OBJ_nid2obj(nid);
-
-	if ((bs=ASN1_BIT_STRING_new()) == NULL) goto err;
-
-	bs->type=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
-
-	z=req_fix_data(nid,&bs->type,i,min,max);
-	if (z == 0)
-		{
-		if (value == NULL)
-			goto start;
-		else	goto err;
-		}
-
-	if (!ASN1_STRING_set(bs,(unsigned char *)buf,i))
-		{ BIO_printf(bio_err,"Malloc failure\n"); goto err; }
-
-	if ((at=ASN1_TYPE_new()) == NULL)
-		{ BIO_printf(bio_err,"Malloc failure\n"); goto err; }
-
-	ASN1_TYPE_set(at,bs->type,(char *)bs);
-	sk_ASN1_TYPE_push(xa->value.set,at);
-	bs=NULL;
-	at=NULL;
-	/* only one item per attribute */
-
-	if (!sk_X509_ATTRIBUTE_push(n,xa)) goto err;
 	return(1);
 err:
-	if (xa != NULL) X509_ATTRIBUTE_free(xa);
-	if (at != NULL) ASN1_TYPE_free(at);
-	if (bs != NULL) ASN1_BIT_STRING_free(bs);
 	return(0);
 	}
 
@@ -1422,26 +1240,8 @@
 	}
 #endif
 
-static int req_fix_data(int nid, int *type, int len, int min, int max)
+static int req_check_len(int len, int min, int max)
 	{
-	if(type) {
-		if (nid == NID_pkcs9_emailAddress)
-			*type=V_ASN1_IA5STRING;
-		if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
-			*type=V_ASN1_T61STRING;
-		if ((nid == NID_pkcs9_challengePassword) &&
-			(*type == V_ASN1_IA5STRING))
-			*type=V_ASN1_T61STRING;
-
-		if ((nid == NID_pkcs9_unstructuredName) &&
-			(*type == V_ASN1_T61STRING))
-			{
-			BIO_printf(bio_err,"invalid characters in string, please re-enter the string\n");
-			return(0);
-			}
-		if (nid == NID_pkcs9_unstructuredName)
-			*type=V_ASN1_IA5STRING;
-	}
 	if (len < min)
 		{
 		BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",min);
diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c
index ca8d9ea..7a710d5 100644
--- a/crypto/asn1/a_mbstr.c
+++ b/crypto/asn1/a_mbstr.c
@@ -142,14 +142,14 @@
 		return -1;
 	}
 
-	if(minsize && (nchar < minsize)) {
+	if((minsize > 0) && (nchar < minsize)) {
 		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_SHORT);
 		sprintf(strbuf, "%ld", minsize);
 		ERR_add_error_data(2, "minsize=", strbuf);
 		return -1;
 	}
 
-	if(maxsize && (nchar > maxsize)) {
+	if((maxsize > 0) && (nchar > maxsize)) {
 		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_LONG);
 		sprintf(strbuf, "%ld", maxsize);
 		ERR_add_error_data(2, "maxsize=", strbuf);
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index a5b2814..d1263ed 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -65,7 +65,7 @@
 #ifndef NO_ERR
 static ERR_STRING_DATA RAND_str_functs[]=
 	{
-{ERR_PACK(0,RAND_F_SSLEAY_RAND_BYTES,0),	"ssleay_rand_bytes"},
+{ERR_PACK(0,RAND_F_SSLEAY_RAND_BYTES,0),	"SSLEAY_RAND_BYTES"},
 {0,NULL}
 	};
 
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index e68e494..1ef305c 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -905,6 +905,23 @@
 int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
 				int nid);
 int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+			  int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_radd_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_radd_attr_by_OBJ(X509_REQ *req,
+			ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len);
+int X509_REQ_radd_attr_by_NID(X509_REQ *req,
+			int nid, int type,
+			unsigned char *bytes, int len);
+int X509_REQ_radd_attr_by_txt(X509_REQ *req,
+			char *attrname, int type,
+			unsigned char *bytes, int len);
 
 int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
 
@@ -968,8 +985,8 @@
 			ASN1_OBJECT *obj);
 int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
 			unsigned char *bytes, int len);
-ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
-ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+ASN1_OBJECT *	X509_NAME_ENTRY_iget_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *	X509_NAME_ENTRY_iget_data(X509_NAME_ENTRY *ne);
 
 int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
 int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
@@ -1119,7 +1136,7 @@
 #define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ		 137
 #define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT		 140
 #define X509_F_X509_ATTRIBUTE_IGET_DATA			 139
-#define X509_F_X509_ATTRIBUTE_ISET_DATA			 138
+#define X509_F_X509_ATTRIBUTE_RSET_DATA			 138
 #define X509_F_X509_CHECK_PRIVATE_KEY			 128
 #define X509_F_X509_EXTENSION_CREATE_BY_NID		 108
 #define X509_F_X509_EXTENSION_CREATE_BY_OBJ		 109
diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c
index e04f77b..da76f9c 100644
--- a/crypto/x509/x509_att.c
+++ b/crypto/x509/x509_att.c
@@ -123,7 +123,6 @@
 					 X509_ATTRIBUTE *attr)
 {
 	X509_ATTRIBUTE *new_attr=NULL;
-	int n;
 	STACK_OF(X509_ATTRIBUTE) *sk=NULL;
 
 	if ((x != NULL) && (*x == NULL))
@@ -134,8 +133,6 @@
 	else
 		sk= *x;
 
-	n=sk_X509_ATTRIBUTE_num(sk);
-
 	if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
 		goto err2;
 	if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
@@ -247,6 +244,7 @@
 		{
 		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
 						X509_R_INVALID_FIELD_NAME);
+		ERR_add_error_data(2, "name=", atrname);
 		return(NULL);
 		}
 	nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
@@ -273,7 +271,7 @@
 		stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
 						OBJ_obj2nid(attr->object));
 		if(!stmp) {
-			X509err(X509_F_X509_ATTRIBUTE_ISET_DATA, ERR_R_ASN1_LIB);
+			X509err(X509_F_X509_ATTRIBUTE_RSET_DATA, ERR_R_ASN1_LIB);
 			return 0;
 		}
 		atype = stmp->type;
@@ -286,10 +284,10 @@
 	if(!(ttmp = ASN1_TYPE_new())) goto err;
 	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
 	attr->set = 1;
-	ASN1_TYPE_set(ttmp, atype, data);
+	ASN1_TYPE_set(ttmp, atype, stmp);
 	return 1;
 	err:
-	X509err(X509_F_X509_ATTRIBUTE_ISET_DATA, ERR_R_MALLOC_FAILURE);
+	X509err(X509_F_X509_ATTRIBUTE_RSET_DATA, ERR_R_MALLOC_FAILURE);
 	return 0;
 }
 
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index 026a92b..a9a8116 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -75,9 +75,9 @@
 {ERR_PACK(0,X509_F_X509_ADD_ATTR,0),	"X509_ADD_ATTR"},
 {ERR_PACK(0,X509_F_X509_ATTRIBUTE_CREATE_BY_NID,0),	"X509_ATTRIBUTE_create_by_NID"},
 {ERR_PACK(0,X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,0),	"X509_ATTRIBUTE_create_by_OBJ"},
-{ERR_PACK(0,X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,0),	"X509_ATTRIBUTE_CREATE_BY_TXT"},
+{ERR_PACK(0,X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,0),	"X509_ATTRIBUTE_create_by_txt"},
 {ERR_PACK(0,X509_F_X509_ATTRIBUTE_IGET_DATA,0),	"X509_ATTRIBUTE_iget_data"},
-{ERR_PACK(0,X509_F_X509_ATTRIBUTE_ISET_DATA,0),	"X509_ATTRIBUTE_ISET_DATA"},
+{ERR_PACK(0,X509_F_X509_ATTRIBUTE_RSET_DATA,0),	"X509_ATTRIBUTE_rset_data"},
 {ERR_PACK(0,X509_F_X509_CHECK_PRIVATE_KEY,0),	"X509_check_private_key"},
 {ERR_PACK(0,X509_F_X509_EXTENSION_CREATE_BY_NID,0),	"X509_EXTENSION_create_by_NID"},
 {ERR_PACK(0,X509_F_X509_EXTENSION_CREATE_BY_OBJ,0),	"X509_EXTENSION_create_by_OBJ"},
diff --git a/crypto/x509/x509name.c b/crypto/x509/x509name.c
index b4ceb65..cf2382d 100644
--- a/crypto/x509/x509name.c
+++ b/crypto/x509/x509name.c
@@ -283,6 +283,7 @@
 		{
 		X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
 						X509_R_INVALID_FIELD_NAME);
+		ERR_add_error_data(2, "name=", field);
 		return(NULL);
 		}
 	nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
diff --git a/doc/man/req.pod b/doc/man/req.pod
index d59a2dc..e836f18 100644
--- a/doc/man/req.pod
+++ b/doc/man/req.pod
@@ -245,7 +245,7 @@
 
 If this is set to B<no> then if a private key is generated it is
 B<not> encrypted. This is equivalent to the B<-nodes> command line
-option. For compatibility B<encrypt_rsai_key> is an equivalent option.
+option. For compatibility B<encrypt_rsa_key> is an equivalent option.
 
 =item B<default_md>
 
@@ -279,24 +279,48 @@
 extensions to add to certificate generated when the B<-x509> switch
 is used. It can be overridden by the B<-extensions> command line switch.
 
+=item B<prompt>
+
+if set to the value B<no> this disables prompting of certificate fields
+and just takes values from the config file directly. It also changes the
+expected format of the B<distinguished_name> and B<attributes> sections.
+
 =item B<attributes>
 
 this specifies the section containing any request attributes: its format
-is the same as B<distinguished_name> described below. Typically these
-may contain the challengePassword or unstructuredName types. They are
-currently ignored by OpenSSL's request signing utilities but some CAs
-might want them.
+is the same as B<distinguished_name>. Typically these may contain the
+challengePassword or unstructuredName types. They are currently ignored
+by OpenSSL's request signing utilities but some CAs might want them.
 
 =item B<distinguished_name>
 
 This specifies the section containing the distinguished name fields to
-prompt for when generating a certificate or certificate request. This
-consists of lines of the form:
+prompt for when generating a certificate or certificate request. The format
+is described in the next section.
 
-	fieldName="prompt"
-	fieldName_default="default field value"
-	fieldName_min= 2
-	fieldName_max= 4
+=back
+
+=head1 DISTINGUISHED NAME AND ATTRIBUTE SECTION FORMAT
+
+There are two separate formats for the distinguished name and attribute
+sections. If the B<prompt> option is set to B<no> then these sections
+just consist of field names and values: for example,
+
+ CN=My Name
+ OU=My Organization
+ emailAddress=someone@somehere.org
+
+This allows external programs (e.g. GUI based) to generate a template file
+with all the field names and values and just pass it to B<req>. An example
+of this kind of configuration files is contained in the B<EXAMPLES> section.
+
+Alternatively if the B<prompt> option is absent or not set to B<no> the the
+file contains field prompting information. It consists of lines of the form:
+
+ fieldName="prompt"
+ fieldName_default="default field value"
+ fieldName_min= 2
+ fieldName_max= 4
 
 "fieldName" is the field name being used, for example commonName (or CN).
 The "prompt" string is used to ask the user to enter the relevant
@@ -312,7 +336,7 @@
 
 Some fields (such as organizationName) can be used more than once
 in a DN. This presents a problem because configuration files will
-not recognise the same name occurring twice. To avoid this problem
+not recognize the same name occurring twice. To avoid this problem
 if the fieldName contains an some characters followed by a full stop
 they will be ignored. So for example a second organizationName can
 be input by calling it "1.organizationName".
@@ -328,7 +352,6 @@
 B<oid_section> options in the configuration file. Any additional fields
 will be treated as though they were a DirectoryString.
 
-=back
 
 =head1 EXAMPLES
 
@@ -360,7 +383,7 @@
  testoid1=1.2.3.5
  testoid2=${testoid1}.6
 
-Sample configuration file:
+Sample configuration file prompting for field values:
 
  [ req ]
  default_bits		= 1024
@@ -374,8 +397,8 @@
  [ req_distinguished_name ]
  countryName			= Country Name (2 letter code)
  countryName_default		= AU
- countryName_min			= 2
- countryName_max			= 2
+ countryName_min		= 2
+ countryName_max		= 2
 
  localityName			= Locality Name (eg, city)
 
@@ -398,6 +421,32 @@
  authorityKeyIdentifier=keyid:always,issuer:always
  basicConstraints = CA:true
 
+Sample configuration containing all field values:
+
+
+ RANDFILE		= $ENV::HOME/.rnd
+
+ [ req ]
+ default_bits		= 1024
+ default_keyfile 	= keyfile.pem
+ distinguished_name	= req_distinguished_name
+ attributes		= req_attributes
+ prompt			= no
+ output_password	= mypass
+
+ [ req_distinguished_name ]
+ C			= GB
+ ST			= Test State or Province
+ L			= Test Locality
+ O			= Organization Name
+ OU			= Organizational Unit Name
+ CN			= Common Name
+ emailAddress		= test@email.address
+
+ [ req_attributes ]
+ challengePassword		= A challenge password
+
+
 =head1 NOTES
 
 The header and footer lines in the B<PEM> format are respectively:
@@ -469,18 +518,10 @@
 currently chokes on these. If you have to use accented characters with Netscape
 and MSIE then you currently need to use the invalid T61String form.
 
-The current prompting is not very friendly. It exits if you get the strings
-wrong and doesn't allow you to confirm what you've just entered. Other things
-like extensions in certificate requests are statically defined in the configuration
-file. Some of these: like an email address in subjectAltName should be input
-by the user.
-
-There should be a way to have a friendly front end (e.g. perl script or GUI)
-handle all user input and then just feed a "template" file into B<req> which
-then silently creates the request or certificate. This would also shift the
-responsibility for handling such problems as internationalisation of characters
-onto the front end: the template could then just expect valid UTF8 character
-strings for example.
+The current prompting is not very friendly. It doesn't allow you to confirm what
+you've just entered. Other things like extensions in certificate requests are
+statically defined in the configuration file. Some of these: like an email
+address in subjectAltName should be input by the user.
 
 =head1 SEE ALSO
 
diff --git a/test/Makefile.ssl b/test/Makefile.ssl
index 0e09546..cfa069a 100644
--- a/test/Makefile.ssl
+++ b/test/Makefile.ssl
@@ -330,7 +330,7 @@
 dhtest.o: ../include/openssl/bio.h ../include/openssl/bn.h
 dhtest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
 dhtest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-dhtest.o: ../include/openssl/stack.h
+dhtest.o: ../include/openssl/rand.h ../include/openssl/stack.h
 dsatest.o: ../include/openssl/bio.h ../include/openssl/bn.h
 dsatest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
 dsatest.o: ../include/openssl/dsa.h ../include/openssl/err.h
@@ -383,11 +383,12 @@
 ssltest.o: ../include/openssl/mdc2.h ../include/openssl/objects.h
 ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
 ssltest.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssltest.o: ../include/openssl/pkcs7.h ../include/openssl/rc2.h
-ssltest.o: ../include/openssl/rc4.h ../include/openssl/rc5.h
-ssltest.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h
-ssltest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssltest.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssltest.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssltest.o: ../include/openssl/stack.h ../include/openssl/tls1.h
-ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ssltest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+ssltest.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
+ssltest.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h
+ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssltest.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssltest.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssltest.o: ../include/openssl/x509_vfy.h
diff --git a/util/libeay.num b/util/libeay.num
index 6182984..2fa6c51 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -2178,3 +2178,17 @@
 BIO_number_read                         2203
 X509_STORE_CTX_rget_chain               2204
 ERR_load_RAND_strings                   2205
+RAND_pseudo_bytes                       2206
+X509_REQ_get_attr_by_NID                2207
+X509_REQ_get_attr                       2208
+X509_REQ_radd_attr_by_NID               2209
+X509_REQ_get_attr_by_OBJ                2210
+X509at_radd_attr_by_NID                 2211
+X509_REQ_radd_attr_by_OBJ               2212
+X509_REQ_get_attr_count                 2213
+X509_REQ_radd_attr                      2214
+X509_REQ_delete_attr                    2215
+X509at_radd_attr_by_OBJ                 2216
+X509_REQ_radd_attr_by_txt               2217
+X509_ATTRIBUTE_create_by_txt            2218
+X509at_radd_attr_by_txt                 2219