diff options
-rw-r--r-- | gio/gtlscertificate.c | 69 | ||||
-rw-r--r-- | gio/tests/Makefile.am | 25 | ||||
-rw-r--r-- | gio/tests/cert-tests/key8enc.pem | 18 | ||||
-rw-r--r-- | gio/tests/cert-tests/key_missing-footer.pem | 14 | ||||
-rw-r--r-- | gio/tests/cert-tests/key_missing-header.pem | 14 | ||||
-rw-r--r-- | gio/tests/tls-certificate.c | 33 |
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); |