static GkmDataResult load_encrypted_key (GBytes *data, const gchar *dekinfo, const gchar *password, gssize n_password, gcry_sexp_t *skey) { guchar *decrypted = NULL; gsize n_decrypted = 0; GBytes *bytes; GkmDataResult ret; gint length; /* Decrypt, this will result in garble if invalid password */ decrypted = egg_openssl_decrypt_block (dekinfo, password, n_password, data, &n_decrypted); if (!decrypted) return FALSE; /* Unpad the DER data */ length = egg_asn1x_element_length (decrypted, n_decrypted); if (length > 0) n_decrypted = length; bytes = g_bytes_new_with_free_func (decrypted, n_decrypted, egg_secure_free, decrypted); /* Try to parse */ ret = gkm_data_der_read_private_key (bytes, skey); g_bytes_unref (bytes); if (ret != GKM_DATA_UNRECOGNIZED) return ret; return GKM_DATA_LOCKED; }
static void parsed_pem_block (GQuark type, GBytes *data, GBytes *outer, GHashTable *headers, gpointer user_data) { ParsePrivate *ctx = (ParsePrivate*)user_data; const gchar *dekinfo; if (!is_private_key_type (type)) return; ctx->seen = TRUE; /* Only parse first key in the file */ if (ctx->sexp) return; /* If it's encrypted ... */ dekinfo = egg_openssl_get_dekinfo (headers); if (dekinfo) { ctx->result = load_encrypted_key (data, dekinfo, ctx->password, ctx->n_password, &ctx->sexp); /* not encryted, just load the data */ } else { ctx->result = gkm_data_der_read_private_key (data, &ctx->sexp); } }
static void test_der_private (gcry_sexp_t key) { guchar *data; gsize n_data; GkmDataResult ret; gcry_sexp_t sexp; /* Encode it */ data = gkm_data_der_write_private_key (key, &n_data); g_assert ("couldn't encode private key" && data != NULL); g_assert ("encoding is empty" && n_data > 0); /* Now parse it */ ret = gkm_data_der_read_private_key (data, n_data, &sexp); g_assert ("couldn't decode private key" && ret == GKM_DATA_SUCCESS); g_assert ("parsed key is empty" && sexp != NULL); /* Now compare them */ g_assert ("key parsed differently" && compare_keys (key, sexp)); egg_secure_free (data); }