From feff178c3f5dadeff47228500a212a9be5688ba2 Mon Sep 17 00:00:00 2001
From: Fredrik Ternerot <fredrikt@axis.com>
Date: Fri, 14 Dec 2018 11:46:27 +0100
Subject: [PATCH 355/682] gtlscertificate: Fix bug in PEM private key parser

Make sure to not go outside of PEM data buffer when looking for private
key.

Also adding test case that triggers this bug.
---
 gio/gtlscertificate.c       |  2 +-
 gio/tests/tls-certificate.c | 13 +++++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index 9e497c58b..1ec48f118 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -258,7 +258,7 @@ parse_private_key (const gchar *data,
 	}
     }
 
-  end = g_strstr_len (start, data_len - (data - start), footer);
+  end = g_strstr_len (start, data_len - (start - data), footer);
   if (!end)
     {
       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index 4cc15d2d7..db2511f59 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -36,14 +36,16 @@ pem_parser (const Reference *ref)
 {
   GTlsCertificate *cert;
   gchar *pem;
+  gsize pem_len = 0;
   gchar *parsed_cert_pem = NULL;
   const gchar *parsed_key_pem = NULL;
   GError *error = NULL;
 
   /* Check PEM parsing in certificate, private key order. */
-  g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, NULL, &error);
+  g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, &pem_len, &error);
   g_assert_no_error (error);
   g_assert (pem);
+  g_assert_cmpuint (pem_len, >=, 10);
 
   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
   g_assert_no_error (error);
@@ -61,10 +63,17 @@ pem_parser (const Reference *ref)
 
   g_object_unref (cert);
 
-  /* Make sure length is respected and parser detect invalid (truncated) PEM. */
+  /* Make sure length is respected and parser detect invalid PEM
+   * when cert is truncated. */
   cert = g_tls_certificate_new_from_pem (pem, 10, &error);
   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
   g_clear_error (&error);
+
+  /* Make sure length is respected and parser detect invalid PEM
+   * when cert exists but key is truncated. */
+  cert = g_tls_certificate_new_from_pem (pem, pem_len - 10, &error);
+  g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+  g_clear_error (&error);
   g_free (pem);
 
   /* Check PEM parsing in private key, certificate order */
-- 
2.19.1

