summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gio/gtlscertificate.c69
-rw-r--r--gio/tests/Makefile.am25
-rw-r--r--gio/tests/cert-tests/key8enc.pem18
-rw-r--r--gio/tests/cert-tests/key_missing-footer.pem14
-rw-r--r--gio/tests/cert-tests/key_missing-header.pem14
-rw-r--r--gio/tests/tls-certificate.c33
6 files changed, 128 insertions, 45 deletions
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index 1ec48f118..72de5eb1f 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -218,12 +218,11 @@ g_tls_certificate_new_internal (const gchar *certificate_pem,
#define PEM_CERTIFICATE_HEADER "-----BEGIN CERTIFICATE-----"
#define PEM_CERTIFICATE_FOOTER "-----END CERTIFICATE-----"
-#define PEM_PKCS1_PRIVKEY_HEADER "-----BEGIN RSA PRIVATE KEY-----"
-#define PEM_PKCS1_PRIVKEY_FOOTER "-----END RSA PRIVATE KEY-----"
-#define PEM_PKCS8_PRIVKEY_HEADER "-----BEGIN PRIVATE KEY-----"
-#define PEM_PKCS8_PRIVKEY_FOOTER "-----END PRIVATE KEY-----"
+#define PEM_PRIVKEY_HEADER_BEGIN "-----BEGIN "
+#define PEM_PRIVKEY_HEADER_END "PRIVATE KEY-----"
+#define PEM_PRIVKEY_FOOTER_BEGIN "-----END "
+#define PEM_PRIVKEY_FOOTER_END "PRIVATE KEY-----"
#define PEM_PKCS8_ENCRYPTED_HEADER "-----BEGIN ENCRYPTED PRIVATE KEY-----"
-#define PEM_PKCS8_ENCRYPTED_FOOTER "-----END ENCRYPTED PRIVATE KEY-----"
static gchar *
parse_private_key (const gchar *data,
@@ -231,45 +230,47 @@ parse_private_key (const gchar *data,
gboolean required,
GError **error)
{
- const gchar *start, *end, *footer;
+ const gchar *header_start = NULL, *header_end, *footer_start = NULL, *footer_end;
- start = g_strstr_len (data, data_len, PEM_PKCS1_PRIVKEY_HEADER);
- if (start)
- footer = PEM_PKCS1_PRIVKEY_FOOTER;
- else
+ header_end = g_strstr_len (data, data_len, PEM_PRIVKEY_HEADER_END);
+ if (header_end)
+ header_start = g_strrstr_len (data, header_end - data, PEM_PRIVKEY_HEADER_BEGIN);
+
+ if (!header_start)
{
- start = g_strstr_len (data, data_len, PEM_PKCS8_PRIVKEY_HEADER);
- if (start)
- footer = PEM_PKCS8_PRIVKEY_FOOTER;
- else
- {
- start = g_strstr_len (data, data_len, PEM_PKCS8_ENCRYPTED_HEADER);
- if (start)
- {
- g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
- _("Cannot decrypt PEM-encoded private key"));
- }
- else if (required)
- {
- g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
- _("No PEM-encoded private key found"));
- }
- return NULL;
- }
+ if (required)
+ g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
+ _("No PEM-encoded private key found"));
+
+ return NULL;
}
- end = g_strstr_len (start, data_len - (start - data), footer);
- if (!end)
+ header_end += strlen (PEM_PRIVKEY_HEADER_END);
+
+ if (strncmp (header_start, PEM_PKCS8_ENCRYPTED_HEADER, header_end - header_start) == 0)
+ {
+ g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
+ _("Cannot decrypt PEM-encoded private key"));
+ return NULL;
+ }
+
+ footer_end = g_strstr_len (header_end, data_len - (header_end - data), PEM_PRIVKEY_FOOTER_END);
+ if (footer_end)
+ footer_start = g_strrstr_len (header_end, footer_end - header_end, PEM_PRIVKEY_FOOTER_BEGIN);
+
+ if (!footer_start)
{
g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
_("Could not parse PEM-encoded private key"));
return NULL;
}
- end += strlen (footer);
- while (*end == '\r' || *end == '\n')
- end++;
- return g_strndup (start, end - start);
+ footer_end += strlen (PEM_PRIVKEY_FOOTER_END);
+
+ while (*footer_end == '\r' || *footer_end == '\n')
+ footer_end++;
+
+ return g_strndup (header_start, footer_end - header_start);
}
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index 0ad61e4d1..d07792e66 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -225,17 +225,20 @@ tls_certificate_SOURCES = \
dist_test_data += $(cert_data_files)
cert_data_files = $(addprefix cert-tests/,$(cert_tests))
cert_tests = \
- cert1.pem \
- cert2.pem \
- cert3.pem \
- cert-crlf.pem \
- cert-key.pem \
- cert-list.pem \
- key8.pem \
- key-cert.pem \
- key.pem \
- key-crlf.pem \
- nothing.pem \
+ cert1.pem \
+ cert2.pem \
+ cert3.pem \
+ cert-crlf.pem \
+ cert-key.pem \
+ cert-list.pem \
+ key8.pem \
+ key8enc.pem \
+ key-cert.pem \
+ key.pem \
+ key-crlf.pem \
+ key_missing-footer.pem \
+ key_missing-header.pem \
+ nothing.pem \
$(NULL)
uninstalled_test_extra_programs += socket-client
diff --git a/gio/tests/cert-tests/key8enc.pem b/gio/tests/cert-tests/key8enc.pem
new file mode 100644
index 000000000..26a7157b4
--- /dev/null
+++ b/gio/tests/cert-tests/key8enc.pem
@@ -0,0 +1,18 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIdjDoEOJTH2ICAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDNLC2sDVjClaQyT8BfXTt1BIIC
+gCN4s9Z5bmfKogL7YHIJly2zLX5uILHeCr3iQpoPS8057V9Af1wqB/8AUOJrLY96
+R2amkXjlxuqA0BebEk4gcR4tWvCNQ2VCOqvQozUt8LnA+2xQRgzNwaW0HPxcAUzf
+6GVZKL7xfpwFD2ootfLwTHB2zAIVMo8nwgEzdDz93ZwsMmXJmOfSO7vpDQUnVqUX
+jVlue0i8n7fO4ClQ8fz5J8zyvPj403bR9qxsIJjQZACNVLMIksQXjTDngymy/ziI
+lZD4JDLXCQwAOgFz6N6vsyD/mHROyL4/4q8ujYFPmVpuAlQzuZJe6TFnmZHiSfoI
+we6wi1Nee1rbM4VzsGFzMa4Fr0ZhElHEKBXXje4YKWCAOWEo3tLjow4+0dQxNx5W
+tsbQdRt2fRYNYTgt18O55kq3DVfy93aMQVYIMuXkxwAuCWBeiLQrCfAM5r7kDwfc
+owp2AQ5Ndf+aAwr89k2fYUpexz9kZzU+eIY2K1cRhpUlLRAr5SG2oVy7n9IvYs1m
+O7/hjVBvXeAPDADVOtx/YNxPYr9ZI1X2QNDYGxNuSUNF1qGps66Gj+fcRe2NO+Ej
+YfSyfBvw+0h8sad81ZPepCSpIkYX91p6lCdCmRnJWYBwYyn6V5tXOx6tn5ntKJZ9
+9OtTGr7CMm7PLs9S8b03MV9IDJH+TBqR7msP1KWZbTxCNOws28EXo75tQ51ywElF
+FJI6ZU2gBYaX39i8WyvEMXFRRqzYUMzV0Yw2KeVRiGLh0ZX/4rlh2PQqVXGyakvn
+XttDRKEYPEvXDSRpO+tIvESlq9T0Pfo/rpnD4xJd2JWO6z/CSrn8cujs80e1+YjT
+HXksoJzsoLGeiYG2DzTK9lY=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/gio/tests/cert-tests/key_missing-footer.pem b/gio/tests/cert-tests/key_missing-footer.pem
new file mode 100644
index 000000000..3a5b38d25
--- /dev/null
+++ b/gio/tests/cert-tests/key_missing-footer.pem
@@ -0,0 +1,14 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
+P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
+dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
+AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
+gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
+Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
+pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
++3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
+Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
+oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
+J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
+aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
+HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
diff --git a/gio/tests/cert-tests/key_missing-header.pem b/gio/tests/cert-tests/key_missing-header.pem
new file mode 100644
index 000000000..4bcb3674f
--- /dev/null
+++ b/gio/tests/cert-tests/key_missing-header.pem
@@ -0,0 +1,14 @@
+MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
+P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
+dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
+AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
+gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
+Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
+pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
++3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
+Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
+oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
+J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
+aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
+HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
+-----END RSA PRIVATE KEY-----
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index 02bcf5eec..e1ba23737 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -260,6 +260,22 @@ from_files (const Reference *ref)
g_clear_error (&error);
g_assert_null (cert);
+ /* Missing header private key */
+ cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
+ g_test_get_filename (G_TEST_DIST, "cert-tests", "key_missing-header.pem", NULL),
+ &error);
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+ g_clear_error (&error);
+ g_assert_null (cert);
+
+ /* Missing footer private key */
+ cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
+ g_test_get_filename (G_TEST_DIST, "cert-tests", "key_missing-footer.pem", NULL),
+ &error);
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+ g_clear_error (&error);
+ g_assert_null (cert);
+
/* Missing certificate */
cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
@@ -334,6 +350,21 @@ from_files_pkcs8 (const Reference *ref)
}
static void
+from_files_pkcs8enc (const Reference *ref)
+{
+ GTlsCertificate *cert;
+ GError *error = NULL;
+
+ /* Mare sure an error is returned for encrypted key */
+ cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
+ g_test_get_filename (G_TEST_DIST, "cert-tests", "key8enc.pem", NULL),
+ &error);
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+ g_clear_error (&error);
+ g_assert_null (cert);
+}
+
+static void
list_from_file (const Reference *ref)
{
GList *list, *l;
@@ -429,6 +460,8 @@ main (int argc,
&ref, (GTestDataFunc)from_files_crlf);
g_test_add_data_func ("/tls-certificate/from_files_pkcs8",
&ref, (GTestDataFunc)from_files_pkcs8);
+ g_test_add_data_func ("/tls-certificate/from_files_pkcs8enc",
+ &ref, (GTestDataFunc)from_files_pkcs8enc);
g_test_add_data_func ("/tls-certificate/list_from_file",
&ref, (GTestDataFunc)list_from_file);