Merge branch 'master' of github.com:open-keychain/open-keychain

This commit is contained in:
Vincent Breitmoser 2015-09-21 11:49:12 +02:00
commit 2b83ed6cfc
22 changed files with 200 additions and 142 deletions

View file

@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFpzCCBI+gAwIBAgIQSCQjuTbnogvWCWWHeCDMbzANBgkqhkiG9w0BAQsFADB2
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTUkxEjAQBgNVBAcTCUFubiBBcmJvcjES
MBAGA1UEChMJSW50ZXJuZXQyMREwDwYDVQQLEwhJbkNvbW1vbjEfMB0GA1UEAxMW
SW5Db21tb24gUlNBIFNlcnZlciBDQTAeFw0xNDEwMDkwMDAwMDBaFw0xNzEwMDgy
MzU5NTlaMIHlMQswCQYDVQQGEwJVUzEOMAwGA1UEERMFMDIxMzkxCzAJBgNVBAgT
Ak1hMRIwEAYDVQQHEwlDYW1icmlkZ2UxHTAbBgNVBAkTFDc3IE1hc3NhY2h1c2V0
dHMgQXZlMS4wLAYDVQQKEyVNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNo
bm9sb2d5MSowKAYDVQQLFCFJbmZvcm1hdGlvbiBTZXJ2aWNlcyAmIFRlY2hub2xv
Z3kxFDASBgNVBAsTC1BsYXRpbnVtU1NMMRQwEgYDVQQDEwtwZ3AubWl0LmVkdTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOXCQWXwK1O/saHfUEJjeE6w
VvTMe8xgl5qmkU+9U2TS6HdyVItD9fHZ3sAwVHo7mYtLGXp0S8F2hiiyLgQeQo84
F/owinPaPU8c+2Ogw464HbROmjU7Vc/iHQklA0kR+lZsFwZuWd+nYjmPrNfm87Ik
k9Wenco7wwFUquoJ8XZW1RVTr9WRWWlyNKwPnil5aBUGtbG6CP1+IFN75xfJYjz5
g+JcLHYsKyb6JhPYxT42ZdgTPKVRJNuIpyOMXMIPB/qFgUyU+2T/g7vxoa3THllq
vkp/ds5lpDe+uu6H9mbtMYvX5w9TBqt7YPegWcTUhGERnytXxeNpncYkzGMMUN0C
AwEAAaOCAb8wggG7MB8GA1UdIwQYMBaAFB4Fo3ePbJbiW4dLprSGrHEADOc4MB0G
A1UdDgQWBBRISoMA6cVQE5089wT6LFO4aiNnzTAOBgNVHQ8BAf8EBAMCBaAwDAYD
VR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwZwYDVR0g
BGAwXjBSBgwrBgEEAa4jAQQDAQEwQjBABggrBgEFBQcCARY0aHR0cHM6Ly93d3cu
aW5jb21tb24ub3JnL2NlcnQvcmVwb3NpdG9yeS9jcHNfc3NsLnBkZjAIBgZngQwB
AgIwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC5pbmNvbW1vbi1yc2Eub3Jn
L0luQ29tbW9uUlNBU2VydmVyQ0EuY3JsMHUGCCsGAQUFBwEBBGkwZzA+BggrBgEF
BQcwAoYyaHR0cDovL2NydC51c2VydHJ1c3QuY29tL0luQ29tbW9uUlNBU2VydmVy
Q0FfMi5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20w
FgYDVR0RBA8wDYILcGdwLm1pdC5lZHUwDQYJKoZIhvcNAQELBQADggEBAHbQqv2o
LrRD8rMzaHvPHVa92gfi6bpEsiRsVw3kpH4D4k+PL9LWkgtgTWpM+MvskiUvS9ay
FbWdXiy/peOj421fwnL/re9gmWs1g7FtUrDgIpz2T2jonPqbnIJPMHxI+ICWZMYH
V/dO844geRKAiGs/UZbG4Uf1Jo0PxtPtD5puaUk4l9Va8WHU2OLq0kzS9K+iu/sx
z0XG+fAMneyiXm5jtfjYE2W8/h61RhZulSUmYBkiMLzKr5eqe2VIkMqyTfyZ5zms
1LZ1GWaouMsTBN1+2TXssQ71L1tIZg/lXJVlfVRkwOIV5Mp3ohxLSBZT8qNSef1v
mFNa+DGU1sdl6m4=
-----END CERTIFICATE-----

View file

@ -91,14 +91,15 @@ public class KeychainApplication extends Application {
}
brandGlowEffect(getApplicationContext(),
FormattingUtils.getColorFromAttr(getApplicationContext(), R.attr.colorPrimary));
FormattingUtils.getColorFromAttr(getApplicationContext(), R.attr.colorPrimary));
setupAccountAsNeeded(this);
// Update keyserver list as needed
Preferences.getPreferences(this).upgradePreferences(this);
TlsHelper.addStaticCA("pool.sks-keyservers.net", getAssets(), "sks-keyservers.netCA.cer");
TlsHelper.addPinnedCertificate("hkps.pool.sks-keyservers.net", getAssets(), "hkps.pool.sks-keyservers.net.CA.cer");
TlsHelper.addPinnedCertificate("pgp.mit.edu", getAssets(), "pgp.mit.edu.cer");
TemporaryStorageProvider.cleanUp(this);

View file

@ -204,11 +204,15 @@ public class HkpKeyserver extends Keyserver {
OkHttpClient client = new OkHttpClient();
try {
TlsHelper.pinCertificateIfNecessary(client, url);
TlsHelper.usePinnedCertificateIfAvailable(client, url);
} catch (TlsHelper.TlsHelperException e) {
Log.w(Constants.TAG, e);
}
// don't follow any redirects
client.setFollowRedirects(false);
client.setFollowSslRedirects(false);
if (proxy != null) {
client.setProxy(proxy);
client.setConnectTimeout(30000, TimeUnit.MILLISECONDS);

View file

@ -155,7 +155,7 @@ public class SettingsKeyserverFragment extends Fragment implements RecyclerItemC
data.getBoolean(AddEditKeyserverDialogFragment.MESSAGE_VERIFIED);
if (verified) {
Notify.create(getActivity(),
R.string.add_keyserver_verified, Notify.Style.OK).show();
R.string.add_keyserver_connection_verified, Notify.Style.OK).show();
} else {
Notify.create(getActivity(),
R.string.add_keyserver_without_verification,
@ -177,26 +177,6 @@ public class SettingsKeyserverFragment extends Fragment implements RecyclerItemC
}
break;
}
case AddEditKeyserverDialogFragment.MESSAGE_VERIFICATION_FAILED: {
AddEditKeyserverDialogFragment.FailureReason failureReason =
(AddEditKeyserverDialogFragment.FailureReason) data.getSerializable(
AddEditKeyserverDialogFragment.MESSAGE_FAILURE_REASON);
switch (failureReason) {
case CONNECTION_FAILED: {
Notify.create(getActivity(),
R.string.add_keyserver_connection_failed,
Notify.Style.ERROR).show();
break;
}
case INVALID_URL: {
Notify.create(getActivity(),
R.string.add_keyserver_invalid_url,
Notify.Style.ERROR).show();
break;
}
}
break;
}
}
}
};

View file

@ -24,6 +24,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import android.app.Activity;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
@ -44,6 +45,7 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@ -54,6 +56,7 @@ import com.squareup.okhttp.Request;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.TlsHelper;
@ -68,11 +71,9 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
private static final String ARG_KEYSERVER = "arg_keyserver";
public static final int MESSAGE_OKAY = 1;
public static final int MESSAGE_VERIFICATION_FAILED = 2;
public static final String MESSAGE_KEYSERVER = "new_keyserver";
public static final String MESSAGE_VERIFIED = "verified";
public static final String MESSAGE_FAILURE_REASON = "failure_reason";
public static final String MESSAGE_KEYSERVER_DELETED = "keyserver_deleted";
public static final String MESSAGE_DIALOG_ACTION = "message_dialog_action";
public static final String MESSAGE_EDIT_POSITION = "keyserver_edited_position";
@ -82,7 +83,9 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
private int mPosition;
private EditText mKeyserverEditText;
private TextInputLayout mKeyserverEditTextLayout;
private CheckBox mVerifyKeyserverCheckBox;
private CheckBox mOnlyTrustedKeyserverCheckBox;
public enum DialogAction {
ADD,
@ -91,7 +94,8 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
public enum FailureReason {
INVALID_URL,
CONNECTION_FAILED
CONNECTION_FAILED,
NO_PINNED_CERTIFICATE
}
public static AddEditKeyserverDialogFragment newInstance(Messenger messenger,
@ -126,7 +130,15 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
alert.setView(view);
mKeyserverEditText = (EditText) view.findViewById(R.id.keyserver_url_edit_text);
mVerifyKeyserverCheckBox = (CheckBox) view.findViewById(R.id.verify_keyserver_checkbox);
mKeyserverEditTextLayout = (TextInputLayout) view.findViewById(R.id.keyserver_url_edit_text_layout);
mVerifyKeyserverCheckBox = (CheckBox) view.findViewById(R.id.verify_connection_checkbox);
mOnlyTrustedKeyserverCheckBox = (CheckBox) view.findViewById(R.id.only_trusted_keyserver_checkbox);
mVerifyKeyserverCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mOnlyTrustedKeyserverCheckBox.setEnabled(isChecked);
}
});
switch (mDialogAction) {
case ADD: {
@ -212,6 +224,8 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
positiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mKeyserverEditTextLayout.setErrorEnabled(false);
// behaviour same for edit and add
final String keyserverUrl = mKeyserverEditText.getText().toString();
if (mVerifyKeyserverCheckBox.isChecked()) {
@ -220,13 +234,20 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
OrbotHelper.DialogActions dialogActions = new OrbotHelper.DialogActions() {
@Override
public void onOrbotStarted() {
verifyConnection(keyserverUrl,
proxyPrefs.parcelableProxy.getProxy());
verifyConnection(
keyserverUrl,
proxyPrefs.parcelableProxy.getProxy(),
mOnlyTrustedKeyserverCheckBox.isChecked()
);
}
@Override
public void onNeutralButton() {
verifyConnection(keyserverUrl, null);
verifyConnection(
keyserverUrl,
null,
mOnlyTrustedKeyserverCheckBox.isChecked()
);
}
@Override
@ -236,7 +257,11 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
};
if (OrbotHelper.putOrbotInRequiredState(dialogActions, getActivity())) {
verifyConnection(keyserverUrl, proxyPrefs.parcelableProxy.getProxy());
verifyConnection(
keyserverUrl,
proxyPrefs.parcelableProxy.getProxy(),
mOnlyTrustedKeyserverCheckBox.isChecked()
);
}
} else {
dismiss();
@ -272,14 +297,28 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
sendMessageToHandler(MESSAGE_OKAY, data);
}
public void verificationFailed(FailureReason reason) {
Bundle data = new Bundle();
data.putSerializable(MESSAGE_FAILURE_REASON, reason);
public void verificationFailed(FailureReason failureReason) {
switch (failureReason) {
case CONNECTION_FAILED: {
mKeyserverEditTextLayout.setError(
getString(R.string.add_keyserver_connection_failed));
break;
}
case INVALID_URL: {
mKeyserverEditTextLayout.setError(
getString(R.string.add_keyserver_invalid_url));
break;
}
case NO_PINNED_CERTIFICATE: {
mKeyserverEditTextLayout.setError(
getString(R.string.add_keyserver_keyserver_not_trusted));
break;
}
}
sendMessageToHandler(MESSAGE_VERIFICATION_FAILED, data);
}
public void verifyConnection(String keyserver, final Proxy proxy) {
public void verifyConnection(String keyserver, final Proxy proxy, final boolean onlyTrustedKeyserver) {
new AsyncTask<String, Void, FailureReason>() {
ProgressDialog mProgressDialog;
@ -288,7 +327,7 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
@Override
protected void onPreExecute() {
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setMessage(getString(R.string.progress_verifying_keyserver_url));
mProgressDialog.setMessage(getString(R.string.progress_verifying_keyserver_connection));
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
@ -316,7 +355,18 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On
Log.d("Converted URL", newKeyserver.toString());
OkHttpClient client = HkpKeyserver.getClient(newKeyserver.toURL(), proxy);
TlsHelper.pinCertificateIfNecessary(client, newKeyserver.toURL());
// don't follow any redirects
client.setFollowRedirects(false);
client.setFollowSslRedirects(false);
if (onlyTrustedKeyserver
&& !TlsHelper.usePinnedCertificateIfAvailable(client, newKeyserver.toURL())) {
Log.w(Constants.TAG, "No pinned certificate for this host in OpenKeychain's assets.");
reason = FailureReason.NO_PINNED_CERTIFICATE;
return reason;
}
client.newCall(new Request.Builder().url(newKeyserver.toURL()).build()).execute();
} catch (TlsHelper.TlsHelperException e) {
reason = FailureReason.CONNECTION_FAILED;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2013-2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.util;
import android.content.res.AssetManager;
import com.squareup.okhttp.OkHttpClient;
import org.sufficientlysecure.keychain.Constants;
import java.io.ByteArrayInputStream;
@ -37,7 +38,6 @@ import java.security.cert.CertificateFactory;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
@ -49,15 +49,14 @@ public class TlsHelper {
}
}
private static Map<String, byte[]> sStaticCA = new HashMap<>();
private static Map<String, byte[]> sPinnedCertificates = new HashMap<>();
public static void addStaticCA(String domain, byte[] certificate) {
sStaticCA.put(domain, certificate);
}
public static void addStaticCA(String domain, AssetManager assetManager, String name) {
/**
* Add certificate from assets to pinned certificate map.
*/
public static void addPinnedCertificate(String host, AssetManager assetManager, String cerFilename) {
try {
InputStream is = assetManager.open(name);
InputStream is = assetManager.open(cerFilename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int reads = is.read();
@ -68,27 +67,36 @@ public class TlsHelper {
is.close();
addStaticCA(domain, baos.toByteArray());
sPinnedCertificates.put(host, baos.toByteArray());
} catch (IOException e) {
Log.w(Constants.TAG, e);
}
}
public static void pinCertificateIfNecessary(OkHttpClient client, URL url) throws TlsHelperException, IOException {
/**
* Use pinned certificate for OkHttpClient if we have one.
*
* @return true, if certificate is available, false if not
* @throws TlsHelperException
* @throws IOException
*/
public static boolean usePinnedCertificateIfAvailable(OkHttpClient client, URL url) throws TlsHelperException, IOException {
if (url.getProtocol().equals("https")) {
for (String domain : sStaticCA.keySet()) {
if (url.getHost().endsWith(domain)) {
pinCertificate(sStaticCA.get(domain), client);
// use certificate PIN from assets if we have one
for (String host : sPinnedCertificates.keySet()) {
if (url.getHost().endsWith(host)) {
pinCertificate(sPinnedCertificates.get(host), client);
return true;
}
}
}
return false;
}
/**
* Modifies the client to accept only requests with a given certificate. Applies to all URLs requested by the
* client.
* Therefore a client that is pinned this way should be used to only make requests to URLs with passed certificate.
* TODO: Refactor - More like SSH StrictHostKeyChecking than pinning?
*
* @param certificate certificate to pin
* @param client OkHttpClient to enforce pinning on
@ -97,8 +105,10 @@ public class TlsHelper {
*/
private static void pinCertificate(byte[] certificate, OkHttpClient client)
throws TlsHelperException, IOException {
// We don't use OkHttp's CertificatePinner since it depends on a TrustManager to verify it too. Refer to
// note at end of description: http://square.github.io/okhttp/javadoc/com/squareup/okhttp/CertificatePinner.html
// We don't use OkHttp's CertificatePinner since it can not be used to pin self-signed
// certificate if such certificate is not accepted by TrustManager.
// (Refer to note at end of description:
// http://square.github.io/okhttp/javadoc/com/squareup/okhttp/CertificatePinner.html )
// Creating our own TrustManager that trusts only our certificate eliminates the need for certificate pinning
try {
// Load CA
@ -126,42 +136,4 @@ public class TlsHelper {
}
}
/**
* Opens a Connection that will only accept certificates signed with a specific CA and skips common name check.
* This is required for some distributed Keyserver networks like sks-keyservers.net
*
* @param certificate The X.509 certificate used to sign the servers certificate
* @param url Connection target
*/
public static HttpsURLConnection openCAConnection(byte[] certificate, URL url)
throws TlsHelperException, IOException {
try {
// Load CA
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate ca = cf.generateCertificate(new ByteArrayInputStream(certificate));
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the URLConnection to use a SocketFactory from our SSLContext
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
return urlConnection;
} catch (CertificateException | KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
throw new TlsHelperException(e);
}
}
}

View file

@ -9,21 +9,37 @@
android:paddingRight="24dp"
android:paddingTop="16dp">
<EditText
android:id="@+id/keyserver_url_edit_text"
<android.support.design.widget.TextInputLayout
android:id="@+id/keyserver_url_edit_text_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="8dp"
android:ems="10"
android:hint="@string/label_enter_keyserver_url"
android:imeOptions="actionDone" />
android:layout_marginBottom="8dp">
<EditText
android:id="@+id/keyserver_url_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:ems="10"
android:hint="@string/label_enter_keyserver_url"
android:imeOptions="actionDone"
android:inputType="textUri" />
</android.support.design.widget.TextInputLayout>
<CheckBox
android:id="@+id/verify_keyserver_checkbox"
android:id="@+id/verify_connection_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_verify_keyserver"
android:checked="true"/>
android:checked="true"
android:text="@string/label_verify_keyserver_connection" />
<CheckBox
android:id="@+id/only_trusted_keyserver_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/label_only_trusted_keyserver" />
</LinearLayout>

View file

@ -135,7 +135,7 @@
<string name="label_enable_compression">Zapnout kompresi</string>
<string name="label_encrypt_filenames">Zašifrovat jména souborů</string>
<string name="label_hidden_recipients">Skrýt příjemce</string>
<string name="label_verify_keyserver">Ověřit keyserver</string>
<string name="label_verify_keyserver_connection">Ověřit keyserver</string>
<string name="label_enter_keyserver_url">Zadejte URL keyserveru</string>
<string name="pref_keyserver">OpenPGP keyserver</string>
<string name="pref_keyserver_summary">Vyhledat klíče na vybraném OpenPGP keyserveru (protokol HKP)</string>
@ -496,7 +496,7 @@
<string name="view_key_fragment_no_system_contact">&lt;žádný&gt;</string>
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Přidat keyserver</string>
<string name="add_keyserver_verified">Keyserver ověřen!</string>
<string name="add_keyserver_connection_verified">Keyserver ověřen!</string>
<string name="add_keyserver_without_verification">Keyserver přidán bez verifikace.</string>
<string name="add_keyserver_invalid_url">Neplatná URL!</string>
<string name="add_keyserver_connection_failed">Nepodařilo se připojit ke key severu. Prosím ověřte URL a vaše připojení k internetu.</string>

View file

@ -155,7 +155,7 @@
<string name="label_enable_compression">Komprimierung aktivieren</string>
<string name="label_encrypt_filenames">Dateinamen verschlüsseln</string>
<string name="label_hidden_recipients">Empfänger verbergen</string>
<string name="label_verify_keyserver">Schlüsselserver verifizieren</string>
<string name="label_verify_keyserver_connection">Schlüsselserver verifizieren</string>
<string name="label_enter_keyserver_url">Schlüsselserver-URL eingeben</string>
<string name="label_keyserver_dialog_delete">Schlüsselserver löschen</string>
<string name="label_theme">Design</string>
@ -386,7 +386,7 @@
<string name="progress_deleting">Lösche Schlüssel…</string>
<string name="progress_con_saving">Zusammenführung: Sichere in den Zwischenspeicher...</string>
<string name="progress_con_reimport">Zusammenführung: Reimportiere...</string>
<string name="progress_verifying_keyserver_url">Schlüsselserver wird verifiziert…</string>
<string name="progress_verifying_keyserver_connection">Schlüsselserver wird verifiziert…</string>
<string name="progress_starting_orbot">Orbot wird gestartet…</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Via Name, E-Mail suchen...</string>
@ -691,7 +691,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Schlüsselserver hinzufügen</string>
<string name="edit_keyserver_dialog_title">Schlüsselserver bearbeiten</string>
<string name="add_keyserver_verified">Schlüsselserver verifiziert!</string>
<string name="add_keyserver_connection_verified">Schlüsselserver verifiziert!</string>
<string name="add_keyserver_without_verification">Schlüsselserver ohne Verifikation hinzugefügt.</string>
<string name="add_keyserver_invalid_url">Ungültige URL!</string>
<string name="add_keyserver_connection_failed">Verbindung zum Schlüsselserver fehlgeschlagen. Bitte überprüfe die URL und deine Internetverbindung.</string>

View file

@ -155,7 +155,7 @@
<string name="label_enable_compression">Habilitar compresión</string>
<string name="label_encrypt_filenames">Cifrar nombres de ficheros</string>
<string name="label_hidden_recipients">Ocultar receptores</string>
<string name="label_verify_keyserver">Verificar servidor de claves</string>
<string name="label_verify_keyserver_connection">Verificar servidor de claves</string>
<string name="label_enter_keyserver_url">Introduzca URL de servidor de claves</string>
<string name="label_keyserver_dialog_delete">Borrar servidor de claves</string>
<string name="label_theme">Tema decorativo</string>
@ -386,7 +386,7 @@
<string name="progress_deleting">borrando claves...</string>
<string name="progress_con_saving">consolidación: guardando en caché...</string>
<string name="progress_con_reimport">consolidación: reimportando</string>
<string name="progress_verifying_keyserver_url">verificando servidor de claves...</string>
<string name="progress_verifying_keyserver_connection">verificando servidor de claves...</string>
<string name="progress_starting_orbot">Iniciando Orbot...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Buscar mediante Nombre, Correo electrónico...</string>
@ -691,7 +691,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Añadir servidor de claves</string>
<string name="edit_keyserver_dialog_title">Editar servidor de claves</string>
<string name="add_keyserver_verified">¡Servidor de claves verificado!</string>
<string name="add_keyserver_connection_verified">¡Servidor de claves verificado!</string>
<string name="add_keyserver_without_verification">Servidor de claves añadido sin verificación</string>
<string name="add_keyserver_invalid_url">¡URL no válida!</string>
<string name="add_keyserver_connection_failed">Fallo al conectar al servidor de claves. Por favor, compuebe la URL y su conexión a Internet.</string>

View file

@ -154,7 +154,7 @@
<string name="label_enable_compression">Gaitu konpresioa</string>
<string name="label_encrypt_filenames">Enkriptatu agirizenak</string>
<string name="label_hidden_recipients">Ezkutatu jasotzaileak</string>
<string name="label_verify_keyserver">Egiaztatu giltza-zerbitzaria</string>
<string name="label_verify_keyserver_connection">Egiaztatu giltza-zerbitzaria</string>
<string name="label_enter_keyserver_url">Sartu giltza-zerbitzariaren URL-a</string>
<string name="label_keyserver_dialog_delete">Ezabatu giltza-zerbitzaria</string>
<string name="label_theme">Azalgaia</string>
@ -376,7 +376,7 @@
<string name="progress_deleting">giltzak ezabatzen...</string>
<string name="progress_con_saving">sendotu: katxean gordetzen...</string>
<string name="progress_con_reimport">sendotu: berrinportatzen...</string>
<string name="progress_verifying_keyserver_url">giltza-zerbitzaria egiaztatzen...</string>
<string name="progress_verifying_keyserver_connection">giltza-zerbitzaria egiaztatzen...</string>
<string name="progress_starting_orbot">Orbot Abiarazten...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Bilatu Izena, Post@... bidez</string>
@ -675,7 +675,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Gehitu giltza-zerbitzaria</string>
<string name="edit_keyserver_dialog_title">Editatu giltza-zerbitzaria</string>
<string name="add_keyserver_verified">Giltza-zerbitzaria egiaztatuta!</string>
<string name="add_keyserver_connection_verified">Giltza-zerbitzaria egiaztatuta!</string>
<string name="add_keyserver_without_verification">Giltza-zerbitzaria gehituta egiaztapen gabe.</string>
<string name="add_keyserver_invalid_url">URL baliogabea!</string>
<string name="add_keyserver_connection_failed">Hutsegitea giltza-zerbitzariarekin elkartzerakoan. Mesedez egiaztatu URL-a eta zure internet elkarketa.</string>

View file

@ -146,7 +146,7 @@
<string name="label_enable_compression">فشرده‌کردن</string>
<string name="label_encrypt_filenames">رمزگذاری اسمِ فایل‌ها</string>
<string name="label_hidden_recipients">مخفی‌کردن گیرنده‌ها</string>
<string name="label_verify_keyserver">بررسی سرورِ کلیدها</string>
<string name="label_verify_keyserver_connection">بررسی سرورِ کلیدها</string>
<string name="label_enter_keyserver_url">آدرس URL سرورِ کلید را وارد کنید</string>
<string name="label_keyserver_dialog_delete">حذف سرورهای کلید</string>
<string name="label_theme">قالب</string>

View file

@ -155,7 +155,7 @@
<string name="label_enable_compression">Activer la compression</string>
<string name="label_encrypt_filenames">Chiffrer les nom de fichier</string>
<string name="label_hidden_recipients">Cacher les destinataires</string>
<string name="label_verify_keyserver">Vérifier le serveur de clefs</string>
<string name="label_verify_keyserver_connection">Vérifier le serveur de clefs</string>
<string name="label_enter_keyserver_url">Saisir l\'URL du serveur de clefs</string>
<string name="label_keyserver_dialog_delete">Supprimer le serveur de clefs</string>
<string name="label_theme">Thème</string>
@ -386,7 +386,7 @@
<string name="progress_deleting">suppression des clefs...</string>
<string name="progress_con_saving">consolider : enregistrement dans le cache...</string>
<string name="progress_con_reimport">consolider : réimportation...</string>
<string name="progress_verifying_keyserver_url">vérification du serveur de clefs...</string>
<string name="progress_verifying_keyserver_connection">vérification du serveur de clefs...</string>
<string name="progress_starting_orbot">Démarrage d\'Orbot...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Chercher par nom, adresse courriel...</string>
@ -691,7 +691,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Ajouter un serveur de clefs</string>
<string name="edit_keyserver_dialog_title">Modifier le serveur de clefs</string>
<string name="add_keyserver_verified">Le serveur de clefs a été vérifié !</string>
<string name="add_keyserver_connection_verified">Le serveur de clefs a été vérifié !</string>
<string name="add_keyserver_without_verification">Le serveur de clefs a été ajouté sans vérification.</string>
<string name="add_keyserver_invalid_url">URL invalide !</string>
<string name="add_keyserver_connection_failed">Échec de connexion au serveur de clefs. Veuillez vérifier l\'URL et votre connexion Internet.</string>

View file

@ -149,7 +149,7 @@
<string name="label_enable_compression">Abilitare compressione</string>
<string name="label_encrypt_filenames">Codifica nome dei file</string>
<string name="label_hidden_recipients">Nascondi destinatari</string>
<string name="label_verify_keyserver">Verificare server chiavi</string>
<string name="label_verify_keyserver_connection">Verificare server chiavi</string>
<string name="label_enter_keyserver_url">Inserisci URL server chiavi</string>
<string name="label_keyserver_dialog_delete">Cancella server chiavi</string>
<string name="pref_keyserver">Server chiavi OpenPGP</string>

View file

@ -155,7 +155,7 @@
<string name="label_enable_compression">圧縮を有効</string>
<string name="label_encrypt_filenames">暗号化するファイル名</string>
<string name="label_hidden_recipients">受信者を隠す</string>
<string name="label_verify_keyserver">鍵サーバを検証</string>
<string name="label_verify_keyserver_connection">鍵サーバを検証</string>
<string name="label_enter_keyserver_url">鍵サーバのURLを入力</string>
<string name="label_keyserver_dialog_delete">鍵サーバの削除</string>
<string name="label_theme">テーマ</string>
@ -382,7 +382,7 @@
<string name="progress_deleting">鍵の削除中...</string>
<string name="progress_con_saving">統合: キャッシュへ保存…</string>
<string name="progress_con_reimport">統合: 再インポート中…</string>
<string name="progress_verifying_keyserver_url">鍵サーバの検証...</string>
<string name="progress_verifying_keyserver_connection">鍵サーバの検証...</string>
<string name="progress_starting_orbot">Orbotを始める...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">名前、Email...で検索</string>
@ -674,7 +674,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">鍵サーバを追加</string>
<string name="edit_keyserver_dialog_title">鍵サーバの編集</string>
<string name="add_keyserver_verified">鍵サーバを検証しました!</string>
<string name="add_keyserver_connection_verified">鍵サーバを検証しました!</string>
<string name="add_keyserver_without_verification">鍵サーバを検証なしで追加した。</string>
<string name="add_keyserver_invalid_url">無効なURLです!</string>
<string name="add_keyserver_connection_failed">鍵サーバへの接続し失敗。URLとあなたのインターネット接続をチェックしてください。</string>

View file

@ -151,7 +151,7 @@
<string name="label_enable_compression">Compressie aanzetten</string>
<string name="label_encrypt_filenames">Versleutel bestandsnamen</string>
<string name="label_hidden_recipients">Verberg ontvangers</string>
<string name="label_verify_keyserver">Sleutelserver verifiëren</string>
<string name="label_verify_keyserver_connection">Sleutelserver verifiëren</string>
<string name="label_enter_keyserver_url">Voer sleutelserver-URL in</string>
<string name="label_keyserver_dialog_delete">Sleutelserver verwijderen</string>
<string name="label_theme">Thema</string>
@ -366,7 +366,7 @@
<string name="progress_deleting">bezig met verwijderen van sleutels…</string>
<string name="progress_con_saving">consolidatie: bezig met opslaan naar cache…</string>
<string name="progress_con_reimport">consolidatie: bezig met opnieuw importeren…</string>
<string name="progress_verifying_keyserver_url">bezig met verifiëren van sleutelserver…</string>
<string name="progress_verifying_keyserver_connection">bezig met verifiëren van sleutelserver…</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Zoeken via naam, e-mail, ...</string>
<!--key bit length selections-->
@ -648,7 +648,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Sleutelserver toevoegen</string>
<string name="edit_keyserver_dialog_title">Sleutelserver bewerken</string>
<string name="add_keyserver_verified">Sleutelserver geverifieerd!</string>
<string name="add_keyserver_connection_verified">Sleutelserver geverifieerd!</string>
<string name="add_keyserver_without_verification">Sleutelserver toegevoegd zonder verificatie.</string>
<string name="add_keyserver_invalid_url">Ongeldige URL!</string>
<string name="add_keyserver_connection_failed">Kon niet verbinden met sleutelserver. Controleer de URL en je internetverbinding.</string>

View file

@ -152,7 +152,7 @@
<string name="label_enable_compression">Использовать сжатие</string>
<string name="label_encrypt_filenames">Шифровать имена файлов</string>
<string name="label_hidden_recipients">Скрыть получателей</string>
<string name="label_verify_keyserver">Подтвердить сервер ключей</string>
<string name="label_verify_keyserver_connection">Подтвердить сервер ключей</string>
<string name="label_enter_keyserver_url">Введите адрес сервера ключей</string>
<string name="label_keyserver_dialog_delete">Удалить сервер ключей</string>
<string name="label_theme">Тема</string>
@ -364,7 +364,7 @@
<string name="progress_deleting">удаление ключей...</string>
<string name="progress_con_saving">объединение: сохранение в кэш...</string>
<string name="progress_con_reimport">объединение: реимпорт...</string>
<string name="progress_verifying_keyserver_url">подтверждение сервера ключей...</string>
<string name="progress_verifying_keyserver_connection">подтверждение сервера ключей...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Искать через Имя, Email...</string>
<!--key bit length selections-->
@ -568,7 +568,7 @@
<string name="view_key_fragment_no_system_contact">&lt;нет&gt;</string>
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Добавить сервер ключей</string>
<string name="add_keyserver_verified">Сервер ключей подтверждён!</string>
<string name="add_keyserver_connection_verified">Сервер ключей подтверждён!</string>
<string name="add_keyserver_without_verification">Сервер ключей добавлен без подтверждения.</string>
<string name="add_keyserver_invalid_url">Неправильный адрес!</string>
<!--Navigation Drawer-->

View file

@ -155,7 +155,7 @@
<string name="label_enable_compression">Омогући компресију</string>
<string name="label_encrypt_filenames">Шифруј имена фајлова</string>
<string name="label_hidden_recipients">Сакриј примаоце</string>
<string name="label_verify_keyserver">Овери сервер кључева</string>
<string name="label_verify_keyserver_connection">Овери сервер кључева</string>
<string name="label_enter_keyserver_url">Унесите УРЛ сервера кључева</string>
<string name="label_keyserver_dialog_delete">Обриши сервер кључева</string>
<string name="label_theme">Тема</string>
@ -390,7 +390,7 @@
<string name="progress_deleting">бришем кључеве…</string>
<string name="progress_con_saving">учвршћивање: уписујем у кеш…</string>
<string name="progress_con_reimport">учвршћивање: поново увозим…</string>
<string name="progress_verifying_keyserver_url">оверавам сервер кључева…</string>
<string name="progress_verifying_keyserver_connection">оверавам сервер кључева…</string>
<string name="progress_starting_orbot">Покрећем Орбот…</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Тражи преко имена, е-адресе…</string>
@ -709,7 +709,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Додај сервер кључева</string>
<string name="edit_keyserver_dialog_title">Промени сервер кључева</string>
<string name="add_keyserver_verified">Сервер кључева оверен!</string>
<string name="add_keyserver_connection_verified">Сервер кључева оверен!</string>
<string name="add_keyserver_without_verification">Сервер кључева додат без оверивања.</string>
<string name="add_keyserver_invalid_url">Неисправан УРЛ!</string>
<string name="add_keyserver_connection_failed">Неуспех повезивања са сервером кључева. Проверите УРЛ и вашу везу са интернетом.</string>

View file

@ -135,7 +135,7 @@
<string name="label_enable_compression">Aktivera kompression</string>
<string name="label_encrypt_filenames">Kryptera filnamn</string>
<string name="label_hidden_recipients">Dölj mottagare</string>
<string name="label_verify_keyserver">Verifiera nyckelserver</string>
<string name="label_verify_keyserver_connection">Verifiera nyckelserver</string>
<string name="label_enter_keyserver_url">Ange nyckelserver-URL</string>
<string name="pref_keyserver">OpenPGP nyckelservrar</string>
<string name="pref_keyserver_summary">Sök nycklar på valda OpenPGP nyckelservrar (HKP-protokollet)</string>
@ -313,7 +313,7 @@
<string name="progress_deleting">raderar nycklar…</string>
<string name="progress_con_saving">konsolidera: sparar till cache…</string>
<string name="progress_con_reimport">konsolidera: återimporterar…</string>
<string name="progress_verifying_keyserver_url">verifierar nyckelserver...</string>
<string name="progress_verifying_keyserver_connection">verifierar nyckelserver...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">Söker via Namn, E-post...</string>
<!--key bit length selections-->
@ -565,7 +565,7 @@
<string name="view_key_fragment_no_system_contact">&lt;ingen&gt;</string>
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">Lägg till nyckelserver</string>
<string name="add_keyserver_verified">Nyckelserver verifierad!</string>
<string name="add_keyserver_connection_verified">Nyckelserver verifierad!</string>
<string name="add_keyserver_without_verification">Nyckelserver tillagd utan verifiering.</string>
<string name="add_keyserver_invalid_url">Ogiltig URL!</string>
<string name="add_keyserver_connection_failed">Misslyckades med att ansluta till nyckelserver. Kontrollera URL:en och din internetanslutning.</string>

View file

@ -149,7 +149,7 @@
<string name="label_enable_compression">啓用壓縮</string>
<string name="label_encrypt_filenames">加密檔名</string>
<string name="label_hidden_recipients">隱藏收件人</string>
<string name="label_verify_keyserver">驗證金鑰伺服器</string>
<string name="label_verify_keyserver_connection">驗證金鑰伺服器</string>
<string name="label_enter_keyserver_url">輸入金鑰伺服器網址</string>
<string name="label_keyserver_dialog_delete">刪除金鑰伺服器</string>
<string name="label_theme">主題</string>
@ -362,7 +362,7 @@
<string name="progress_verifying_integrity">正在驗證完整性…</string>
<string name="progress_deleting_securely">正在安全地刪除 \'%s\'...</string>
<string name="progress_deleting">正在刪除金鑰…</string>
<string name="progress_verifying_keyserver_url">正在驗證金鑰伺服器...</string>
<string name="progress_verifying_keyserver_connection">正在驗證金鑰伺服器...</string>
<string name="progress_starting_orbot">正在啟動Orbot...</string>
<!--action strings-->
<string name="hint_cloud_search_hint">使用姓名,電子郵件尋找...</string>
@ -625,7 +625,7 @@
<!--Add/Edit keyserver-->
<string name="add_keyserver_dialog_title">新增金鑰伺服器</string>
<string name="edit_keyserver_dialog_title">編輯金鑰伺服器</string>
<string name="add_keyserver_verified">已驗證金鑰伺服器!</string>
<string name="add_keyserver_connection_verified">已驗證金鑰伺服器!</string>
<string name="add_keyserver_without_verification">已新增金鑰伺服器但並未進行驗證。</string>
<string name="add_keyserver_invalid_url">URL無效</string>
<string name="add_keyserver_connection_failed">連線到金鑰伺服器失敗。請確認金鑰伺服器網址及網路連線。</string>

View file

@ -172,8 +172,9 @@
<string name="label_encrypt_filenames">"Encrypt filenames"</string>
<string name="label_hidden_recipients">"Hide recipients"</string>
<string name="label_verify_keyserver">"Verify keyserver"</string>
<string name="label_enter_keyserver_url">"Enter keyserver URL"</string>
<string name="label_verify_keyserver_connection">"Test connection"</string>
<string name="label_only_trusted_keyserver">"Only trusted keyserver"</string>
<string name="label_enter_keyserver_url">"URL"</string>
<string name="label_keyserver_dialog_delete">"Delete keyserver"</string>
<string name="label_theme">"Theme"</string>
@ -445,7 +446,7 @@
<string name="progress_con_saving">"consolidate: saving to cache…"</string>
<string name="progress_con_reimport">"consolidate: reimporting…"</string>
<string name="progress_verifying_keyserver_url">"verifying keyserver…"</string>
<string name="progress_verifying_keyserver_connection">"verifying connection…"</string>
<string name="progress_starting_orbot">"Starting Orbot…"</string>
@ -778,9 +779,10 @@
<!-- Add/Edit keyserver -->
<string name="add_keyserver_dialog_title">"Add keyserver"</string>
<string name="edit_keyserver_dialog_title">"Edit keyserver"</string>
<string name="add_keyserver_verified">"Keyserver verified!"</string>
<string name="add_keyserver_connection_verified">"Connection verified!"</string>
<string name="add_keyserver_without_verification">"Keyserver added without verification."</string>
<string name="add_keyserver_invalid_url">"Invalid URL!"</string>
<string name="add_keyserver_keyserver_not_trusted">"Keyserver is not one of the trusted ones (no pinned certificate available)!"</string>
<string name="add_keyserver_connection_failed">"Failed to connect to keyserver. Please check the URL and your Internet connection."</string>
<string name="keyserver_preference_deleted">"%s deleted"</string>
<string name="keyserver_preference_cannot_delete_last">"Cannot delete last keyserver. At least one is required!"</string>