Have BIO_get_mem_data return a size_t and uint8_t*

Change-Id: I883f9c3527b572a2140ae4899cf4409cdc25c6dc
Reviewed-on: https://boringssl-review.googlesource.com/1261
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/bio/bio_mem.c b/crypto/bio/bio_mem.c
index 4d047cf..457c2e0 100644
--- a/crypto/bio/bio_mem.c
+++ b/crypto/bio/bio_mem.c
@@ -254,7 +254,7 @@
       ret = (long)b->length;
       if (ptr != NULL) {
         pptr = (char **)ptr;
-        *pptr = (char *)&(b->data[0]);
+        *pptr = (char *)&b->data[0];
       }
       break;
     case BIO_C_SET_BUF_MEM:
@@ -297,6 +297,19 @@
 
 const BIO_METHOD *BIO_s_mem(void) { return &mem_method; }
 
+int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents,
+                     size_t *out_len) {
+  const BUF_MEM *b;
+  if (bio->method != &mem_method) {
+    return 0;
+  }
+
+  b = (BUF_MEM *)bio->ptr;
+  *out_contents = (uint8_t *)b->data;
+  *out_len = b->length;
+  return 1;
+}
+
 long BIO_get_mem_data(BIO *bio, char **contents) {
   return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents);
 }
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index af3789e..1e433d3 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -358,8 +358,18 @@
  * don't depend on this in new code. */
 BIO *BIO_new_mem_buf(void *buf, int len);
 
+/* BIO_mem_contents sets |*out_contents| to point to the current contents of
+ * |bio| and |*out_len| to contain the length of that data. It returns one on
+ * success and zero otherwise. */
+int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents,
+                     size_t *out_len);
+
 /* BIO_get_mem_data sets |*contents| to point to the current contents of |bio|
- * and returns the length of the data. */
+ * and returns the length of the data.
+ *
+ * WARNING: don't use this, use |BIO_mem_contents|. A return value of zero from
+ * this function can mean either that it failed or that the memory buffer is
+ * empty. */
 long BIO_get_mem_data(BIO *bio, char **contents);
 
 /* BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 856843b..f4da38f 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -2587,12 +2587,11 @@
 		 */
 		if (SSL_USE_SIGALGS(s))
 			{
-			long hdatalen = 0;
-			char *hdata;
+			const uint8_t *hdata;
+			size_t hdatalen;
 			md = s->cert->key->digest;
-			hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,
-								&hdata);
-			if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md))
+			if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen) ||
+			    !tls12_get_sigandhash(p, pkey, md))
 				{
 				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_INTERNAL_ERROR);
 				goto err;
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 8f6d75b..24298fd 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -552,15 +552,14 @@
 	int i;
 	long mask;
 	const EVP_MD *md;
-	long hdatalen;
-	char *hdata;
+	const uint8_t *hdata;
+	size_t hdatalen;
 
 	/* Allocate handshake_dgst array */
 	ssl3_free_digest_list(s);
 	s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
 	memset(s->s3->handshake_dgst,0,SSL_MAX_DIGEST *sizeof(EVP_MD_CTX *));
-	hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,&hdata);
-	if (hdatalen <= 0)
+	if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen))
 		{
 		OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, SSL_R_BAD_HANDSHAKE_LENGTH);
 		return 0;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 3d05522..2a348aa 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -2702,10 +2702,9 @@
 
 	if (SSL_USE_SIGALGS(s))
 		{
-		long hdatalen = 0;
-		char *hdata;
-		hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
-		if (hdatalen <= 0)
+		size_t hdatalen;
+		const uint8_t *hdata;
+		if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen))
 			{
 			OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, ERR_R_INTERNAL_ERROR);
 			al=SSL_AD_INTERNAL_ERROR;