Use BUF_strlcpy() instead of strcpy().
Use BUF_strlcat() instead of strcat().
Use BIO_snprintf() instead of sprintf().
In some cases, keep better track of buffer lengths.
This is part of a large change submitted by Markus Friedl <markus@openbsd.org>
diff --git a/apps/apps.c b/apps/apps.c
index 6e72f11..47b59b4 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -1396,14 +1396,16 @@
 char *make_config_name()
 	{
 	const char *t=X509_get_default_cert_area();
+	size_t len;
 	char *p;
 
-	p=OPENSSL_malloc(strlen(t)+strlen(OPENSSL_CONF)+2);
-	strcpy(p,t);
+	len=strlen(t)+strlen(OPENSSL_CONF)+2;
+	p=OPENSSL_malloc(len);
+	BUF_strlcpy(p,t,len);
 #ifndef OPENSSL_SYS_VMS
-	strcat(p,"/");
+	BUF_strlcat(p,"/",len);
 #endif
-	strcat(p,OPENSSL_CONF);
+	BUF_strlcat(p,OPENSSL_CONF,len);
 
 	return p;
 	}
diff --git a/apps/ca.c b/apps/ca.c
index 0b33811..afcbfcd 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -557,16 +557,19 @@
 	if (configfile == NULL)
 		{
 		const char *s=X509_get_default_cert_area();
+		size_t len;
 
 #ifdef OPENSSL_SYS_VMS
-		tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
+		len = strlen(s)+sizeof(CONFIG_FILE);
+		tofree=OPENSSL_malloc(len);
 		strcpy(tofree,s);
 #else
-		tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
-		strcpy(tofree,s);
-		strcat(tofree,"/");
+		len = strlen(s)+sizeof(CONFIG_FILE)+1;
+		tofree=OPENSSL_malloc(len);
+		BUF_strlcpy(tofree,s,len);
+		BUF_strlcat(tofree,"/",len);
 #endif
-		strcat(tofree,CONFIG_FILE);
+		BUF_strlcat(tofree,CONFIG_FILE,len);
 		configfile=tofree;
 		}
 
@@ -1236,7 +1239,7 @@
 		for (i=0; i<sk_X509_num(cert_sk); i++)
 			{
 			int k;
-			unsigned char *n;
+			char *n;
 
 			x=sk_X509_value(cert_sk,i);
 
@@ -1252,15 +1255,19 @@
 			strcpy(buf[2],outdir);
 
 #ifndef OPENSSL_SYS_VMS
-			strcat(buf[2],"/");
+			BUF_strlcat(buf[2],"/",sizeof(buf[2]));
 #endif
 
-			n=(unsigned char *)&(buf[2][strlen(buf[2])]);
+			n=(char *)&(buf[2][strlen(buf[2])]);
 			if (j > 0)
 				{
 				for (k=0; k<j; k++)
 					{
-					sprintf((char *)n,"%02X",(unsigned char)*(p++));
+					if (n >= &(buf[2][sizeof(buf[2])]))
+						break;
+					BIO_snprintf(n,
+						     &buf[2][0] + sizeof(buf[2]) - n,
+						     "%02X",(unsigned char)*(p++));
 					n+=2;
 					}
 				}
@@ -2127,7 +2134,7 @@
 		BIO_printf(bio_err,"Memory allocation failure\n");
 		goto err;
 		}
-	strcpy(row[DB_file],"unknown");
+	BUF_strlcpy(row[DB_file],"unknown",8);
 	row[DB_type][0]='V';
 	row[DB_type][1]='\0';
 
@@ -2428,7 +2435,7 @@
 			BIO_printf(bio_err,"Memory allocation failure\n");
 			goto err;
 			}
-		strcpy(row[DB_file],"unknown");
+		BUF_strlcpy(row[DB_file],"unknown",8);
 		row[DB_type][0]='V';
 		row[DB_type][1]='\0';
 
@@ -2752,16 +2759,16 @@
 
 	if (!str) return NULL;
 
-	strcpy(str, (char *)revtm->data);
+	BUF_strlcpy(str, (char *)revtm->data, i);
 	if (reason)
 		{
-		strcat(str, ",");
-		strcat(str, reason);
+		BUF_strlcat(str, ",", i);
+		BUF_strlcat(str, reason, i);
 		}
 	if (other)
 		{
-		strcat(str, ",");
-		strcat(str, other);
+		BUF_strlcat(str, ",", i);
+		BUF_strlcat(str, other, i);
 		}
 	ASN1_UTCTIME_free(revtm);
 	return str;
diff --git a/apps/dgst.c b/apps/dgst.c
index 47d1309..be25daf 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -347,8 +347,9 @@
 				}
 			if(!out_bin)
 				{
-				tmp=tofree=OPENSSL_malloc(strlen(name)+strlen(argv[i])+5);
-				sprintf(tmp,"%s(%s)= ",name,argv[i]);
+				size_t len = strlen(name)+strlen(argv[i])+5;
+				tmp=tofree=OPENSSL_malloc(len);
+				BIO_snprintf(tmp,len,"%s(%s)= ",name,argv[i]);
 				}
 			else
 				tmp="";
diff --git a/apps/enc.c b/apps/enc.c
index ae18452..69f4beb 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -373,9 +373,9 @@
 			{
 			char buf[200];
 
-			sprintf(buf,"enter %s %s password:",
-				OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
-				(enc)?"encryption":"decryption");
+			BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
+				     OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
+				     (enc)?"encryption":"decryption");
 			strbuf[0]='\0';
 			i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
 			if (i == 0)
diff --git a/apps/engine.c b/apps/engine.c
index feee965..b951254 100644
--- a/apps/engine.c
+++ b/apps/engine.c
@@ -123,8 +123,8 @@
 		return 0;
 
 	if (**buf != '\0')
-		strcat(*buf, ", ");
-	strcat(*buf, s);
+		BUF_strlcat(*buf, ", ", *size);
+	BUF_strlcat(*buf, s, *size);
 
 	return 1;
 	}
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 385011b..cbd9336 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -551,7 +551,7 @@
 	    	BIO_printf (bio_err, "Can't read Password\n");
 	    	goto export_end;
         	}
-	if (!twopass) strcpy(macpass, pass);
+	if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
 
 #ifdef CRYPTO_MDEBUG
 	CRYPTO_pop_info();
@@ -613,7 +613,7 @@
     CRYPTO_pop_info();
 #endif
 
-    if (!twopass) strcpy(macpass, pass);
+    if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
 
     if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
     if(macver) {
diff --git a/apps/req.c b/apps/req.c
index c5becc9..c4594c4 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -1321,34 +1321,34 @@
 				mval = 0;
 			/* If OBJ not recognised ignore it */
 			if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
-
-			if(strlen(v->name) > sizeof buf-9)
+			if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
+				>= sizeof buf)
 			   {
 			   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
 			   return 0;
 			   }
 
-			sprintf(buf,"%s_default",v->name);
 			if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
 				{
 				ERR_clear_error();
 				def="";
 				}
-			sprintf(buf,"%s_value",v->name);
+				
+			BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
 			if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
 				{
 				ERR_clear_error();
 				value=NULL;
 				}
 
-			sprintf(buf,"%s_min",v->name);
+			BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
 			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
 				{
 				ERR_clear_error();
 				n_min = -1;
 				}
 
-			sprintf(buf,"%s_max",v->name);
+			BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
 			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
 				{
 				ERR_clear_error();
@@ -1386,13 +1386,13 @@
 				if ((nid=OBJ_txt2nid(type)) == NID_undef)
 					goto start2;
 
-				if(strlen(v->name) > sizeof buf-9)
+				if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
+					>= sizeof buf)
 				   {
 				   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
 				   return 0;
 				   }
 
-				sprintf(buf,"%s_default",type);
 				if ((def=NCONF_get_string(req_conf,attr_sect,buf))
 					== NULL)
 					{
@@ -1401,7 +1401,7 @@
 					}
 				
 				
-				sprintf(buf,"%s_value",type);
+				BIO_snprintf(buf,sizeof buf,"%s_value",type);
 				if ((value=NCONF_get_string(req_conf,attr_sect,buf))
 					== NULL)
 					{
@@ -1409,11 +1409,11 @@
 					value=NULL;
 					}
 
-				sprintf(buf,"%s_min",type);
+				BIO_snprintf(buf,sizeof buf,"%s_min",type);
 				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
 					n_min = -1;
 
-				sprintf(buf,"%s_max",type);
+				BIO_snprintf(buf,sizeof buf,"%s_max",type);
 				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
 					n_max = -1;
 
@@ -1507,9 +1507,8 @@
 	(void)BIO_flush(bio_err);
 	if(value != NULL)
 		{
-		OPENSSL_assert(strlen(value) < sizeof buf-2);
-		strcpy(buf,value);
-		strcat(buf,"\n");
+		BUF_strlcpy(buf,value,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
 		BIO_printf(bio_err,"%s\n",value);
 		}
 	else
@@ -1531,8 +1530,8 @@
 		{
 		if ((def == NULL) || (def[0] == '\0'))
 			return(1);
-		strcpy(buf,def);
-		strcat(buf,"\n");
+		BUF_strlcpy(buf,def,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
 		}
 	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
 
@@ -1566,9 +1565,8 @@
 	(void)BIO_flush(bio_err);
 	if (value != NULL)
 		{
-		OPENSSL_assert(strlen(value) < sizeof buf-2);
-		strcpy(buf,value);
-		strcat(buf,"\n");
+		BUF_strlcpy(buf,value,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
 		BIO_printf(bio_err,"%s\n",value);
 		}
 	else
@@ -1590,8 +1588,8 @@
 		{
 		if ((def == NULL) || (def[0] == '\0'))
 			return(1);
-		strcpy(buf,def);
-		strcat(buf,"\n");
+		BUF_strlcpy(buf,def,sizeof buf);
+		BUF_strlcat(buf,"\n",sizeof buf);
 		}
 	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
 
diff --git a/apps/s_socket.c b/apps/s_socket.c
index ff8c282..28c6b1e 100644
--- a/apps/s_socket.c
+++ b/apps/s_socket.c
@@ -429,7 +429,7 @@
 			perror("OPENSSL_malloc");
 			return(0);
 			}
-		strcpy(*host,h1->h_name);
+		BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
 
 		h2=GetHostByName(*host);
 		if (h2 == NULL)
diff --git a/apps/s_time.c b/apps/s_time.c
index 1134020..904945e 100644
--- a/apps/s_time.c
+++ b/apps/s_time.c
@@ -516,7 +516,7 @@
 
 		if (s_www_path != NULL)
 			{
-			sprintf(buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
 			SSL_write(scon,buf,strlen(buf));
 			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
 				bytes_read+=i;
@@ -571,7 +571,7 @@
 
 	if (s_www_path != NULL)
 		{
-		sprintf(buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+		BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
 		SSL_write(scon,buf,strlen(buf));
 		while (SSL_read(scon,buf,sizeof(buf)) > 0)
 			;
@@ -609,7 +609,7 @@
 
 		if (s_www_path)
 			{
-			sprintf(buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
+			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
 			SSL_write(scon,buf,strlen(buf));
 			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
 				bytes_read+=i;
diff --git a/apps/x509.c b/apps/x509.c
index 036e255..d30fbbe 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -1048,24 +1048,26 @@
 	char *buf = NULL, *p;
 	ASN1_INTEGER *bs = NULL;
 	BIGNUM *serial = NULL;
+	size_t len;
 
-	buf=OPENSSL_malloc( ((serialfile == NULL)
-			?(strlen(CAfile)+strlen(POSTFIX)+1)
-			:(strlen(serialfile)))+1);
+	len = ((serialfile == NULL)
+		?(strlen(CAfile)+strlen(POSTFIX)+1)
+		:(strlen(serialfile)))+1;
+	buf=OPENSSL_malloc(len);
 	if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
 	if (serialfile == NULL)
 		{
-		strcpy(buf,CAfile);
+		BUF_strlcpy(buf,CAfile,len);
 		for (p=buf; *p; p++)
 			if (*p == '.')
 				{
 				*p='\0';
 				break;
 				}
-		strcat(buf,POSTFIX);
+		BUF_strlcat(buf,POSTFIX,len);
 		}
 	else
-		strcpy(buf,serialfile);
+		BUF_strlcpy(buf,serialfile,len);
 
 	serial = load_serial(buf, create, NULL);
 	if (serial == NULL) goto end;