summaryrefslogtreecommitdiff
path: root/gio/gtlscertificate.c
diff options
context:
space:
mode:
authorFredrik Ternerot <fredrikt@axis.com>2018-12-10 08:48:45 +0100
committerFredrik Ternerot <fredrikt@axis.com>2018-12-18 11:43:08 +0100
commita437a506944a4ddd6ec31df5c302e0fe368ba438 (patch)
tree4fb99e070fea5b39fff99379b065529343cb3cee /gio/gtlscertificate.c
parent73ca761a8d7461a79ebe62ad97ae0d6054f20822 (diff)
downloadglib-a437a506944a4ddd6ec31df5c302e0fe368ba438.tar.gz
gtlscertificate: Allow any type of private key in PEM files
Allow any type of private key in PEM files by treating PEM guards ending with "PRIVATE KEY-----" as a private key instead of looking for a pre-defined set of PEM guards. This enables the possibility for custom GTlsBackend to add support for new key types. Test cases have been expanded to ensure PEM parsing works for private key when either header or footer is missing. Encrypted PKCS#8 is still rejected. Test case has been added for this to ensure behaviour is the same before and after this change.
Diffstat (limited to 'gio/gtlscertificate.c')
-rw-r--r--gio/gtlscertificate.c69
1 files changed, 35 insertions, 34 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);
}