-#define PEM_CERTIFICATE_HEADER "-----BEGIN CERTIFICATE-----"
-#define PEM_CERTIFICATE_FOOTER "-----END CERTIFICATE-----"
-#define PEM_PRIVKEY_HEADER "-----BEGIN RSA PRIVATE KEY-----"
-#define PEM_PRIVKEY_FOOTER "-----END RSA PRIVATE KEY-----"
+#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_PKCS8_ENCRYPTED_HEADER "-----BEGIN ENCRYPTED PRIVATE KEY-----"
+#define PEM_PKCS8_ENCRYPTED_FOOTER "-----END ENCRYPTED PRIVATE KEY-----"
+
+static gchar *
+parse_private_key (const gchar *data,
+ gsize data_len,
+ gboolean required,
+ GError **error)
+{
+ const gchar *start, *end, *footer;
+
+ start = g_strstr_len (data, data_len, PEM_PKCS1_PRIVKEY_HEADER);
+ if (start)
+ footer = PEM_PKCS1_PRIVKEY_FOOTER;
+ else
+ {
+ 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;
+ }
+ }