Merge branch 'master' into improve-file-more

Conflicts:
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
	OpenKeychain/src/main/res/layout/encrypt_content.xml
This commit is contained in:
mar-v-in 2014-07-06 02:24:34 +02:00
commit fdf6411d5f
74 changed files with 11697 additions and 1929 deletions

View File

@ -89,12 +89,12 @@
android:label="@string/title_wizard"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".ui.EditKeyActivity"
android:name=".ui.EditKeyActivityOld"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_edit_key"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".ui.EditKeyActivityNew"
android:name=".ui.EditKeyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_edit_key"
android:windowSoftInputMode="stateHidden" />

View File

@ -38,6 +38,7 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
@ -50,6 +51,9 @@ import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel;
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Primes;
import java.io.IOException;
@ -63,6 +67,7 @@ import java.security.SignatureException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;
/**
@ -99,18 +104,13 @@ public class PgpKeyOperation {
}
/** Creates new secret key. */
private PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
boolean isMasterKey) throws PgpGeneralMsgIdException {
private PGPKeyPair createKey(int algorithmChoice, int keySize) throws PgpGeneralMsgIdException {
try {
if (keySize < 512) {
throw new PgpGeneralMsgIdException(R.string.error_key_size_minimum512bit);
}
if (passphrase == null) {
passphrase = "";
}
int algorithm;
KeyPairGenerator keyGen;
@ -123,9 +123,6 @@ public class PgpKeyOperation {
}
case Constants.choice.algorithm.elgamal: {
if (isMasterKey) {
throw new PgpGeneralMsgIdException(R.string.error_master_key_must_not_be_el_gamal);
}
keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
BigInteger p = Primes.getBestPrime(keySize);
BigInteger g = new BigInteger("2");
@ -151,19 +148,8 @@ public class PgpKeyOperation {
}
// build new key pair
PGPKeyPair keyPair = new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
return new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
// define hashing and signing algos
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
HashAlgorithmTags.SHA1);
// Build key encrypter and decrypter based on passphrase
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
PGPEncryptedData.CAST5, sha1Calc)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor);
} catch(NoSuchProviderException e) {
throw new RuntimeException(e);
} catch(NoSuchAlgorithmException e) {
@ -175,6 +161,55 @@ public class PgpKeyOperation {
}
}
public UncachedKeyRing createSecretKeyRing(SaveKeyringParcel saveParcel, OperationLog log,
int indent) {
try {
log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_KEYID, indent);
indent += 1;
updateProgress(R.string.progress_building_key, 0, 100);
if (saveParcel.addSubKeys == null || saveParcel.addSubKeys.isEmpty()) {
log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_NO_MASTER, indent);
return null;
}
SubkeyAdd add = saveParcel.addSubKeys.remove(0);
PGPKeyPair keyPair = createKey(add.mAlgorithm, add.mKeysize);
if (add.mAlgorithm == Constants.choice.algorithm.elgamal) {
throw new PgpGeneralMsgIdException(R.string.error_master_key_must_not_be_el_gamal);
}
// define hashing and signing algos
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
.build().get(HashAlgorithmTags.SHA1);
// Build key encrypter and decrypter based on passphrase
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
PGPEncryptedData.CAST5, sha1Calc)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
PGPSecretKey masterSecretKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, true, keyEncryptor);
PGPSecretKeyRing sKR = new PGPSecretKeyRing(
masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator());
return internal(sKR, masterSecretKey, saveParcel, "", log, indent);
} catch (PGPException e) {
Log.e(Constants.TAG, "pgp error encoding key", e);
return null;
} catch (IOException e) {
Log.e(Constants.TAG, "io error encoding key", e);
return null;
} catch (PgpGeneralMsgIdException e) {
Log.e(Constants.TAG, "pgp msg id error", e);
return null;
}
}
/** This method introduces a list of modifications specified by a SaveKeyringParcel to a
* WrappedSecretKeyRing.
*
@ -204,14 +239,40 @@ public class PgpKeyOperation {
indent += 1;
updateProgress(R.string.progress_building_key, 0, 100);
// Make sure this is called with a proper SaveKeyringParcel
if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) {
log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_KEYID, indent);
return null;
}
// We work on bouncycastle object level here
PGPSecretKeyRing sKR = wsKR.getRing();
PGPPublicKey masterPublicKey = sKR.getPublicKey();
PGPSecretKey masterSecretKey = sKR.getSecretKey();
// Make sure the fingerprint matches
if (saveParcel.mFingerprint == null
|| !Arrays.equals(saveParcel.mFingerprint,
masterSecretKey.getPublicKey().getFingerprint())) {
log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_FINGERPRINT, indent);
return null;
}
return internal(sKR, masterSecretKey, saveParcel, passphrase, log, indent);
}
private UncachedKeyRing internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey,
SaveKeyringParcel saveParcel, String passphrase,
OperationLog log, int indent) {
updateProgress(R.string.progress_certifying_master_key, 20, 100);
PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
// 1. Unlock private key
log.add(LogLevel.DEBUG, LogType.MSG_MF_UNLOCK, indent);
PGPPrivateKey masterPrivateKey; {
PGPPrivateKey masterPrivateKey;
{
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
@ -221,11 +282,6 @@ public class PgpKeyOperation {
return null;
}
}
if (!Arrays.equals(saveParcel.mFingerprint, sKR.getPublicKey().getFingerprint())) {
return null;
}
updateProgress(R.string.progress_certifying_master_key, 20, 100);
// work on master secret key
try {
@ -235,14 +291,42 @@ public class PgpKeyOperation {
// 2a. Add certificates for new user ids
for (String userId : saveParcel.addUserIds) {
log.add(LogLevel.INFO, LogType.MSG_MF_UID_ADD, indent);
// this operation supersedes all previous binding and revocation certificates,
// so remove those to retain assertions from canonicalization for later operations
@SuppressWarnings("unchecked")
Iterator<PGPSignature> it = modifiedPublicKey.getSignaturesForID(userId);
if (it != null) {
for (PGPSignature cert : new IterableIterator<PGPSignature>(it)) {
// if it's not a self cert, never mind
if (cert.getKeyID() != masterPublicKey.getKeyID()) {
continue;
}
if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION
|| cert.getSignatureType() == PGPSignature.NO_CERTIFICATION
|| cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION
|| cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION
|| cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) {
modifiedPublicKey = PGPPublicKey.removeCertification(
modifiedPublicKey, userId, cert);
}
}
}
// if it's supposed to be primary, we can do that here as well
boolean isPrimary = saveParcel.changePrimaryUserId != null
&& userId.equals(saveParcel.changePrimaryUserId);
// generate and add new certificate
PGPSignature cert = generateUserIdSignature(masterPrivateKey,
masterPublicKey, userId, false);
masterPublicKey, userId, isPrimary);
modifiedPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, cert);
}
// 2b. Add revocations for revoked user ids
for (String userId : saveParcel.revokeUserIds) {
log.add(LogLevel.INFO, LogType.MSG_MF_UID_REVOKE, indent);
// a duplicate revocatin will be removed during canonicalization, so no need to
// take care of that here.
PGPSignature cert = generateRevocationSignature(masterPrivateKey,
masterPublicKey, userId);
modifiedPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, cert);
@ -251,7 +335,84 @@ public class PgpKeyOperation {
// 3. If primary user id changed, generate new certificates for both old and new
if (saveParcel.changePrimaryUserId != null) {
log.add(LogLevel.INFO, LogType.MSG_MF_UID_PRIMARY, indent);
// todo
// we work on the modifiedPublicKey here, to respect new or newly revoked uids
// noinspection unchecked
for (String userId : new IterableIterator<String>(modifiedPublicKey.getUserIDs())) {
boolean isRevoked = false;
PGPSignature currentCert = null;
// noinspection unchecked
for (PGPSignature cert : new IterableIterator<PGPSignature>(
masterPublicKey.getSignaturesForID(userId))) {
// if it's not a self cert, never mind
if (cert.getKeyID() != masterPublicKey.getKeyID()) {
continue;
}
// we know from canonicalization that if there is any revocation here, it
// is valid and not superseded by a newer certification.
if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION) {
isRevoked = true;
continue;
}
// we know from canonicalization that there is only one binding
// certification here, so we can just work with the first one.
if (cert.getSignatureType() == PGPSignature.NO_CERTIFICATION ||
cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION ||
cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION ||
cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) {
currentCert = cert;
}
}
if (currentCert == null) {
// no certificate found?! error error error
log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent);
return null;
}
// we definitely should not update certifications of revoked keys, so just leave it.
if (isRevoked) {
// revoked user ids cannot be primary!
if (userId.equals(saveParcel.changePrimaryUserId)) {
log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_REVOKED_PRIMARY, indent);
return null;
}
continue;
}
// if this is~ the/a primary user id
if (currentCert.hasSubpackets() && currentCert.getHashedSubPackets().isPrimaryUserID()) {
// if it's the one we want, just leave it as is
if (userId.equals(saveParcel.changePrimaryUserId)) {
continue;
}
// otherwise, generate new non-primary certification
modifiedPublicKey = PGPPublicKey.removeCertification(
modifiedPublicKey, userId, currentCert);
PGPSignature newCert = generateUserIdSignature(
masterPrivateKey, masterPublicKey, userId, false);
modifiedPublicKey = PGPPublicKey.addCertification(
modifiedPublicKey, userId, newCert);
continue;
}
// if we are here, this is not currently a primary user id
// if it should be
if (userId.equals(saveParcel.changePrimaryUserId)) {
// add shiny new primary user id certificate
modifiedPublicKey = PGPPublicKey.removeCertification(
modifiedPublicKey, userId, currentCert);
PGPSignature newCert = generateUserIdSignature(
masterPrivateKey, masterPublicKey, userId, true);
modifiedPublicKey = PGPPublicKey.addCertification(
modifiedPublicKey, userId, newCert);
}
// user id is not primary and is not supposed to be - nothing to do here.
}
}
// Update the secret key ring
@ -261,7 +422,6 @@ public class PgpKeyOperation {
sKR = PGPSecretKeyRing.insertSecretKey(sKR, masterSecretKey);
}
// 4a. For each subkey change, generate new subkey binding certificate
for (SaveKeyringParcel.SubkeyChange change : saveParcel.changeSubKeys) {
log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_CHANGE,
@ -280,7 +440,8 @@ public class PgpKeyOperation {
return null;
}
// generate and add new signature
// generate and add new signature. we can be sloppy here and just leave the old one,
// it will be removed during canonicalization
PGPSignature sig = generateSubkeyBindingSignature(masterPublicKey, masterPrivateKey,
sKey, pKey, change.mFlags, change.mExpiry, passphrase);
pKey = PGPPublicKey.addCertification(pKey, sig);
@ -316,16 +477,36 @@ public class PgpKeyOperation {
}
log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent);
PGPSecretKey sKey = createKey(add.mAlgorithm, add.mKeysize, passphrase, false);
// generate a new secret key (privkey only for now)
PGPKeyPair keyPair = createKey(add.mAlgorithm, add.mKeysize);
// add subkey binding signature (making this a sub rather than master key)
PGPPublicKey pKey = keyPair.getPublicKey();
PGPSignature cert = generateSubkeyBindingSignature(
masterPublicKey, masterPrivateKey, keyPair.getPrivateKey(), pKey,
add.mFlags, add.mExpiry);
pKey = PGPPublicKey.addSubkeyBindingCertification(pKey, cert);
PGPSecretKey sKey; {
// define hashing and signing algos
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
.build().get(HashAlgorithmTags.SHA1);
// Build key encrypter and decrypter based on passphrase
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
PGPEncryptedData.CAST5, sha1Calc)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey,
sha1Calc, false, keyEncryptor);
}
log.add(LogLevel.DEBUG, LogType.MSG_MF_SUBKEY_NEW_ID,
indent+1, PgpKeyHelper.convertKeyIdToHex(sKey.getKeyID()));
PGPPublicKey pKey = sKey.getPublicKey();
PGPSignature cert = generateSubkeyBindingSignature(masterPublicKey, masterPrivateKey,
sKey, pKey, add.mFlags, add.mExpiry, passphrase);
pKey = PGPPublicKey.addCertification(pKey, cert);
sKey = PGPSecretKey.replacePublicKey(sKey, pKey);
sKR = PGPSecretKeyRing.insertSecretKey(sKR, PGPSecretKey.replacePublicKey(sKey, pKey));
sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
} catch (PgpGeneralMsgIdException e) {
return null;
}
@ -420,6 +601,18 @@ public class PgpKeyOperation {
PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey,
PGPSecretKey sKey, PGPPublicKey pKey, int flags, Long expiry, String passphrase)
throws IOException, PGPException, SignatureException {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
passphrase.toCharArray());
PGPPrivateKey subPrivateKey = sKey.extractPrivateKey(keyDecryptor);
return generateSubkeyBindingSignature(masterPublicKey, masterPrivateKey, subPrivateKey,
pKey, flags, expiry);
}
private static PGPSignature generateSubkeyBindingSignature(
PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey,
PGPPrivateKey subPrivateKey, PGPPublicKey pKey, int flags, Long expiry)
throws IOException, PGPException, SignatureException {
// date for signing
Date todayDate = new Date();
@ -427,12 +620,6 @@ public class PgpKeyOperation {
// If this key can sign, we need a primary key binding signature
if ((flags & KeyFlags.SIGN_DATA) != 0) {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
passphrase.toCharArray());
PGPPrivateKey subPrivateKey = sKey.extractPrivateKey(keyDecryptor);
// cross-certify signing keys
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
subHashedPacketsGen.setSignatureCreationTime(false, todayDate);

View File

@ -8,16 +8,13 @@ import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
import java.security.NoSuchProviderException;
import java.util.Iterator;
public class WrappedSecretKeyRing extends WrappedKeyRing {
@ -91,29 +88,6 @@ public class WrappedSecretKeyRing extends WrappedKeyRing {
}
}
public UncachedKeyRing changeSecretKeyPassphrase(String oldPassphrase,
String newPassphrase)
throws IOException, PGPException, NoSuchProviderException {
if (oldPassphrase == null) {
oldPassphrase = "";
}
if (newPassphrase == null) {
newPassphrase = "";
}
PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword(
mRing,
new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()),
new JcePBESecretKeyEncryptorBuilder(mRing.getSecretKey()
.getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray()));
return new UncachedKeyRing(newKeyRing);
}
public IterableIterator<WrappedSecretKey> secretKeyIterator() {
final Iterator<PGPSecretKey> it = mRing.getSecretKeys();
return new IterableIterator<WrappedSecretKey>(new Iterator<WrappedSecretKey>() {

View File

@ -405,7 +405,11 @@ public class ProviderHelper {
// classify and order user ids. primary are moved to the front, revoked to the back,
// otherwise the order in the keyfile is preserved.
if (trustedKeys.size() == 0) {
log(LogLevel.INFO, LogType.MSG_IP_UID_CLASSIFYING_ZERO);
} else {
log(LogLevel.INFO, LogType.MSG_IP_UID_CLASSIFYING, trustedKeys.size());
}
mIndent += 1;
List<UserIdItem> uids = new ArrayList<UserIdItem>();
for (String userId : new IterableIterator<String>(

View File

@ -35,7 +35,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.ui.EditKeyActivity;
import org.sufficientlysecure.keychain.ui.EditKeyActivityOld;
import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;
import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter;
import org.sufficientlysecure.keychain.util.AlgorithmNames;
@ -163,11 +163,11 @@ public class AccountSettingsFragment extends Fragment implements
}
private void createKey() {
Intent intent = new Intent(getActivity(), EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
Intent intent = new Intent(getActivity(), EditKeyActivityOld.class);
intent.setAction(EditKeyActivityOld.ACTION_CREATE_KEY);
intent.putExtra(EditKeyActivityOld.EXTRA_GENERATE_DEFAULT_KEYS, true);
// set default user id to account name
intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, mAccSettings.getAccountName());
intent.putExtra(EditKeyActivityOld.EXTRA_USER_IDS, mAccSettings.getAccountName());
startActivityForResult(intent, REQUEST_CODE_CREATE_KEY);
}

View File

@ -215,6 +215,10 @@ public class KeychainIntentService extends IntentService
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
Bundle data = extras.getBundle(EXTRA_DATA);
if (data == null) {
Log.e(Constants.TAG, "data extra is null!");
return;
}
OtherHelper.logDebugBundle(data, "EXTRA_DATA");
@ -331,33 +335,41 @@ public class KeychainIntentService extends IntentService
try {
/* Input */
SaveKeyringParcel saveParcel = data.getParcelable(SAVE_KEYRING_PARCEL);
long masterKeyId = saveParcel.mMasterKeyId;
if (saveParcel == null) {
Log.e(Constants.TAG, "bug: missing save_keyring_parcel in data!");
return;
}
/* Operation */
ProviderHelper providerHelper = new ProviderHelper(this);
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 50, 100));
try {
String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
WrappedSecretKeyRing secRing = providerHelper.getWrappedSecretKeyRing(masterKeyId);
OperationLog log = new OperationLog();
UncachedKeyRing ring = keyOperations.modifySecretKeyRing(secRing, saveParcel,
UncachedKeyRing ring;
if (saveParcel.mMasterKeyId != null) {
String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
WrappedSecretKeyRing secRing =
providerHelper.getWrappedSecretKeyRing(saveParcel.mMasterKeyId);
ring = keyOperations.modifySecretKeyRing(secRing, saveParcel,
passphrase, log, 0);
providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
} else {
ring = keyOperations.createSecretKeyRing(saveParcel, log, 0);
}
providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 10, 95, 100));
// cache new passphrase
if (saveParcel.newPassphrase != null) {
PassphraseCacheService.addCachedPassphrase(this, ring.getMasterKeyId(),
saveParcel.newPassphrase);
}
} catch (ProviderHelper.NotFoundException e) {
// UncachedKeyRing ring = keyOperations.(saveParcel); //new Keyring
// save the pair
setProgress(R.string.progress_saving_key_ring, 95, 100);
// providerHelper.saveSecretKeyRing(ring);
sendErrorToHandler(e);
}
setProgress(R.string.progress_done, 100, 100);
if (saveParcel.newPassphrase != null) {
PassphraseCacheService.addCachedPassphrase(this, masterKeyId, saveParcel.newPassphrase);
}
/* Output */
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
} catch (Exception e) {
@ -458,7 +470,7 @@ public class KeychainIntentService extends IntentService
outStream);
if (mIsCanceled && outputFile != null) {
boolean isDeleted = new File(outputFile).delete();
new File(outputFile).delete();
}
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
@ -614,6 +626,7 @@ public class KeychainIntentService extends IntentService
return;
}
Message msg = Message.obtain();
assert msg != null;
msg.arg1 = arg1;
if (arg2 != null) {
msg.arg2 = arg2;

View File

@ -27,8 +27,10 @@ import android.support.v4.app.FragmentManager;
import com.devspark.appmsg.AppMsg;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
public class KeychainIntentServiceHandler extends Handler {
@ -126,6 +128,7 @@ public class KeychainIntentServiceHandler extends Handler {
break;
default:
Log.e(Constants.TAG, "unknown handler message!");
break;
}
}

View File

@ -165,6 +165,7 @@ public class OperationResultParcel implements Parcelable {
MSG_IP_UID_CERT_ERROR (R.string.msg_ip_uid_cert_error),
MSG_IP_UID_CERT_GOOD (R.string.msg_ip_uid_cert_good),
MSG_IP_UID_CERTS_UNKNOWN (R.plurals.msg_ip_uid_certs_unknown),
MSG_IP_UID_CLASSIFYING_ZERO (R.string.msg_ip_uid_classifying_zero),
MSG_IP_UID_CLASSIFYING (R.plurals.msg_ip_uid_classifying),
MSG_IP_UID_REORDER(R.string.msg_ip_uid_reorder),
MSG_IP_UID_PROCESSING (R.string.msg_ip_uid_processing),
@ -233,9 +234,16 @@ public class OperationResultParcel implements Parcelable {
MSG_MG_NEW_SUBKEY (R.string.msg_mg_new_subkey),
MSG_MG_FOUND_NEW (R.string.msg_mg_found_new),
// secret key create
MSG_CR_ERROR_NO_MASTER (R.string.msg_mr),
// secret key modify
MSG_MF (R.string.msg_mr),
MSG_MF_ERROR_ENCODE (R.string.msg_mf_error_encode),
MSG_MF_ERROR_FINGERPRINT (R.string.msg_mf_error_fingerprint),
MSG_MF_ERROR_KEYID (R.string.msg_mf_error_keyid),
MSG_MF_ERROR_INTEGRITY (R.string.msg_mf_error_integrity),
MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary),
MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp),
MSG_MF_ERROR_SIG (R.string.msg_mf_error_sig),
MSG_MF_PASSPHRASE (R.string.msg_mf_passphrase),

View File

@ -49,7 +49,6 @@ import java.util.Date;
* convenience.
*/
public class PassphraseCacheService extends Service {
public static final String TAG = Constants.TAG + ": PassphraseCacheService";
public static final String ACTION_PASSPHRASE_CACHE_ADD = Constants.INTENT_PREFIX
+ "PASSPHRASE_CACHE_ADD";
@ -83,7 +82,7 @@ public class PassphraseCacheService extends Service {
* @param passphrase
*/
public static void addCachedPassphrase(Context context, long keyId, String passphrase) {
Log.d(TAG, "cacheNewPassphrase() for " + keyId);
Log.d(Constants.TAG, "PassphraseCacheService.cacheNewPassphrase() for " + keyId);
Intent intent = new Intent(context, PassphraseCacheService.class);
intent.setAction(ACTION_PASSPHRASE_CACHE_ADD);
@ -103,7 +102,7 @@ public class PassphraseCacheService extends Service {
* @return passphrase or null (if no passphrase is cached for this keyId)
*/
public static String getCachedPassphrase(Context context, long keyId) {
Log.d(TAG, "getCachedPassphrase() get masterKeyId for " + keyId);
Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphrase() get masterKeyId for " + keyId);
Intent intent = new Intent(context, PassphraseCacheService.class);
intent.setAction(ACTION_PASSPHRASE_CACHE_GET);
@ -159,7 +158,7 @@ public class PassphraseCacheService extends Service {
private String getCachedPassphraseImpl(long keyId) {
// passphrase for symmetric encryption?
if (keyId == Constants.key.symmetric) {
Log.d(TAG, "getCachedPassphraseImpl() for symmetric encryption");
Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphraseImpl() for symmetric encryption");
String cachedPassphrase = mPassphraseCache.get(Constants.key.symmetric);
if (cachedPassphrase == null) {
return null;
@ -170,7 +169,7 @@ public class PassphraseCacheService extends Service {
// try to get master key id which is used as an identifier for cached passphrases
try {
Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + keyId);
Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphraseImpl() for masterKeyId " + keyId);
WrappedSecretKeyRing key = new ProviderHelper(this).getWrappedSecretKeyRing(
KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId));
// no passphrase needed? just add empty string and return it, then
@ -184,18 +183,18 @@ public class PassphraseCacheService extends Service {
// get cached passphrase
String cachedPassphrase = mPassphraseCache.get(keyId);
if (cachedPassphrase == null) {
Log.d(TAG, "Passphrase not (yet) cached, returning null");
Log.d(Constants.TAG, "PassphraseCacheService Passphrase not (yet) cached, returning null");
// not really an error, just means the passphrase is not cached but not empty either
return null;
}
// set it again to reset the cache life cycle
Log.d(TAG, "Cache passphrase again when getting it!");
Log.d(Constants.TAG, "PassphraseCacheService Cache passphrase again when getting it!");
addCachedPassphrase(this, keyId, cachedPassphrase);
return cachedPassphrase;
} catch (ProviderHelper.NotFoundException e) {
Log.e(TAG, "Passphrase for unknown key was requested!");
Log.e(Constants.TAG, "PassphraseCacheService Passphrase for unknown key was requested!");
return null;
}
}
@ -212,7 +211,7 @@ public class PassphraseCacheService extends Service {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "Received broadcast...");
Log.d(Constants.TAG, "PassphraseCacheService Received broadcast...");
if (action.equals(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
@ -248,7 +247,7 @@ public class PassphraseCacheService extends Service {
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand()");
Log.d(Constants.TAG, "PassphraseCacheService.onStartCommand()");
// register broadcastreceiver
registerReceiver();
@ -259,8 +258,8 @@ public class PassphraseCacheService extends Service {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
String passphrase = intent.getStringExtra(EXTRA_PASSPHRASE);
Log.d(TAG,
"Received ACTION_PASSPHRASE_CACHE_ADD intent in onStartCommand() with keyId: "
Log.d(Constants.TAG,
"PassphraseCacheService Received ACTION_PASSPHRASE_CACHE_ADD intent in onStartCommand() with keyId: "
+ keyId + ", ttl: " + ttl);
// add keyId and passphrase to memory
@ -285,10 +284,10 @@ public class PassphraseCacheService extends Service {
try {
messenger.send(msg);
} catch (RemoteException e) {
Log.e(Constants.TAG, "Sending message failed", e);
Log.e(Constants.TAG, "PassphraseCacheService Sending message failed", e);
}
} else {
Log.e(Constants.TAG, "Intent or Intent Action not supported!");
Log.e(Constants.TAG, "PassphraseCacheService Intent or Intent Action not supported!");
}
}
@ -305,11 +304,11 @@ public class PassphraseCacheService extends Service {
// remove passphrase corresponding to keyId from memory
mPassphraseCache.remove(keyId);
Log.d(TAG, "Timeout of keyId " + keyId + ", removed from memory!");
Log.d(Constants.TAG, "PassphraseCacheService Timeout of keyId " + keyId + ", removed from memory!");
// stop whole service if no cached passphrases remaining
if (mPassphraseCache.size() == 0) {
Log.d(TAG, "No passphrases remaining in memory, stopping service!");
Log.d(Constants.TAG, "PassphraseCacheServic No passphrases remaining in memory, stopping service!");
stopSelf();
}
}

View File

@ -22,10 +22,10 @@ import java.util.ArrayList;
*/
public class SaveKeyringParcel implements Parcelable {
// the master key id to be edited
public final long mMasterKeyId;
// the key fingerprint, for safety
public final byte[] mFingerprint;
// the master key id to be edited. if this is null, a new one will be created
public Long mMasterKeyId;
// the key fingerprint, for safety. MUST be null for a new key.
public byte[] mFingerprint;
public String newPassphrase;
@ -38,9 +38,7 @@ public class SaveKeyringParcel implements Parcelable {
public ArrayList<String> revokeUserIds;
public ArrayList<Long> revokeSubKeys;
public SaveKeyringParcel(long masterKeyId, byte[] fingerprint) {
mMasterKeyId = masterKeyId;
mFingerprint = fingerprint;
public SaveKeyringParcel() {
addUserIds = new ArrayList<String>();
addSubKeys = new ArrayList<SubkeyAdd>();
changeSubKeys = new ArrayList<SubkeyChange>();
@ -48,13 +46,19 @@ public class SaveKeyringParcel implements Parcelable {
revokeSubKeys = new ArrayList<Long>();
}
public SaveKeyringParcel(long masterKeyId, byte[] fingerprint) {
this();
mMasterKeyId = masterKeyId;
mFingerprint = fingerprint;
}
// performance gain for using Parcelable here would probably be negligible,
// use Serializable instead.
public static class SubkeyAdd implements Serializable {
public final int mAlgorithm;
public final int mKeysize;
public final int mFlags;
public final Long mExpiry;
public int mAlgorithm;
public int mKeysize;
public int mFlags;
public Long mExpiry;
public SubkeyAdd(int algorithm, int keysize, int flags, Long expiry) {
mAlgorithm = algorithm;
mKeysize = keysize;
@ -64,9 +68,9 @@ public class SaveKeyringParcel implements Parcelable {
}
public static class SubkeyChange implements Serializable {
public final long mKeyId;
public final Integer mFlags;
public final Long mExpiry;
public long mKeyId;
public Integer mFlags;
public Long mExpiry;
public SubkeyChange(long keyId, Integer flags, Long expiry) {
mKeyId = keyId;
mFlags = flags;
@ -75,9 +79,11 @@ public class SaveKeyringParcel implements Parcelable {
}
public SaveKeyringParcel(Parcel source) {
mMasterKeyId = source.readLong();
mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
mFingerprint = source.createByteArray();
newPassphrase = source.readString();
addUserIds = source.createStringArrayList();
addSubKeys = (ArrayList<SubkeyAdd>) source.readSerializable();
@ -90,9 +96,14 @@ public class SaveKeyringParcel implements Parcelable {
@Override
public void writeToParcel(Parcel destination, int flags) {
destination.writeInt(mMasterKeyId == null ? 0 : 1);
if(mMasterKeyId != null) {
destination.writeLong(mMasterKeyId);
}
destination.writeByteArray(mFingerprint);
destination.writeString(newPassphrase);
destination.writeStringList(addUserIds);
destination.writeSerializable(addSubKeys);

View File

@ -155,7 +155,7 @@ public class DecryptActivity extends DrawerActivity {
} else if (ACTION_DECRYPT.equals(action) && uri != null) {
mFileFragmentBundle.putParcelable(DecryptFileFragment.ARG_URI, uri);
mSwitchToTab = PAGER_TAB_FILE;
} else {
} else if (ACTION_DECRYPT.equals(action)) {
Log.e(Constants.TAG,
"Include the extra 'text' or an Uri with setData() in your Intent!");
}

View File

@ -1,6 +1,5 @@
/*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2014 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
@ -18,732 +17,52 @@
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.devspark.appmsg.AppMsg;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.UncachedSecretKey;
import org.sufficientlysecure.keychain.pgp.WrappedSecretKey;
import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.widget.Editor;
import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
import org.sufficientlysecure.keychain.ui.widget.KeyEditor;
import org.sufficientlysecure.keychain.ui.widget.SectionView;
import org.sufficientlysecure.keychain.ui.widget.UserIdEditor;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Vector;
public class EditKeyActivity extends ActionBarActivity {
public class EditKeyActivity extends ActionBarActivity implements EditorListener {
// Actions for internal use only:
public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY";
public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEY";
// possible extra keys
public static final String EXTRA_USER_IDS = "user_ids";
public static final String EXTRA_NO_PASSPHRASE = "no_passphrase";
public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys";
// EDIT
private Uri mDataUri;
private SectionView mUserIdsView;
private SectionView mKeysView;
private String mCurrentPassphrase = null;
private String mNewPassphrase = null;
private String mSavedNewPassphrase = null;
private boolean mIsPassphraseSet;
private boolean mNeedsSaving;
private boolean mIsBrandNewKeyring = false;
private Button mChangePassphrase;
private CheckBox mNoPassphrase;
Vector<String> mUserIds;
Vector<UncachedSecretKey> mKeys;
Vector<Integer> mKeysUsages;
boolean mMasterCanSign = true;
ExportHelper mExportHelper;
public boolean needsSaving() {
mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving();
mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving();
mNeedsSaving |= hasPassphraseChanged();
mNeedsSaving |= mIsBrandNewKeyring;
return mNeedsSaving;
}
public void somethingChanged() {
ActivityCompat.invalidateOptionsMenu(this);
}
public void onDeleted(Editor e, boolean wasNewItem) {
somethingChanged();
}
public void onEdited() {
somethingChanged();
}
private EditKeyFragment mEditKeyFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mExportHelper = new ExportHelper(this);
setContentView(R.layout.edit_key_activity_new);
// Inflate a "Done"/"Cancel" custom action bar view
ActionBarHelper.setTwoButtonView(getSupportActionBar(),
R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Save
saveClicked();
}
}, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Cancel
cancelClicked();
}
}
);
mUserIds = new Vector<String>();
mKeys = new Vector<UncachedSecretKey>();
mKeysUsages = new Vector<Integer>();
// Catch Intents opened from other apps
Intent intent = getIntent();
String action = intent.getAction();
if (ACTION_CREATE_KEY.equals(action)) {
handleActionCreateKey(intent);
} else if (ACTION_EDIT_KEY.equals(action)) {
handleActionEditKey(intent);
}
}
/**
* Handle intent action to create new key
*
* @param intent
*/
private void handleActionCreateKey(Intent intent) {
Bundle extras = intent.getExtras();
mCurrentPassphrase = "";
mIsBrandNewKeyring = true;
if (extras != null) {
// if userId is given, prefill the fields
if (extras.containsKey(EXTRA_USER_IDS)) {
Log.d(Constants.TAG, "UserIds are given!");
mUserIds.add(extras.getString(EXTRA_USER_IDS));
}
// if no passphrase is given
if (extras.containsKey(EXTRA_NO_PASSPHRASE)) {
boolean noPassphrase = extras.getBoolean(EXTRA_NO_PASSPHRASE);
if (noPassphrase) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
mChangePassphrase.setVisibility(View.GONE);
}
}
// generate key
if (extras.containsKey(EXTRA_GENERATE_DEFAULT_KEYS)) {
/*
boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS);
if (generateDefaultKeys) {
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
mCurrentPassphrase);
serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after generating is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
this, getResources().getQuantityString(R.plurals.progress_generating, 1),
ProgressDialog.STYLE_HORIZONTAL, true,
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// Stop key generation on cancel
stopService(serviceIntent);
EditKeyActivity.this.setResult(Activity.RESULT_CANCELED);
EditKeyActivity.this.finish();
}
}) {
@Override
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getData();
ArrayList<UncachedSecretKey> newKeys =
PgpConversionHelper.BytesToPGPSecretKeyList(data
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));
ArrayList<Integer> keyUsageFlags = data.getIntegerArrayList(
KeychainIntentService.RESULT_KEY_USAGES);
if (newKeys.size() == keyUsageFlags.size()) {
for (int i = 0; i < newKeys.size(); ++i) {
mKeys.add(newKeys.get(i));
mKeysUsages.add(keyUsageFlags.get(i));
}
}
buildLayout(true);
}
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
serviceIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(this);
// start service with intent
startService(serviceIntent);
}
*/
}
} else {
buildLayout(false);
}
}
/**
* Handle intent action to edit existing key
*
* @param intent
*/
private void handleActionEditKey(Intent intent) {
mDataUri = intent.getData();
if (mDataUri == null) {
Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
Uri dataUri = getIntent().getData();
if (dataUri == null) {
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
finish();
} else {
Log.d(Constants.TAG, "uri: " + mDataUri);
try {
Uri secretUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
WrappedSecretKeyRing keyRing = new ProviderHelper(this).getWrappedSecretKeyRing(secretUri);
mMasterCanSign = keyRing.getSubKey().canCertify();
for (WrappedSecretKey key : keyRing.secretKeyIterator()) {
// Turn into uncached instance
mKeys.add(key.getUncached());
mKeysUsages.add(key.getKeyUsage()); // get usage when view is created
}
boolean isSet = false;
for (String userId : keyRing.getSubKey().getUserIds()) {
Log.d(Constants.TAG, "Added userId " + userId);
if (!isSet) {
isSet = true;
String[] parts = KeyRing.splitUserId(userId);
if (parts[0] != null) {
setTitle(parts[0]);
}
}
mUserIds.add(userId);
}
buildLayout(false);
mCurrentPassphrase = "";
mIsPassphraseSet = keyRing.hasPassphrase();
if (!mIsPassphraseSet) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
mChangePassphrase.setVisibility(View.GONE);
}
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "Keyring not found: " + e.getMessage(), e);
Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_SHORT).show();
finish();
}
}
}
/**
* Shows the dialog to set a new passphrase
*/
private void showSetPassphraseDialog() {
// Message is received after passphrase is cached
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) {
Bundle data = message.getData();
// set new returned passphrase!
mNewPassphrase = data
.getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE);
updatePassphraseButtonText();
somethingChanged();
}
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(returnHandler);
// set title based on isPassphraseSet()
int title;
if (isPassphraseSet()) {
title = R.string.title_change_passphrase;
} else {
title = R.string.title_set_passphrase;
}
SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance(
messenger, title);
setPassphraseDialog.show(getSupportFragmentManager(), "setPassphraseDialog");
}
/**
* Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user
* id and key.
*
* @param newKeys
*/
private void buildLayout(boolean newKeys) {
setContentView(R.layout.edit_key_activity);
// find views
mChangePassphrase = (Button) findViewById(R.id.edit_key_btn_change_passphrase);
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
// Build layout based on given userIds and keys
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container);
if (mIsPassphraseSet) {
mChangePassphrase.setText(getString(R.string.btn_change_passphrase));
}
mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
mUserIdsView.setType(SectionView.TYPE_USER_ID);
mUserIdsView.setCanBeEdited(mMasterCanSign);
mUserIdsView.setUserIds(mUserIds);
mUserIdsView.setEditorListener(this);
container.addView(mUserIdsView);
mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
mKeysView.setType(SectionView.TYPE_KEY);
mKeysView.setCanBeEdited(mMasterCanSign);
mKeysView.setKeys(mKeys, mKeysUsages, newKeys);
mKeysView.setEditorListener(this);
container.addView(mKeysView);
updatePassphraseButtonText();
mChangePassphrase.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showSetPassphraseDialog();
}
});
// disable passphrase when no passphrase checkbox is checked!
mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// remove passphrase
mSavedNewPassphrase = mNewPassphrase;
mNewPassphrase = "";
mChangePassphrase.setVisibility(View.GONE);
} else {
mNewPassphrase = mSavedNewPassphrase;
mChangePassphrase.setVisibility(View.VISIBLE);
}
somethingChanged();
}
});
}
private long getMasterKeyId() {
if (mKeysView.getEditors().getChildCount() == 0) {
return 0;
}
return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyId();
}
public boolean isPassphraseSet() {
if (mNoPassphrase.isChecked()) {
return true;
} else if ((mIsPassphraseSet)
|| (mNewPassphrase != null && !mNewPassphrase.equals(""))) {
return true;
} else {
return false;
}
}
public boolean hasPassphraseChanged() {
if (mNoPassphrase != null) {
if (mNoPassphrase.isChecked()) {
return mIsPassphraseSet;
} else {
return (mNewPassphrase != null && !mNewPassphrase.equals(""));
}
} else {
return false;
}
}
private void saveClicked() {
final long masterKeyId = getMasterKeyId();
if (needsSaving()) { //make sure, as some versions don't support invalidateOptionsMenu
try {
if (!isPassphraseSet()) {
throw new PgpGeneralException(this.getString(R.string.set_a_passphrase));
}
String passphrase;
if (mIsPassphraseSet) {
passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
} else {
passphrase = "";
}
if (passphrase == null) {
PassphraseDialogFragment.show(this, masterKeyId,
new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
EditKeyActivity.this, masterKeyId);
checkEmptyIDsWanted();
}
}
});
} else {
mCurrentPassphrase = passphrase;
checkEmptyIDsWanted();
}
} catch (PgpGeneralException e) {
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
AppMsg.STYLE_ALERT).show();
}
} else {
AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show();
}
}
private void checkEmptyIDsWanted() {
try {
ArrayList<String> userIDs = getUserIds(mUserIdsView);
List<Boolean> newIDs = mUserIdsView.getNewIDFlags();
ArrayList<String> originalIDs = mUserIdsView.getOriginalIDs();
int curID = 0;
for (String userID : userIDs) {
if (userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID))) {
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(
EditKeyActivity.this);
alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
alert.setTitle(R.string.warning);
alert.setMessage(EditKeyActivity.this.getString(R.string.ask_empty_id_ok));
alert.setPositiveButton(EditKeyActivity.this.getString(android.R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
finallySaveClicked();
}
}
);
alert.setNegativeButton(this.getString(android.R.string.no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
}
);
alert.setCancelable(false);
alert.show();
return;
}
curID++;
}
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show();
}
finallySaveClicked();
loadFragment(savedInstanceState, dataUri);
}
private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
final boolean[] primitives = new boolean[booleanList.size()];
int index = 0;
for (Boolean object : booleanList) {
primitives[index++] = object;
}
return primitives;
private void loadFragment(Bundle savedInstanceState, Uri dataUri) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
private void finallySaveClicked() {
/*
try {
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(this, KeychainIntentService.class);
// Create an instance of the fragment
mEditKeyFragment = EditKeyFragment.newInstance(dataUri);
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
OldSaveKeyringParcel saveParams = new OldSaveKeyringParcel();
saveParams.userIds = getUserIds(mUserIdsView);
saveParams.originalIDs = mUserIdsView.getOriginalIDs();
saveParams.deletedIDs = mUserIdsView.getDeletedIDs();
saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags());
saveParams.primaryIDChanged = mUserIdsView.primaryChanged();
saveParams.moddedKeys = toPrimitiveArray(mKeysView.getNeedsSavingArray());
saveParams.deletedKeys = mKeysView.getDeletedKeys();
saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView);
saveParams.keysUsages = getKeysUsages(mKeysView);
saveParams.newPassphrase = mNewPassphrase;
saveParams.oldPassphrase = mCurrentPassphrase;
saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray());
saveParams.keys = getKeys(mKeysView);
saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID();
// fill values for this action
Bundle data = new Bundle();
data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, mMasterCanSign);
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, saveParams);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after saving is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
Intent data = new Intent();
// return uri pointing to new created key
Uri uri = KeyRings.buildGenericKeyRingUri(getMasterKeyId());
data.setData(uri);
setResult(RESULT_OK, data);
finish();
}
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(this);
// start service with intent
startService(intent);
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
AppMsg.STYLE_ALERT).show();
}
*/
}
private void cancelClicked() {
if (needsSaving()) { //ask if we want to save
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(
EditKeyActivity.this);
alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
alert.setTitle(R.string.warning);
alert.setMessage(EditKeyActivity.this.getString(R.string.ask_save_changed_key));
alert.setPositiveButton(EditKeyActivity.this.getString(android.R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
saveClicked();
}
});
alert.setNegativeButton(this.getString(android.R.string.no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
setResult(RESULT_CANCELED);
finish();
}
});
alert.setCancelable(false);
alert.show();
} else {
setResult(RESULT_CANCELED);
finish();
}
}
/**
* Returns user ids from the SectionView
*
* @param userIdsView
* @return
*/
private ArrayList<String> getUserIds(SectionView userIdsView) throws PgpGeneralException {
ArrayList<String> userIds = new ArrayList<String>();
ViewGroup userIdEditors = userIdsView.getEditors();
boolean gotMainUserId = false;
for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
String userId;
userId = editor.getValue();
if (editor.isMainUserId()) {
userIds.add(0, userId);
gotMainUserId = true;
} else {
userIds.add(userId);
}
}
if (userIds.size() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_a_user_id));
}
if (!gotMainUserId) {
throw new PgpGeneralException(getString(R.string.error_main_user_id_must_not_be_empty));
}
return userIds;
}
/**
* Returns keys from the SectionView
*
* @param keysView
* @return
*/
private ArrayList<UncachedSecretKey> getKeys(SectionView keysView) throws PgpGeneralException {
ArrayList<UncachedSecretKey> keys = new ArrayList<UncachedSecretKey>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keys.add(editor.getValue());
}
return keys;
}
/**
* Returns usage selections of keys from the SectionView
*
* @param keysView
* @return
*/
private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PgpGeneralException {
ArrayList<Integer> keysUsages = new ArrayList<Integer>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keysUsages.add(editor.getUsage());
}
return keysUsages;
}
private ArrayList<Calendar> getKeysExpiryDates(SectionView keysView) throws PgpGeneralException {
ArrayList<Calendar> keysExpiryDates = new ArrayList<Calendar>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keysExpiryDates.add(editor.getExpiryDate());
}
return keysExpiryDates;
}
private void updatePassphraseButtonText() {
mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
: getString(R.string.btn_set_passphrase));
// Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
getSupportFragmentManager().beginTransaction()
.replace(R.id.edit_key_fragment_container, mEditKeyFragment)
.commitAllowingStateLoss();
// do it immediately!
getSupportFragmentManager().executePendingTransactions();
}
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
public class EditKeyActivityNew extends ActionBarActivity {
private EditKeyFragment mEditKeyFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_key_activity_new);
Uri dataUri = getIntent().getData();
if (dataUri == null) {
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
finish();
return;
}
loadFragment(savedInstanceState, dataUri);
}
private void loadFragment(Bundle savedInstanceState, Uri dataUri) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create an instance of the fragment
mEditKeyFragment = EditKeyFragment.newInstance(dataUri);
// Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
getSupportFragmentManager().beginTransaction()
.replace(R.id.edit_key_fragment_container, mEditKeyFragment)
.commitAllowingStateLoss();
// do it immediately!
getSupportFragmentManager().executePendingTransactions();
}
}

View File

@ -0,0 +1,744 @@
/*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.devspark.appmsg.AppMsg;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedSecretKey;
import org.sufficientlysecure.keychain.pgp.WrappedSecretKey;
import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.widget.Editor;
import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
import org.sufficientlysecure.keychain.ui.widget.KeyEditor;
import org.sufficientlysecure.keychain.ui.widget.SectionView;
import org.sufficientlysecure.keychain.ui.widget.UserIdEditor;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Vector;
public class EditKeyActivityOld extends ActionBarActivity implements EditorListener {
// Actions for internal use only:
public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY";
public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEY";
// possible extra keys
public static final String EXTRA_USER_IDS = "user_ids";
public static final String EXTRA_NO_PASSPHRASE = "no_passphrase";
public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys";
// EDIT
private Uri mDataUri;
private SectionView mUserIdsView;
private SectionView mKeysView;
private String mCurrentPassphrase = null;
private String mNewPassphrase = null;
private String mSavedNewPassphrase = null;
private boolean mIsPassphraseSet;
private boolean mNeedsSaving;
private boolean mIsBrandNewKeyring = false;
private Button mChangePassphrase;
private CheckBox mNoPassphrase;
Vector<String> mUserIds;
Vector<UncachedSecretKey> mKeys;
Vector<Integer> mKeysUsages;
boolean mMasterCanSign = true;
ExportHelper mExportHelper;
public boolean needsSaving() {
mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving();
mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving();
mNeedsSaving |= hasPassphraseChanged();
mNeedsSaving |= mIsBrandNewKeyring;
return mNeedsSaving;
}
public void somethingChanged() {
ActivityCompat.invalidateOptionsMenu(this);
}
public void onDeleted(Editor e, boolean wasNewItem) {
somethingChanged();
}
public void onEdited() {
somethingChanged();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mExportHelper = new ExportHelper(this);
// Inflate a "Done"/"Cancel" custom action bar view
ActionBarHelper.setTwoButtonView(getSupportActionBar(),
R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Save
saveClicked();
}
}, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Cancel
cancelClicked();
}
}
);
mUserIds = new Vector<String>();
mKeys = new Vector<UncachedSecretKey>();
mKeysUsages = new Vector<Integer>();
// Catch Intents opened from other apps
Intent intent = getIntent();
String action = intent.getAction();
if (ACTION_CREATE_KEY.equals(action)) {
handleActionCreateKey(intent);
} else if (ACTION_EDIT_KEY.equals(action)) {
handleActionEditKey(intent);
}
}
/**
* Handle intent action to create new key
*
* @param intent
*/
private void handleActionCreateKey(Intent intent) {
Bundle extras = intent.getExtras();
mCurrentPassphrase = "";
mIsBrandNewKeyring = true;
if (extras != null) {
// if userId is given, prefill the fields
if (extras.containsKey(EXTRA_USER_IDS)) {
Log.d(Constants.TAG, "UserIds are given!");
mUserIds.add(extras.getString(EXTRA_USER_IDS));
}
// if no passphrase is given
if (extras.containsKey(EXTRA_NO_PASSPHRASE)) {
boolean noPassphrase = extras.getBoolean(EXTRA_NO_PASSPHRASE);
if (noPassphrase) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
mChangePassphrase.setVisibility(View.GONE);
}
}
// generate key
if (extras.containsKey(EXTRA_GENERATE_DEFAULT_KEYS)) {
/*
boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS);
if (generateDefaultKeys) {
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
mCurrentPassphrase);
serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after generating is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
this, getResources().getQuantityString(R.plurals.progress_generating, 1),
ProgressDialog.STYLE_HORIZONTAL, true,
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// Stop key generation on cancel
stopService(serviceIntent);
EditKeyActivity.this.setResult(Activity.RESULT_CANCELED);
EditKeyActivity.this.finish();
}
}) {
@Override
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getDataAsStringList();
ArrayList<UncachedSecretKey> newKeys =
PgpConversionHelper.BytesToPGPSecretKeyList(data
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));
ArrayList<Integer> keyUsageFlags = data.getIntegerArrayList(
KeychainIntentService.RESULT_KEY_USAGES);
if (newKeys.size() == keyUsageFlags.size()) {
for (int i = 0; i < newKeys.size(); ++i) {
mKeys.add(newKeys.get(i));
mKeysUsages.add(keyUsageFlags.get(i));
}
}
buildLayout(true);
}
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
serviceIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(this);
// start service with intent
startService(serviceIntent);
}
*/
}
} else {
buildLayout(false);
}
}
/**
* Handle intent action to edit existing key
*
* @param intent
*/
private void handleActionEditKey(Intent intent) {
mDataUri = intent.getData();
if (mDataUri == null) {
Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
finish();
} else {
Log.d(Constants.TAG, "uri: " + mDataUri);
try {
Uri secretUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
WrappedSecretKeyRing keyRing = new ProviderHelper(this).getWrappedSecretKeyRing(secretUri);
mMasterCanSign = keyRing.getSubKey().canCertify();
for (WrappedSecretKey key : keyRing.secretKeyIterator()) {
// Turn into uncached instance
mKeys.add(key.getUncached());
mKeysUsages.add(key.getKeyUsage()); // get usage when view is created
}
boolean isSet = false;
for (String userId : keyRing.getSubKey().getUserIds()) {
Log.d(Constants.TAG, "Added userId " + userId);
if (!isSet) {
isSet = true;
String[] parts = KeyRing.splitUserId(userId);
if (parts[0] != null) {
setTitle(parts[0]);
}
}
mUserIds.add(userId);
}
buildLayout(false);
mCurrentPassphrase = "";
mIsPassphraseSet = keyRing.hasPassphrase();
if (!mIsPassphraseSet) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
mChangePassphrase.setVisibility(View.GONE);
}
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "Keyring not found: " + e.getMessage(), e);
Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_SHORT).show();
finish();
}
}
}
/**
* Shows the dialog to set a new passphrase
*/
private void showSetPassphraseDialog() {
// Message is received after passphrase is cached
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) {
Bundle data = message.getData();
// set new returned passphrase!
mNewPassphrase = data
.getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE);
updatePassphraseButtonText();
somethingChanged();
}
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(returnHandler);
// set title based on isPassphraseSet()
int title;
if (isPassphraseSet()) {
title = R.string.title_change_passphrase;
} else {
title = R.string.title_set_passphrase;
}
SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance(
messenger, null, title);
setPassphraseDialog.show(getSupportFragmentManager(), "setPassphraseDialog");
}
/**
* Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user
* id and key.
*
* @param newKeys
*/
private void buildLayout(boolean newKeys) {
setContentView(R.layout.edit_key_activity);
// find views
mChangePassphrase = (Button) findViewById(R.id.edit_key_btn_change_passphrase);
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
// Build layout based on given userIds and keys
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container);
if (mIsPassphraseSet) {
mChangePassphrase.setText(getString(R.string.btn_change_passphrase));
}
mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
mUserIdsView.setType(SectionView.TYPE_USER_ID);
mUserIdsView.setCanBeEdited(mMasterCanSign);
mUserIdsView.setUserIds(mUserIds);
mUserIdsView.setEditorListener(this);
container.addView(mUserIdsView);
mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
mKeysView.setType(SectionView.TYPE_KEY);
mKeysView.setCanBeEdited(mMasterCanSign);
mKeysView.setKeys(mKeys, mKeysUsages, newKeys);
mKeysView.setEditorListener(this);
container.addView(mKeysView);
updatePassphraseButtonText();
mChangePassphrase.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showSetPassphraseDialog();
}
});
// disable passphrase when no passphrase checkbox is checked!
mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// remove passphrase
mSavedNewPassphrase = mNewPassphrase;
mNewPassphrase = "";
mChangePassphrase.setVisibility(View.GONE);
} else {
mNewPassphrase = mSavedNewPassphrase;
mChangePassphrase.setVisibility(View.VISIBLE);
}
somethingChanged();
}
});
}
private long getMasterKeyId() {
if (mKeysView.getEditors().getChildCount() == 0) {
return 0;
}
return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyId();
}
public boolean isPassphraseSet() {
if (mNoPassphrase.isChecked()) {
return true;
} else if ((mIsPassphraseSet)
|| (mNewPassphrase != null && !mNewPassphrase.equals(""))) {
return true;
} else {
return false;
}
}
public boolean hasPassphraseChanged() {
if (mNoPassphrase != null) {
if (mNoPassphrase.isChecked()) {
return mIsPassphraseSet;
} else {
return (mNewPassphrase != null && !mNewPassphrase.equals(""));
}
} else {
return false;
}
}
private void saveClicked() {
final long masterKeyId = getMasterKeyId();
if (needsSaving()) { //make sure, as some versions don't support invalidateOptionsMenu
try {
if (!isPassphraseSet()) {
throw new PgpGeneralException(this.getString(R.string.set_a_passphrase));
}
String passphrase;
if (mIsPassphraseSet) {
passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
} else {
passphrase = "";
}
if (passphrase == null) {
PassphraseDialogFragment.show(this, masterKeyId,
new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
EditKeyActivityOld.this, masterKeyId);
checkEmptyIDsWanted();
}
}
});
} else {
mCurrentPassphrase = passphrase;
checkEmptyIDsWanted();
}
} catch (PgpGeneralException e) {
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
AppMsg.STYLE_ALERT).show();
}
} else {
AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show();
}
}
private void checkEmptyIDsWanted() {
try {
ArrayList<String> userIDs = getUserIds(mUserIdsView);
List<Boolean> newIDs = mUserIdsView.getNewIDFlags();
ArrayList<String> originalIDs = mUserIdsView.getOriginalIDs();
int curID = 0;
for (String userID : userIDs) {
if (userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID))) {
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(
EditKeyActivityOld.this);
alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
alert.setTitle(R.string.warning);
alert.setMessage(EditKeyActivityOld.this.getString(R.string.ask_empty_id_ok));
alert.setPositiveButton(EditKeyActivityOld.this.getString(android.R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
finallySaveClicked();
}
}
);
alert.setNegativeButton(this.getString(android.R.string.no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
}
);
alert.setCancelable(false);
alert.show();
return;
}
curID++;
}
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show();
}
finallySaveClicked();
}
private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
final boolean[] primitives = new boolean[booleanList.size()];
int index = 0;
for (Boolean object : booleanList) {
primitives[index++] = object;
}
return primitives;
}
private void finallySaveClicked() {
/*
try {
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(this, KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
OldSaveKeyringParcel saveParams = new OldSaveKeyringParcel();
saveParams.userIds = getUserIds(mUserIdsView);
saveParams.originalIDs = mUserIdsView.getOriginalIDs();
saveParams.deletedIDs = mUserIdsView.getDeletedIDs();
saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags());
saveParams.primaryIDChanged = mUserIdsView.primaryChanged();
saveParams.moddedKeys = toPrimitiveArray(mKeysView.getNeedsSavingArray());
saveParams.deletedKeys = mKeysView.getDeletedKeys();
saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView);
saveParams.keysUsages = getKeysUsages(mKeysView);
saveParams.newPassphrase = mNewPassphrase;
saveParams.oldPassphrase = mCurrentPassphrase;
saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray());
saveParams.keys = getKeys(mKeysView);
saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID();
// fill values for this action
Bundle data = new Bundle();
data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, mMasterCanSign);
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, saveParams);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after saving is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
Intent data = new Intent();
// return uri pointing to new created key
Uri uri = KeyRings.buildGenericKeyRingUri(getMasterKeyId());
data.setData(uri);
setResult(RESULT_OK, data);
finish();
}
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(this);
// start service with intent
startService(intent);
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
AppMsg.STYLE_ALERT).show();
}
*/
}
private void cancelClicked() {
if (needsSaving()) { //ask if we want to save
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(
EditKeyActivityOld.this);
alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
alert.setTitle(R.string.warning);
alert.setMessage(EditKeyActivityOld.this.getString(R.string.ask_save_changed_key));
alert.setPositiveButton(EditKeyActivityOld.this.getString(android.R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
saveClicked();
}
});
alert.setNegativeButton(this.getString(android.R.string.no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
setResult(RESULT_CANCELED);
finish();
}
});
alert.setCancelable(false);
alert.show();
} else {
setResult(RESULT_CANCELED);
finish();
}
}
/**
* Returns user ids from the SectionView
*
* @param userIdsView
* @return
*/
private ArrayList<String> getUserIds(SectionView userIdsView) throws PgpGeneralException {
ArrayList<String> userIds = new ArrayList<String>();
ViewGroup userIdEditors = userIdsView.getEditors();
boolean gotMainUserId = false;
for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
String userId;
userId = editor.getValue();
if (editor.isMainUserId()) {
userIds.add(0, userId);
gotMainUserId = true;
} else {
userIds.add(userId);
}
}
if (userIds.size() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_a_user_id));
}
if (!gotMainUserId) {
throw new PgpGeneralException(getString(R.string.error_main_user_id_must_not_be_empty));
}
return userIds;
}
/**
* Returns keys from the SectionView
*
* @param keysView
* @return
*/
private ArrayList<UncachedSecretKey> getKeys(SectionView keysView) throws PgpGeneralException {
ArrayList<UncachedSecretKey> keys = new ArrayList<UncachedSecretKey>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keys.add(editor.getValue());
}
return keys;
}
/**
* Returns usage selections of keys from the SectionView
*
* @param keysView
* @return
*/
private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PgpGeneralException {
ArrayList<Integer> keysUsages = new ArrayList<Integer>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keysUsages.add(editor.getUsage());
}
return keysUsages;
}
private ArrayList<Calendar> getKeysExpiryDates(SectionView keysView) throws PgpGeneralException {
ArrayList<Calendar> keysExpiryDates = new ArrayList<Calendar>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keysExpiryDates.add(editor.getExpiryDate());
}
return keysExpiryDates;
}
private void updatePassphraseButtonText() {
mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
: getString(R.string.btn_set_passphrase));
}
}

View File

@ -37,6 +37,7 @@ import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
@ -50,38 +51,48 @@ import org.sufficientlysecure.keychain.service.OperationResults;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsArrayAdapter;
import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter;
import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
public class EditKeyFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_DATA_URI = "uri";
private ListView mUserIdsList;
private ListView mKeysList;
private ListView mSubkeysList;
private ListView mUserIdsAddedList;
private ListView mKeysAddedList;
private ListView mSubkeysAddedList;
private View mChangePassphrase;
private View mAddUserId;
private View mAddKey;
private View mAddSubkey;
private static final int LOADER_ID_USER_IDS = 0;
private static final int LOADER_ID_KEYS = 1;
private static final int LOADER_ID_SUBKEYS = 1;
// cursor adapter
private UserIdsAdapter mUserIdsAdapter;
private SubkeysAdapter mKeysAdapter;
private UserIdsArrayAdapter mUserIdsAddedAdapter;
private SubkeysAdapter mSubkeysAdapter;
// array adapter
private UserIdsAddedAdapter mUserIdsAddedAdapter;
private SubkeysAddedAdapter mSubkeysAddedAdapter;
private ArrayList<UserIdsAddedAdapter.UserIdModel> mUserIdsAddedData;
private Uri mDataUri;
private SaveKeyringParcel mSaveKeyringParcel;
private String mCurrentPassphrase;
/**
* Creates new instance of this fragment
*/
@ -102,12 +113,12 @@ public class EditKeyFragment extends LoaderFragment implements
View view = inflater.inflate(R.layout.edit_key_fragment, getContainer());
mUserIdsList = (ListView) view.findViewById(R.id.edit_key_user_ids);
mKeysList = (ListView) view.findViewById(R.id.edit_key_keys);
mSubkeysList = (ListView) view.findViewById(R.id.edit_key_keys);
mUserIdsAddedList = (ListView) view.findViewById(R.id.edit_key_user_ids_added);
mKeysAddedList = (ListView) view.findViewById(R.id.edit_key_keys_added);
mSubkeysAddedList = (ListView) view.findViewById(R.id.edit_key_subkeys_added);
mChangePassphrase = view.findViewById(R.id.edit_key_action_change_passphrase);
mAddUserId = view.findViewById(R.id.edit_key_action_add_user_id);
mAddKey = view.findViewById(R.id.edit_key_action_add_key);
mAddSubkey = view.findViewById(R.id.edit_key_action_add_key);
return root;
}
@ -123,7 +134,7 @@ public class EditKeyFragment extends LoaderFragment implements
@Override
public void onClick(View v) {
// Save
save();
save(mCurrentPassphrase);
}
}, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
new OnClickListener() {
@ -164,6 +175,8 @@ public class EditKeyFragment extends LoaderFragment implements
getActivity().finish();
}
cachePassphraseForEdit();
mChangePassphrase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -178,6 +191,13 @@ public class EditKeyFragment extends LoaderFragment implements
}
});
mAddSubkey.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
addSubkey();
}
});
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, mSaveKeyringParcel);
mUserIdsList.setAdapter(mUserIdsAdapter);
@ -189,17 +209,21 @@ public class EditKeyFragment extends LoaderFragment implements
}
});
mUserIdsAddedAdapter = new UserIdsArrayAdapter(getActivity());
// TODO: mUserIdsAddedData and SaveParcel from savedInstance?!
mUserIdsAddedData = new ArrayList<UserIdsAddedAdapter.UserIdModel>();
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mUserIdsAddedData);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mUserIdsAddedAdapter.setData(mSaveKeyringParcel.addUserIds);
mKeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
mKeysList.setAdapter(mKeysAdapter);
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
mSubkeysList.setAdapter(mSubkeysAdapter);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.addSubKeys);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
// Prepare the loaders. Either re-connect with an existing ones,
// or start new ones.
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
getLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@ -212,10 +236,10 @@ public class EditKeyFragment extends LoaderFragment implements
UserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
}
case LOADER_ID_KEYS: {
case LOADER_ID_SUBKEYS: {
Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri);
return new CursorLoader(getActivity(), baseUri,
SubkeysAdapter.KEYS_PROJECTION, null, null, null);
SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null);
}
default:
@ -231,8 +255,8 @@ public class EditKeyFragment extends LoaderFragment implements
mUserIdsAdapter.swapCursor(data);
break;
case LOADER_ID_KEYS:
mKeysAdapter.swapCursor(data);
case LOADER_ID_SUBKEYS:
mSubkeysAdapter.swapCursor(data);
break;
}
@ -248,8 +272,8 @@ public class EditKeyFragment extends LoaderFragment implements
case LOADER_ID_USER_IDS:
mUserIdsAdapter.swapCursor(null);
break;
case LOADER_ID_KEYS:
mKeysAdapter.swapCursor(null);
case LOADER_ID_SUBKEYS:
mSubkeysAdapter.swapCursor(null);
break;
}
}
@ -262,11 +286,9 @@ public class EditKeyFragment extends LoaderFragment implements
if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) {
Bundle data = message.getData();
// set new returned passphrase!
String newPassphrase = data
// cache new returned passphrase!
mSaveKeyringParcel.newPassphrase = data
.getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE);
mSaveKeyringParcel.newPassphrase = newPassphrase;
}
}
};
@ -275,7 +297,7 @@ public class EditKeyFragment extends LoaderFragment implements
Messenger messenger = new Messenger(returnHandler);
SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance(
messenger, R.string.title_change_passphrase);
messenger, mCurrentPassphrase, R.string.title_change_passphrase);
setPassphraseDialog.show(getActivity().getSupportFragmentManager(), "setPassphraseDialog");
}
@ -321,56 +343,41 @@ public class EditKeyFragment extends LoaderFragment implements
}
private void addUserId() {
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case AddUserIdDialogFragment.MESSAGE_OKAY:
Bundle data = message.getData();
String userId = data.getString(AddUserIdDialogFragment.MESSAGE_DATA_USER_ID);
if (userId != null) {
mSaveKeyringParcel.addUserIds.add(userId);
mUserIdsAddedAdapter.setData(mSaveKeyringParcel.addUserIds);
}
}
getLoaderManager().getLoader(LOADER_ID_USER_IDS).forceLoad();
}
};
// Create a new Messenger for the communication back
final Messenger messenger = new Messenger(returnHandler);
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
public void run() {
AddUserIdDialogFragment dialogFragment =
AddUserIdDialogFragment.newInstance(messenger);
dialogFragment.show(getActivity().getSupportFragmentManager(), "addUserIdDialog");
}
});
mUserIdsAddedAdapter.add(new UserIdsAddedAdapter.UserIdModel());
}
private void save() {
String passphrase = PassphraseCacheService.getCachedPassphrase(getActivity(),
private void addSubkey() {
// default values
mSubkeysAddedAdapter.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null));
}
private void cachePassphraseForEdit() {
mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(getActivity(),
mSaveKeyringParcel.mMasterKeyId);
if (passphrase == null) {
if (mCurrentPassphrase == null) {
PassphraseDialogFragment.show(getActivity(), mSaveKeyringParcel.mMasterKeyId,
new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
saveFinal();
mCurrentPassphrase =
message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE);
Log.d(Constants.TAG, "after caching passphrase");
} else {
EditKeyFragment.this.getActivity().finish();
}
}
}
);
}
}
}
private void save(String passphrase) {
Log.d(Constants.TAG, "add userids to parcel: " + mUserIdsAddedAdapter.getDataAsStringList());
Log.d(Constants.TAG, "mSaveKeyringParcel.newPassphrase: " + mSaveKeyringParcel.newPassphrase);
mSaveKeyringParcel.addUserIds = mUserIdsAddedAdapter.getDataAsStringList();
private void saveFinal() {
// Message is received after importing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
getActivity(),
@ -381,6 +388,9 @@ public class EditKeyFragment extends LoaderFragment implements
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
getActivity().finish();
// TODO below
// get returned data bundle
Bundle returnData = message.getData();
if (returnData == null) {
@ -408,6 +418,7 @@ public class EditKeyFragment extends LoaderFragment implements
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.SAVE_KEYRING_PASSPHRASE, passphrase);
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, mSaveKeyringParcel);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -298,7 +298,7 @@ public class EncryptActivity extends DrawerActivity implements
// encrypt file based on Uri
mFileFragmentBundle.putParcelableArrayList(EncryptFileFragment.ARG_URIS, uris);
mSwitchToContent = PAGER_CONTENT_FILE;
} else {
} else if (ACTION_ENCRYPT.equals(action)) {
Log.e(Constants.TAG,
"Include the extra 'text' or an Uri with setData() in your Intent!");
}

View File

@ -17,21 +17,33 @@
package org.sufficientlysecure.keychain.ui;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.view.Menu;
import android.view.MenuItem;
import com.devspark.appmsg.AppMsg;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Constants.choice.algorithm;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
import java.util.ArrayList;
public class KeyListActivity extends DrawerActivity {
@ -121,9 +133,42 @@ public class KeyListActivity extends DrawerActivity {
}
private void createKeyExpert() {
Intent intent = new Intent(this, EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
startActivityForResult(intent, 0);
}
Intent intent = new Intent(this, KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
// Message is received after importing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
this,
getString(R.string.progress_importing),
ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
Bundle data = message.getData();
// OtherHelper.logDebugBundle(data, "message reply");
}
};
// fill values for this action
Bundle data = new Bundle();
SaveKeyringParcel parcel = new SaveKeyringParcel();
parcel.addSubKeys.add(new SubkeyAdd(algorithm.rsa, 1024, KeyFlags.CERTIFY_OTHER, null));
parcel.addSubKeys.add(new SubkeyAdd(algorithm.rsa, 1024, KeyFlags.SIGN_DATA, null));
parcel.addUserIds.add("swagerinho");
parcel.newPassphrase = "swag";
// get selected key entries
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(this);
startService(intent);
}
}

View File

@ -47,7 +47,6 @@ import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@ -59,7 +58,6 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.util.Highlighter;
@ -106,10 +104,10 @@ public class KeyListFragment extends LoaderFragment
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, ""); // show user id view
Intent intent = new Intent(getActivity(), EditKeyActivityOld.class);
intent.setAction(EditKeyActivityOld.ACTION_CREATE_KEY);
intent.putExtra(EditKeyActivityOld.EXTRA_GENERATE_DEFAULT_KEYS, true);
intent.putExtra(EditKeyActivityOld.EXTRA_USER_IDS, ""); // show user id view
startActivityForResult(intent, 0);
}
});
@ -205,7 +203,7 @@ public class KeyListFragment extends LoaderFragment
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
if (checked) {
mAdapter.setNewSelection(position, true);
mAdapter.setNewSelection(position, checked);
} else {
mAdapter.removeSelection(position);
}
@ -439,9 +437,7 @@ public class KeyListFragment extends LoaderFragment
private class ItemViewHolder {
TextView mMainUserId;
TextView mMainUserIdRest;
View mStatusDivider;
FrameLayout mStatusLayout;
ImageButton mButton;
TextView mRevoked;
ImageView mVerified;
}
@ -452,9 +448,7 @@ public class KeyListFragment extends LoaderFragment
ItemViewHolder holder = new ItemViewHolder();
holder.mMainUserId = (TextView) view.findViewById(R.id.mainUserId);
holder.mMainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
holder.mStatusDivider = view.findViewById(R.id.status_divider);
holder.mStatusLayout = (FrameLayout) view.findViewById(R.id.status_layout);
holder.mButton = (ImageButton) view.findViewById(R.id.edit);
holder.mRevoked = (TextView) view.findViewById(R.id.revoked);
holder.mVerified = (ImageView) view.findViewById(R.id.verified);
view.setTag(holder);
@ -491,26 +485,12 @@ public class KeyListFragment extends LoaderFragment
{ // set edit button and revoked info, specific by key type
if (cursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {
// this is a secret key - show the edit mButton
h.mStatusDivider.setVisibility(View.VISIBLE);
// this is a secret key
h.mStatusLayout.setVisibility(View.VISIBLE);
h.mRevoked.setVisibility(View.GONE);
h.mVerified.setVisibility(View.GONE);
h.mButton.setVisibility(View.VISIBLE);
final long id = cursor.getLong(INDEX_MASTER_KEY_ID);
h.mButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
editIntent.setData(KeyRingData.buildSecretKeyRingUri(Long.toString(id)));
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
startActivityForResult(editIntent, 0);
}
});
} else {
// this is a public key - hide the edit mButton, show if it's revoked
h.mStatusDivider.setVisibility(View.GONE);
h.mButton.setVisibility(View.GONE);
// this is a public key - show if it's revoked
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = !cursor.isNull(INDEX_EXPIRY)

View File

@ -1,3 +1,20 @@
/*
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.os.Bundle;
@ -9,14 +26,14 @@ import android.view.animation.AnimationUtils;
import org.sufficientlysecure.keychain.R;
/** This is a fragment helper class, which implements a generic
/**
* This is a fragment helper class, which implements a generic
* progressbar/container view.
*
* <p/>
* To use it in a fragment, simply subclass, use onCreateView to create the
* layout's root view, and ues getContainer() as root view of your subclass.
* The layout shows a progress bar by default, and can be switched to the
* actual contents by calling setContentShown().
*
*/
public class LoaderFragment extends Fragment {
private boolean mContentShown;
@ -35,7 +52,6 @@ public class LoaderFragment extends Fragment {
mContentShown = false;
return root;
}
protected ViewGroup getContainer() {

View File

@ -87,7 +87,7 @@ public class ViewKeyKeysFragment extends LoaderFragment implements
setContentShown(false);
Uri baseUri = Keys.buildKeysUri(mDataUri);
return new CursorLoader(getActivity(), baseUri,
SubkeysAdapter.KEYS_PROJECTION, null, null, null);
SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

View File

@ -49,7 +49,6 @@ public class ViewKeyMainFragment extends LoaderFragment implements
public static final String ARG_DATA_URI = "uri";
private View mActionEdit;
private View mActionEditNew;
private View mActionEditDivider;
private View mActionEncrypt;
private View mActionCertify;
@ -74,7 +73,6 @@ public class ViewKeyMainFragment extends LoaderFragment implements
mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids);
mActionEdit = view.findViewById(R.id.view_key_action_edit);
mActionEditNew = view.findViewById(R.id.view_key_action_edit_new);
mActionEditDivider = view.findViewById(R.id.view_key_action_edit_divider);
mActionEncrypt = view.findViewById(R.id.view_key_action_encrypt);
mActionCertify = view.findViewById(R.id.view_key_action_certify);
@ -118,11 +116,6 @@ public class ViewKeyMainFragment extends LoaderFragment implements
editKey(mDataUri);
}
});
mActionEditNew.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
editKeyNew(mDataUri);
}
});
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
mUserIds.setAdapter(mUserIdsAdapter);
@ -259,16 +252,9 @@ public class ViewKeyMainFragment extends LoaderFragment implements
private void editKey(Uri dataUri) {
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
startActivityForResult(editIntent, 0);
}
private void editKeyNew(Uri dataUri) {
Intent editIntent = new Intent(getActivity(), EditKeyActivityNew.class);
// editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
startActivityForResult(editIntent, 0);
// editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
// startActivityForResult(editIntent, 0);
startActivity(editIntent);
}
}

View File

@ -142,7 +142,7 @@ public class WizardActivity extends ActionBarActivity {
emailView.setThreshold(1); // Start working from first character
emailView.setAdapter(
new ArrayAdapter<String>
(getActivity(), android.R.layout.simple_dropdown_item_1line,
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserEmails(getActivity())
)
);
@ -177,7 +177,7 @@ public class WizardActivity extends ActionBarActivity {
nameView.setThreshold(1); // Start working from first character
nameView.setAdapter(
new ArrayAdapter<String>
(getActivity(), android.R.layout.simple_dropdown_item_1line,
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserNames(getActivity())
)
);

View File

@ -38,22 +38,11 @@ import java.util.Date;
public class SubkeysAdapter extends CursorAdapter {
private LayoutInflater mInflater;
private int mIndexKeyId;
private int mIndexAlgorithm;
private int mIndexKeySize;
private int mIndexRank;
private int mIndexCanCertify;
private int mIndexCanEncrypt;
private int mIndexCanSign;
private int mIndexHasSecret;
private int mIndexRevokedKey;
private int mIndexExpiry;
private boolean hasAnySecret;
private ColorStateList mDefaultTextColor;
public static final String[] KEYS_PROJECTION = new String[] {
public static final String[] SUBKEYS_PROJECTION = new String[]{
Keys._ID,
Keys.KEY_ID,
Keys.RANK,
@ -68,24 +57,32 @@ public class SubkeysAdapter extends CursorAdapter {
Keys.EXPIRY,
Keys.FINGERPRINT
};
private static final int INDEX_ID = 0;
private static final int INDEX_KEY_ID = 1;
private static final int INDEX_RANK = 2;
private static final int INDEX_ALGORITHM = 3;
private static final int INDEX_KEY_SIZE = 4;
private static final int INDEX_HAS_SECRET = 5;
private static final int INDEX_CAN_CERTIFY = 6;
private static final int INDEX_CAN_ENCRYPT = 7;
private static final int INDEX_CAN_SIGN = 8;
private static final int INDEX_IS_REVOKED = 9;
private static final int INDEX_CREATION = 10;
private static final int INDEX_EXPIRY = 11;
private static final int INDEX_FINGERPRINT = 12;
public SubkeysAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mInflater = LayoutInflater.from(context);
initIndex(c);
}
@Override
public Cursor swapCursor(Cursor newCursor) {
initIndex(newCursor);
hasAnySecret = false;
if (newCursor != null) {
newCursor.moveToFirst();
if (newCursor != null && newCursor.moveToFirst()) {
do {
if (newCursor.getInt(mIndexHasSecret) != 0) {
if (newCursor.getInt(INDEX_HAS_SECRET) != 0) {
hasAnySecret = true;
break;
}
@ -95,27 +92,6 @@ public class SubkeysAdapter extends CursorAdapter {
return super.swapCursor(newCursor);
}
/**
* Get column indexes for performance reasons just once in constructor and swapCursor. For a
* performance comparison see http://stackoverflow.com/a/17999582
*
* @param cursor
*/
private void initIndex(Cursor cursor) {
if (cursor != null) {
mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID);
mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM);
mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE);
mIndexRank = cursor.getColumnIndexOrThrow(Keys.RANK);
mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY);
mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);
mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN);
mIndexHasSecret = cursor.getColumnIndexOrThrow(Keys.HAS_SECRET);
mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED);
mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY);
}
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView keyId = (TextView) view.findViewById(R.id.keyId);
@ -127,16 +103,16 @@ public class SubkeysAdapter extends CursorAdapter {
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey);
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(INDEX_KEY_ID));
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
context,
cursor.getInt(mIndexAlgorithm),
cursor.getInt(mIndexKeySize)
cursor.getInt(INDEX_ALGORITHM),
cursor.getInt(INDEX_KEY_SIZE)
);
keyId.setText(keyIdStr);
// may be set with additional "stripped" later on
if (hasAnySecret && cursor.getInt(mIndexHasSecret) == 0) {
if (hasAnySecret && cursor.getInt(INDEX_HAS_SECRET) == 0) {
keyDetails.setText(algorithmStr + ", " +
context.getString(R.string.key_stripped));
} else {
@ -144,13 +120,13 @@ public class SubkeysAdapter extends CursorAdapter {
}
// Set icons according to properties
masterKeyIcon.setVisibility(cursor.getInt(mIndexRank) == 0 ? View.VISIBLE : View.INVISIBLE);
certifyIcon.setVisibility(cursor.getInt(mIndexCanCertify) != 0 ? View.VISIBLE : View.GONE);
encryptIcon.setVisibility(cursor.getInt(mIndexCanEncrypt) != 0 ? View.VISIBLE : View.GONE);
signIcon.setVisibility(cursor.getInt(mIndexCanSign) != 0 ? View.VISIBLE : View.GONE);
masterKeyIcon.setVisibility(cursor.getInt(INDEX_RANK) == 0 ? View.VISIBLE : View.INVISIBLE);
certifyIcon.setVisibility(cursor.getInt(INDEX_CAN_CERTIFY) != 0 ? View.VISIBLE : View.GONE);
encryptIcon.setVisibility(cursor.getInt(INDEX_CAN_ENCRYPT) != 0 ? View.VISIBLE : View.GONE);
signIcon.setVisibility(cursor.getInt(INDEX_CAN_SIGN) != 0 ? View.VISIBLE : View.GONE);
boolean valid = true;
if (cursor.getInt(mIndexRevokedKey) > 0) {
if (cursor.getInt(INDEX_IS_REVOKED) > 0) {
revokedKeyIcon.setVisibility(View.VISIBLE);
valid = false;
@ -162,17 +138,19 @@ public class SubkeysAdapter extends CursorAdapter {
revokedKeyIcon.setVisibility(View.GONE);
}
if (!cursor.isNull(mIndexExpiry)) {
Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000);
if (!cursor.isNull(INDEX_EXPIRY)) {
Date expiryDate = new Date(cursor.getLong(INDEX_EXPIRY) * 1000);
valid = valid && expiryDate.after(new Date());
keyExpiry.setText(
context.getString(R.string.label_expiry) + ": " +
DateFormat.getDateFormat(context).format(expiryDate));
DateFormat.getDateFormat(context).format(expiryDate)
);
} else {
keyExpiry.setText(
context.getString(R.string.label_expiry) + ": " +
context.getString(R.string.none));
context.getString(R.string.none)
);
}
// if key is expired or revoked, strike through text

View File

@ -0,0 +1,361 @@
/*
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.adapter;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ContactHelper;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.dialog.CreateKeyDialogFragment;
import org.sufficientlysecure.keychain.util.Choice;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
public class SubkeysAddedAdapter extends ArrayAdapter<SaveKeyringParcel.SubkeyAdd> {
private LayoutInflater mInflater;
private Activity mActivity;
public interface OnAlgorithmSelectedListener {
public void onAlgorithmSelected(Choice algorithmChoice, int keySize);
}
// hold a private reference to the underlying data List
private List<SaveKeyringParcel.SubkeyAdd> mData;
public SubkeysAddedAdapter(Activity activity, List<SaveKeyringParcel.SubkeyAdd> data) {
super(activity, -1, data);
mActivity = activity;
mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mData = data;
}
static class ViewHolder {
public OnAlgorithmSelectedListener mAlgorithmSelectedListener;
public Spinner mAlgorithmSpinner;
public Spinner mKeySizeSpinner;
public TextView mCustomKeyTextView;
public EditText mCustomKeyEditText;
public TextView mCustomKeyInfoTextView;
public ImageButton vDelete;
// also hold a reference to the model item
public SaveKeyringParcel.SubkeyAdd mModel;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// Not recycled, inflate a new view
convertView = mInflater.inflate(R.layout.edit_key_subkey_added_item, null);
final ViewHolder holder = new ViewHolder();
holder.mAlgorithmSpinner = (Spinner) convertView.findViewById(R.id.create_key_algorithm);
holder.mKeySizeSpinner = (Spinner) convertView.findViewById(R.id.create_key_size);
holder.mCustomKeyTextView = (TextView) convertView.findViewById(R.id.custom_key_size_label);
holder.mCustomKeyEditText = (EditText) convertView.findViewById(R.id.custom_key_size_input);
holder.mCustomKeyInfoTextView = (TextView) convertView.findViewById(R.id.custom_key_size_info);
holder.vDelete = (ImageButton) convertView.findViewById(R.id.subkey_added_item_delete);
convertView.setTag(holder);
holder.mAlgorithmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Choice newKeyAlgorithmChoice = (Choice) holder.mAlgorithmSpinner.getSelectedItem();
// update referenced model item
holder.mModel.mAlgorithm = newKeyAlgorithmChoice.getId();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
holder.mKeySizeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Choice newKeyAlgorithmChoice = (Choice) holder.mAlgorithmSpinner.getSelectedItem();
int newKeySize = getProperKeyLength(newKeyAlgorithmChoice.getId(),
getSelectedKeyLength(holder.mKeySizeSpinner, holder.mCustomKeyEditText));
// update referenced model item
holder.mModel.mKeysize = newKeySize;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
holder.vDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// remove reference model item from adapter (data and notify about change)
SubkeysAddedAdapter.this.remove(holder.mModel);
}
});
}
final ViewHolder holder = (ViewHolder) convertView.getTag();
// save reference to model item
holder.mModel = getItem(position);
// TODO
boolean wouldBeMasterKey = false;
// boolean wouldBeMasterKey = (childCount == 0);
ArrayList<Choice> choices = new ArrayList<Choice>();
choices.add(new Choice(Constants.choice.algorithm.dsa, mActivity.getResources().getString(
R.string.dsa)));
if (!wouldBeMasterKey) {
choices.add(new Choice(Constants.choice.algorithm.elgamal, mActivity.getResources().getString(
R.string.elgamal)));
}
choices.add(new Choice(Constants.choice.algorithm.rsa, mActivity.getResources().getString(
R.string.rsa)));
ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(mActivity,
android.R.layout.simple_spinner_item, choices);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.mAlgorithmSpinner.setAdapter(adapter);
// make RSA the default
for (int i = 0; i < choices.size(); ++i) {
if (choices.get(i).getId() == Constants.choice.algorithm.rsa) {
holder.mAlgorithmSpinner.setSelection(i);
break;
}
}
// dynamic ArrayAdapter must be created (instead of ArrayAdapter.getFromResource), because it's content may change
ArrayAdapter<CharSequence> keySizeAdapter = new ArrayAdapter<CharSequence>(mActivity, android.R.layout.simple_spinner_item,
new ArrayList<CharSequence>(Arrays.asList(mActivity.getResources().getStringArray(R.array.rsa_key_size_spinner_values))));
keySizeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.mKeySizeSpinner.setAdapter(keySizeAdapter);
holder.mKeySizeSpinner.setSelection(1); // Default to 4096 for the key length
holder.mCustomKeyEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// setOkButtonAvailability(alertDialog);
}
});
holder.mKeySizeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
setCustomKeyVisibility(holder.mKeySizeSpinner, holder.mCustomKeyEditText,
holder.mCustomKeyTextView, holder.mCustomKeyInfoTextView);
// setOkButtonAvailability(alertDialog);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
holder.mAlgorithmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
setKeyLengthSpinnerValuesForAlgorithm(((Choice) parent.getSelectedItem()).getId(),
holder.mKeySizeSpinner, holder.mCustomKeyInfoTextView);
setCustomKeyVisibility(holder.mKeySizeSpinner, holder.mCustomKeyEditText,
holder.mCustomKeyTextView, holder.mCustomKeyInfoTextView);
// setOkButtonAvailability(alertDialog);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
//
// holder.vAddress.setText(holder.mModel.address);
// holder.vAddress.setThreshold(1); // Start working from first character
// holder.vAddress.setAdapter(mAutoCompleteEmailAdapter);
//
// holder.vName.setText(holder.mModel.name);
// holder.vName.setThreshold(1); // Start working from first character
// holder.vName.setAdapter(mAutoCompleteNameAdapter);
//
// holder.vComment.setText(holder.mModel.comment);
return convertView;
}
private int getSelectedKeyLength(Spinner keySizeSpinner, EditText customKeyEditText) {
final String selectedItemString = (String) keySizeSpinner.getSelectedItem();
final String customLengthString = mActivity.getResources().getString(R.string.key_size_custom);
final boolean customSelected = customLengthString.equals(selectedItemString);
String keyLengthString = customSelected ? customKeyEditText.getText().toString() : selectedItemString;
int keySize;
try {
keySize = Integer.parseInt(keyLengthString);
} catch (NumberFormatException e) {
keySize = 0;
}
return keySize;
}
/**
* <h3>RSA</h3>
* <p>for RSA algorithm, key length must be greater than 1024 (according to
* <a href="https://github.com/open-keychain/open-keychain/issues/102">#102</a>). Possibility to generate keys bigger
* than 8192 bits is currently disabled, because it's almost impossible to generate them on a mobile device (check
* <a href="http://www.javamex.com/tutorials/cryptography/rsa_key_length.shtml">RSA key length plot</a> and
* <a href="http://www.keylength.com/">Cryptographic Key Length Recommendation</a>). Also, key length must be a
* multiplicity of 8.</p>
* <h3>ElGamal</h3>
* <p>For ElGamal algorithm, supported key lengths are 1536, 2048, 3072, 4096 or 8192 bits.</p>
* <h3>DSA</h3>
* <p>For DSA algorithm key length must be between 512 and 1024. Also, it must me dividable by 64.</p>
*
* @return correct key length, according to SpongyCastle specification. Returns <code>-1</code>, if key length is
* inappropriate.
*/
private int getProperKeyLength(int algorithmId, int currentKeyLength) {
final int[] elGamalSupportedLengths = {1536, 2048, 3072, 4096, 8192};
int properKeyLength = -1;
switch (algorithmId) {
case Constants.choice.algorithm.rsa:
if (currentKeyLength > 1024 && currentKeyLength <= 8192) {
properKeyLength = currentKeyLength + ((8 - (currentKeyLength % 8)) % 8);
}
break;
case Constants.choice.algorithm.elgamal:
int[] elGammalKeyDiff = new int[elGamalSupportedLengths.length];
for (int i = 0; i < elGamalSupportedLengths.length; i++) {
elGammalKeyDiff[i] = Math.abs(elGamalSupportedLengths[i] - currentKeyLength);
}
int minimalValue = Integer.MAX_VALUE;
int minimalIndex = -1;
for (int i = 0; i < elGammalKeyDiff.length; i++) {
if (elGammalKeyDiff[i] <= minimalValue) {
minimalValue = elGammalKeyDiff[i];
minimalIndex = i;
}
}
properKeyLength = elGamalSupportedLengths[minimalIndex];
break;
case Constants.choice.algorithm.dsa:
if (currentKeyLength >= 512 && currentKeyLength <= 1024) {
properKeyLength = currentKeyLength + ((64 - (currentKeyLength % 64)) % 64);
}
break;
}
return properKeyLength;
}
// TODO: make this an error message on the field
// private boolean setOkButtonAvailability(AlertDialog alertDialog) {
// final Choice selectedAlgorithm = (Choice) mAlgorithmSpinner.getSelectedItem();
// final int selectedKeySize = getSelectedKeyLength(); //Integer.parseInt((String) mKeySizeSpinner.getSelectedItem());
// final int properKeyLength = getProperKeyLength(selectedAlgorithm.getId(), selectedKeySize);
// alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(properKeyLength > 0);
// }
private void setCustomKeyVisibility(Spinner keySizeSpinner, EditText customkeyedittext, TextView customKeyTextView, TextView customKeyInfoTextView) {
final String selectedItemString = (String) keySizeSpinner.getSelectedItem();
final String customLengthString = mActivity.getResources().getString(R.string.key_size_custom);
final boolean customSelected = customLengthString.equals(selectedItemString);
final int visibility = customSelected ? View.VISIBLE : View.GONE;
customkeyedittext.setVisibility(visibility);
customKeyTextView.setVisibility(visibility);
customKeyInfoTextView.setVisibility(visibility);
// hide keyboard after setting visibility to gone
if (visibility == View.GONE) {
InputMethodManager imm = (InputMethodManager)
mActivity.getSystemService(mActivity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(customkeyedittext.getWindowToken(), 0);
}
}
private void setKeyLengthSpinnerValuesForAlgorithm(int algorithmId, Spinner keySizeSpinner, TextView customKeyInfoTextView) {
final ArrayAdapter<CharSequence> keySizeAdapter = (ArrayAdapter<CharSequence>) keySizeSpinner.getAdapter();
final Object selectedItem = keySizeSpinner.getSelectedItem();
keySizeAdapter.clear();
switch (algorithmId) {
case Constants.choice.algorithm.rsa:
replaceArrayAdapterContent(keySizeAdapter, R.array.rsa_key_size_spinner_values);
customKeyInfoTextView.setText(mActivity.getResources().getString(R.string.key_size_custom_info_rsa));
break;
case Constants.choice.algorithm.elgamal:
replaceArrayAdapterContent(keySizeAdapter, R.array.elgamal_key_size_spinner_values);
customKeyInfoTextView.setText(""); // ElGamal does not support custom key length
break;
case Constants.choice.algorithm.dsa:
replaceArrayAdapterContent(keySizeAdapter, R.array.dsa_key_size_spinner_values);
customKeyInfoTextView.setText(mActivity.getResources().getString(R.string.key_size_custom_info_dsa));
break;
}
keySizeAdapter.notifyDataSetChanged();
// when switching algorithm, try to select same key length as before
for (int i = 0; i < keySizeAdapter.getCount(); i++) {
if (selectedItem.equals(keySizeAdapter.getItem(i))) {
keySizeSpinner.setSelection(i);
break;
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void replaceArrayAdapterContent(ArrayAdapter<CharSequence> arrayAdapter, int stringArrayResourceId) {
final String[] spinnerValuesStringArray = mActivity.getResources().getStringArray(stringArrayResourceId);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
arrayAdapter.addAll(spinnerValuesStringArray);
} else {
for (final String value : spinnerValuesStringArray) {
arrayAdapter.add(value);
}
}
}
}

View File

@ -41,9 +41,6 @@ import java.util.ArrayList;
public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener {
private LayoutInflater mInflater;
private int mIndexUserId, mIndexRank;
private int mVerifiedId, mIsRevoked, mIsPrimary;
private final ArrayList<Boolean> mCheckStates;
private SaveKeyringParcel mSaveKeyringParcel;
@ -56,6 +53,13 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
UserIds.IS_PRIMARY,
UserIds.IS_REVOKED
};
private static final int INDEX_ID = 0;
private static final int INDEX_USER_ID = 1;
private static final int INDEX_RANK = 2;
private static final int INDEX_VERIFIED = 3;
private static final int INDEX_IS_PRIMARY = 4;
private static final int INDEX_IS_REVOKED = 5;
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes,
SaveKeyringParcel saveKeyringParcel) {
@ -64,8 +68,6 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
mCheckStates = showCheckBoxes ? new ArrayList<Boolean>() : null;
mSaveKeyringParcel = saveKeyringParcel;
initIndex(c);
}
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) {
@ -82,7 +84,6 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
@Override
public Cursor swapCursor(Cursor newCursor) {
initIndex(newCursor);
if (mCheckStates != null) {
mCheckStates.clear();
if (newCursor != null) {
@ -91,7 +92,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
// initialize to true (use case knowledge: we usually want to sign all uids)
for (int i = 0; i < count; i++) {
newCursor.moveToPosition(i);
int verified = newCursor.getInt(mVerifiedId);
int verified = newCursor.getInt(INDEX_VERIFIED);
mCheckStates.add(verified != Certs.VERIFIED_SECRET);
}
}
@ -100,31 +101,15 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
return super.swapCursor(newCursor);
}
/**
* Get column indexes for performance reasons just once in constructor and swapCursor. For a
* performance comparison see http://stackoverflow.com/a/17999582
*
* @param cursor
*/
private void initIndex(Cursor cursor) {
if (cursor != null) {
mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID);
mIndexRank = cursor.getColumnIndexOrThrow(UserIds.RANK);
mVerifiedId = cursor.getColumnIndexOrThrow(UserIds.VERIFIED);
mIsRevoked = cursor.getColumnIndexOrThrow(UserIds.IS_REVOKED);
mIsPrimary = cursor.getColumnIndexOrThrow(UserIds.IS_PRIMARY);
}
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView vName = (TextView) view.findViewById(R.id.userId);
TextView vAddress = (TextView) view.findViewById(R.id.address);
TextView vComment = (TextView) view.findViewById(R.id.comment);
ImageView vVerified = (ImageView) view.findViewById(R.id.certified);
ImageView vHasChanges = (ImageView) view.findViewById(R.id.has_changes);
ImageView vEditImage = (ImageView) view.findViewById(R.id.edit_image);
String userId = cursor.getString(mIndexUserId);
String userId = cursor.getString(INDEX_USER_ID);
String[] splitUserId = KeyRing.splitUserId(userId);
if (splitUserId[0] != null) {
vName.setText(splitUserId[0]);
@ -144,31 +129,29 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
vComment.setVisibility(View.GONE);
}
boolean isPrimary = cursor.getInt(mIsPrimary) != 0;
boolean isRevoked = cursor.getInt(mIsRevoked) > 0;
boolean isPrimary = cursor.getInt(INDEX_IS_PRIMARY) != 0;
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
// for edit key
if (mSaveKeyringParcel != null) {
boolean changeUserId = (mSaveKeyringParcel.changePrimaryUserId != null
boolean changeAnyPrimaryUserId = (mSaveKeyringParcel.changePrimaryUserId != null);
boolean changeThisPrimaryUserId = (mSaveKeyringParcel.changePrimaryUserId != null
&& mSaveKeyringParcel.changePrimaryUserId.equals(userId));
boolean revoke = (mSaveKeyringParcel.revokeUserIds.contains(userId));
boolean revokeThisUserId = (mSaveKeyringParcel.revokeUserIds.contains(userId));
if (changeUserId) {
isPrimary = !isPrimary;
if (changeAnyPrimaryUserId) {
// change all user ids, only this one should be primary
isPrimary = changeThisPrimaryUserId;
}
if (revoke) {
if (revokeThisUserId) {
if (!isRevoked) {
isRevoked = true;
}
}
if (changeUserId || revoke) {
vHasChanges.setVisibility(View.VISIBLE);
vEditImage.setVisibility(View.VISIBLE);
} else {
vHasChanges.setVisibility(View.GONE);
}
} else {
vHasChanges.setVisibility(View.GONE);
vEditImage.setVisibility(View.GONE);
}
if (isRevoked) {
@ -178,15 +161,18 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
// disable and strike through text for revoked user ids
vName.setEnabled(false);
vAddress.setEnabled(false);
vComment.setEnabled(false);
vName.setText(OtherHelper.strikeOutText(vName.getText()));
vAddress.setText(OtherHelper.strikeOutText(vAddress.getText()));
vComment.setText(OtherHelper.strikeOutText(vComment.getText()));
} else {
vName.setEnabled(true);
vAddress.setEnabled(true);
vComment.setEnabled(true);
// verified: has been verified
// isPrimary: show small star icon for primary user ids
int verified = cursor.getInt(mVerifiedId);
int verified = cursor.getInt(INDEX_VERIFIED);
switch (verified) {
case Certs.VERIFIED_SECRET:
vVerified.setImageResource(isPrimary
@ -234,7 +220,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
for (int i = 0; i < mCheckStates.size(); i++) {
if (mCheckStates.get(i)) {
mCursor.moveToPosition(i);
result.add(mCursor.getString(mIndexUserId));
result.add(mCursor.getString(INDEX_USER_ID));
}
}
return result;
@ -242,7 +228,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
public String getUserId(int position) {
mCursor.moveToPosition(position);
return mCursor.getString(mIndexUserId);
return mCursor.getString(INDEX_USER_ID);
}
@Override

View File

@ -0,0 +1,206 @@
/*
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.adapter;
import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ContactHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
public class UserIdsAddedAdapter extends ArrayAdapter<UserIdsAddedAdapter.UserIdModel> {
private LayoutInflater mInflater;
private Activity mActivity;
private ArrayAdapter<String> mAutoCompleteNameAdapter;
private ArrayAdapter<String> mAutoCompleteEmailAdapter;
// hold a private reference to the underlying data List
private List<UserIdModel> mData;
public static class UserIdModel {
String name = "";
String address = "";
String comment = "";
@Override
public String toString() {
String userId = name;
if (!TextUtils.isEmpty(comment)) {
userId += " (" + comment + ")";
}
if (!TextUtils.isEmpty(address)) {
userId += " <" + address + ">";
}
return userId;
}
}
public UserIdsAddedAdapter(Activity activity, List<UserIdModel> data) {
super(activity, -1, data);
mActivity = activity;
mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mData = data;
mAutoCompleteNameAdapter = new ArrayAdapter<String>
(mActivity, android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserNames(mActivity)
);
mAutoCompleteEmailAdapter = new ArrayAdapter<String>
(mActivity, android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserEmails(mActivity)
);
}
public ArrayList<String> getDataAsStringList() {
ArrayList<String> out = new ArrayList<String>();
for (UserIdModel id : mData) {
// ignore empty user ids
if (!TextUtils.isEmpty(id.toString())) {
out.add(id.toString());
}
}
return out;
}
static class ViewHolder {
public AutoCompleteTextView vAddress;
public AutoCompleteTextView vName;
public EditText vComment;
public ImageButton vDelete;
// also hold a reference to the model item
public UserIdModel mModel;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// Not recycled, inflate a new view
convertView = mInflater.inflate(R.layout.edit_key_user_id_added_item, null);
final ViewHolder holder = new ViewHolder();
holder.vAddress = (AutoCompleteTextView) convertView.findViewById(R.id.user_id_added_item_address);
holder.vName = (AutoCompleteTextView) convertView.findViewById(R.id.user_id_added_item_name);
holder.vComment = (EditText) convertView.findViewById(R.id.user_id_added_item_comment);
holder.vDelete = (ImageButton) convertView.findViewById(R.id.user_id_added_item_delete);
convertView.setTag(holder);
holder.vAddress.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// update referenced item in view holder
holder.mModel.address = s.toString();
// show icon on valid email addresses
if (holder.mModel.address.length() > 0) {
Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(holder.mModel.address);
if (emailMatcher.matches()) {
holder.vAddress.setCompoundDrawablesWithIntrinsicBounds(0, 0,
R.drawable.uid_mail_ok, 0);
} else {
holder.vAddress.setCompoundDrawablesWithIntrinsicBounds(0, 0,
R.drawable.uid_mail_bad, 0);
}
} else {
// remove drawable if email is empty
holder.vAddress.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
}
});
holder.vName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// update referenced item in view holder
holder.mModel.name = s.toString();
}
});
holder.vComment.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// update referenced item in view holder
holder.mModel.comment = s.toString();
}
});
holder.vDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// remove reference model item from adapter (data and notify about change)
UserIdsAddedAdapter.this.remove(holder.mModel);
}
});
}
final ViewHolder holder = (ViewHolder) convertView.getTag();
// save reference to model item
holder.mModel = getItem(position);
holder.vAddress.setText(holder.mModel.address);
holder.vAddress.setThreshold(1); // Start working from first character
holder.vAddress.setAdapter(mAutoCompleteEmailAdapter);
holder.vName.setText(holder.mModel.name);
holder.vName.setThreshold(1); // Start working from first character
holder.vName.setAdapter(mAutoCompleteNameAdapter);
holder.vComment.setText(holder.mModel.comment);
return convertView;
}
}

View File

@ -1,131 +0,0 @@
/*
* Copyright (C) 2013-2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.adapter;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import java.util.List;
public class UserIdsArrayAdapter extends ArrayAdapter<String> {
protected LayoutInflater mInflater;
protected Activity mActivity;
protected List<String> mData;
static class ViewHolder {
public TextView vName;
public TextView vAddress;
public TextView vComment;
public ImageView vVerified;
public ImageView vHasChanges;
public CheckBox vCheckBox;
}
public UserIdsArrayAdapter(Activity activity) {
super(activity, -1);
mActivity = activity;
mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setData(List<String> data) {
clear();
if (data != null) {
this.mData = data;
// add data to extended ArrayAdapter
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
addAll(data);
} else {
for (String entry : data) {
add(entry);
}
}
}
}
public List<String> getData() {
return mData;
}
@Override
public boolean hasStableIds() {
return true;
}
public View getView(int position, View convertView, ViewGroup parent) {
String entry = mData.get(position);
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.view_key_userids_item, null);
holder.vName = (TextView) convertView.findViewById(R.id.userId);
holder.vAddress = (TextView) convertView.findViewById(R.id.address);
holder.vComment = (TextView) convertView.findViewById(R.id.comment);
holder.vVerified = (ImageView) convertView.findViewById(R.id.certified);
holder.vHasChanges = (ImageView) convertView.findViewById(R.id.has_changes);
holder.vCheckBox = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// user id
String[] splitUserId = KeyRing.splitUserId(entry);
if (splitUserId[0] != null) {
holder.vName.setText(splitUserId[0]);
} else {
holder.vName.setText(R.string.user_id_no_name);
}
if (splitUserId[1] != null) {
holder.vAddress.setText(splitUserId[1]);
holder.vAddress.setVisibility(View.VISIBLE);
} else {
holder.vAddress.setVisibility(View.GONE);
}
if (splitUserId[2] != null) {
holder.vComment.setText(splitUserId[2]);
holder.vComment.setVisibility(View.VISIBLE);
} else {
holder.vComment.setVisibility(View.GONE);
}
holder.vCheckBox.setVisibility(View.GONE);
holder.vVerified.setImageResource(R.drawable.key_certify_ok_depth0);
// all items are "new"
holder.vHasChanges.setVisibility(View.VISIBLE);
return convertView;
}
}

View File

@ -1,165 +0,0 @@
/*
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.dialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
public class AddUserIdDialogFragment extends DialogFragment implements EditText.OnEditorActionListener {
private static final String ARG_MESSENGER = "messenger";
public static final int MESSAGE_OKAY = 1;
public static final String MESSAGE_DATA_USER_ID = "user_id";
private Messenger mMessenger;
EditText mName;
EditText mAddress;
EditText mComment;
/**
* Creates new instance of this dialog fragment
*/
public static AddUserIdDialogFragment newInstance(Messenger messenger) {
AddUserIdDialogFragment frag = new AddUserIdDialogFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_MESSENGER, messenger);
frag.setArguments(args);
return frag;
}
/**
* Creates dialog
*/
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.add_user_id_dialog, null);
alert.setView(view);
alert.setTitle("Add Identity");
mName = (EditText) view.findViewById(R.id.name);
mAddress = (EditText) view.findViewById(R.id.address);
mComment = (EditText) view.findViewById(R.id.comment);
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
done();
}
});
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
return alert.show();
}
@Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
// Show soft keyboard automatically
mName.requestFocus();
getDialog().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
mComment.setOnEditorActionListener(this);
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (EditorInfo.IME_ACTION_DONE == actionId) {
done();
return true;
}
return false;
}
private void done() {
String name = mName.getText().toString();
String email = mAddress.getText().toString();
String comment = mComment.getText().toString();
String userId = null;
if (!TextUtils.isEmpty(name)) {
userId = name;
if (!TextUtils.isEmpty(comment)) {
userId += " (" + comment + ")";
}
if (!TextUtils.isEmpty(email)) {
userId += " <" + email + ">";
}
}
Bundle data = new Bundle();
data.putString(MESSAGE_DATA_USER_ID, userId);
sendMessageToHandler(MESSAGE_OKAY, data);
this.dismiss();
}
/**
* Send message back to handler which is initialized in a activity
*
* @param what Message integer you want to send
*/
private void sendMessageToHandler(Integer what, Bundle data) {
Message msg = Message.obtain();
msg.what = what;
if (data != null) {
msg.setData(data);
}
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
} catch (NullPointerException e) {
Log.w(Constants.TAG, "Messenger is null!", e);
}
}
}

View File

@ -51,8 +51,6 @@ public class CreateKeyDialogFragment extends DialogFragment {
private static final String ARG_EDITOR_CHILD_COUNT = "child_count";
private int mNewKeySize;
private Choice mNewKeyAlgorithmChoice;
private OnAlgorithmSelectedListener mAlgorithmSelectedListener;
private Spinner mAlgorithmSpinner;
private Spinner mKeySizeSpinner;
@ -131,9 +129,9 @@ public class CreateKeyDialogFragment extends DialogFragment {
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di, int id) {
di.dismiss();
mNewKeyAlgorithmChoice = (Choice) mAlgorithmSpinner.getSelectedItem();
mNewKeySize = getProperKeyLength(mNewKeyAlgorithmChoice.getId(), getSelectedKeyLength());
mAlgorithmSelectedListener.onAlgorithmSelected(mNewKeyAlgorithmChoice, mNewKeySize);
Choice newKeyAlgorithmChoice = (Choice) mAlgorithmSpinner.getSelectedItem();
int newKeySize = getProperKeyLength(newKeyAlgorithmChoice.getId(), getSelectedKeyLength());
mAlgorithmSelectedListener.onAlgorithmSelected(newKeyAlgorithmChoice, newKeySize);
}
}
);

View File

@ -26,6 +26,7 @@ import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
public class EditUserIdDialogFragment extends DialogFragment {
@ -57,9 +58,9 @@ public class EditUserIdDialogFragment extends DialogFragment {
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity());
CharSequence[] array = {"change to primary user id", "revoke"};
CharSequence[] array = getResources().getStringArray(R.array.edit_key_edit_user_id);
builder.setTitle("select action!");
builder.setTitle(R.string.edit_key_edit_user_id_title);
builder.setItems(array, new DialogInterface.OnClickListener() {
@Override
@ -76,7 +77,7 @@ public class EditUserIdDialogFragment extends DialogFragment {
}
}
});
builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();

View File

@ -26,12 +26,15 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.EditorInfo;
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;
@ -44,6 +47,7 @@ import org.sufficientlysecure.keychain.util.Log;
public class SetPassphraseDialogFragment extends DialogFragment implements OnEditorActionListener {
private static final String ARG_MESSENGER = "messenger";
private static final String ARG_TITLE = "title";
private static final String ARG_OLD_PASSPHRASE = "old_passphrase";
public static final int MESSAGE_OKAY = 1;
@ -52,6 +56,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
private Messenger mMessenger;
private EditText mPassphraseEditText;
private EditText mPassphraseAgainEditText;
private CheckBox mNoPassphraseCheckBox;
/**
* Creates new instance of this dialog fragment
@ -60,11 +65,12 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
* @param messenger to communicate back after setting the passphrase
* @return
*/
public static SetPassphraseDialogFragment newInstance(Messenger messenger, int title) {
public static SetPassphraseDialogFragment newInstance(Messenger messenger, String oldPassphrase, int title) {
SetPassphraseDialogFragment frag = new SetPassphraseDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_TITLE, title);
args.putParcelable(ARG_MESSENGER, messenger);
args.putString(ARG_OLD_PASSPHRASE, oldPassphrase);
frag.setArguments(args);
@ -80,6 +86,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
int title = getArguments().getInt(ARG_TITLE);
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
String oldPassphrase = getArguments().getString(ARG_OLD_PASSPHRASE);
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
@ -92,6 +99,21 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
mPassphraseAgainEditText = (EditText) view.findViewById(R.id.passphrase_passphrase_again);
mNoPassphraseCheckBox = (CheckBox) view.findViewById(R.id.passphrase_no_passphrase);
if (TextUtils.isEmpty(oldPassphrase)) {
mNoPassphraseCheckBox.setChecked(true);
mPassphraseEditText.setEnabled(false);
mPassphraseAgainEditText.setEnabled(false);
}
mNoPassphraseCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPassphraseEditText.setEnabled(!isChecked);
mPassphraseAgainEditText.setEnabled(!isChecked);
}
});
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@ -99,13 +121,18 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
public void onClick(DialogInterface dialog, int id) {
dismiss();
String passphrase1 = mPassphraseEditText.getText().toString();
String passphrase1;
if (mNoPassphraseCheckBox.isChecked()) {
passphrase1 = "";
} else {
passphrase1 = mPassphraseEditText.getText().toString();
String passphrase2 = mPassphraseAgainEditText.getText().toString();
if (!passphrase1.equals(passphrase2)) {
Toast.makeText(
activity,
getString(R.string.error_message,
getString(R.string.passphrases_do_not_match)), Toast.LENGTH_SHORT)
getString(R.string.passphrases_do_not_match)), Toast.LENGTH_SHORT
)
.show();
return;
}
@ -115,9 +142,11 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
activity,
getString(R.string.error_message,
getString(R.string.passphrase_must_not_be_empty)),
Toast.LENGTH_SHORT).show();
Toast.LENGTH_SHORT
).show();
return;
}
}
// return resulting data back to activity
Bundle data = new Bundle();

View File

@ -25,9 +25,7 @@ import android.widget.ListView;
* Automatically calculate height of ListView based on contained items. This enables to put this
* ListView into a ScrollView without messing up.
* <p/>
* from
* http://stackoverflow.com/questions/2419246/how-do-i-create-a-listview-thats-not-in-a-scrollview-
* or-has-the-scrollview-dis
* from http://stackoverflow.com/a/3580117
*/
public class FixedListView extends ListView {

View File

@ -388,7 +388,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getData();
Bundle data = message.getDataAsStringList();
UncachedSecretKey newKey = PgpConversionHelper
.BytesToPGPSecretKey(data
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));

View File

@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:stretchColumns="1">
<TableRow android:layout_marginBottom="5dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="Name" />
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:padding="4dp" />
</TableRow>
<TableRow android:layout_marginBottom="10dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="Email" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:padding="4dp" />
</TableRow>
<TableRow android:layout_marginBottom="10dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="Comment" />
<EditText
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:padding="4dp" />
</TableRow>
</TableLayout>

View File

@ -18,8 +18,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="@color/emphasis"
android:textColor="#fff" />
android:textColor="@color/emphasis" />
</android.support.v4.view.ViewPager>
</LinearLayout>

View File

@ -14,7 +14,7 @@
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:text="Passphrase"
android:text="@string/label_passphrase"
android:layout_weight="1" />
<TextView
@ -24,7 +24,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="change passphrase"
android:text="@string/edit_key_action_change_passphrase"
android:minHeight="?android:attr/listPreferredItemHeight"
android:drawableRight="@drawable/ic_action_edit"
android:drawablePadding="8dp"
@ -67,7 +67,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="add identity"
android:text="@string/edit_key_action_add_identity"
android:minHeight="?android:attr/listPreferredItemHeight"
android:drawableRight="@drawable/ic_action_add_person"
android:drawablePadding="8dp"
@ -93,7 +93,7 @@
android:background="?android:attr/listDivider" />
<org.sufficientlysecure.keychain.ui.widget.FixedListView
android:id="@+id/edit_key_keys_added"
android:id="@+id/edit_key_subkeys_added"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@ -109,9 +109,9 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="add key"
android:text="@string/edit_key_action_add_subkey"
android:minHeight="?android:attr/listPreferredItemHeight"
android:drawableRight="@drawable/ic_action_add_person"
android:drawableRight="@drawable/ic_action_new_account"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:clickable="true"

View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="10dp"
android:background="@color/result_green" />
<TableLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="8dp"
android:stretchColumns="1">
<TableRow>
<TextView
android:id="@+id/label_expiry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
android:text="@string/label_expiry" />
<Button
android:id="@+id/expiry"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="@string/none"
android:background="@drawable/button_edgy" />
</TableRow>
<TableRow
android:id="@+id/row_certify">
<TextView
android:id="@+id/label_usage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
android:text="@string/label_usage" />
<CheckBox
android:id="@+id/chkCertify"
android:enabled = "false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/flag_certify" />
</TableRow>
<TableRow
android:id="@+id/row_sign">
<TextView
android:id="@+id/label_usage2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
android:text="@string/label_usage" />
<CheckBox
android:id="@+id/chkSign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/flag_sign" />
</TableRow>
<TableRow
android:id="@+id/row_encrypt">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip" />
<CheckBox
android:id="@+id/chkEncrypt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/flag_encrypt" />
</TableRow>
<TableRow
android:id="@+id/row_authenticate">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip" />
<CheckBox
android:id="@+id/chkAuthenticate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/flag_authenticate" />
</TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/key_creation_el_gamal_info" />
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/label_algorithm" />
<Spinner
android:id="@+id/create_key_algorithm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/label_key_size" />
<Spinner
android:id="@+id/create_key_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:padding="4dp" />
</TableRow>
<TextView
android:id="@+id/custom_key_size_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/key_size_custom_info"
android:visibility="gone" />
<EditText
android:id="@+id/custom_key_size_input"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number"
android:visibility="gone" />
<TextView
android:id="@+id/custom_key_size_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:visibility="gone" />
</TableLayout>
<ImageButton
android:id="@+id/subkey_added_item_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:src="@drawable/ic_action_cancel"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
</LinearLayout>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:singleLine="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="10dp"
android:background="@color/result_green" />
<LinearLayout
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_width="0dip"
android:layout_marginLeft="8dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<AutoCompleteTextView
android:id="@+id/user_id_added_item_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/label_email"
android:inputType="textEmailAddress"
android:textAppearance="?android:attr/textAppearanceMedium" />
<AutoCompleteTextView
android:id="@+id/user_id_added_item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="@string/label_name"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/user_id_added_item_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/tertiary_text_light"
android:hint="@string/label_comment"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<ImageButton
android:id="@+id/user_id_added_item_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:src="@drawable/ic_action_cancel"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
</LinearLayout>

View File

@ -38,32 +38,11 @@
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<View
android:id="@+id/status_divider"
android:layout_width="1dip"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider" />
<FrameLayout
android:id="@+id/status_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageButton
android:id="@+id/edit"
style="@style/SelectableItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:enabled="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/black"
android:src="@drawable/ic_action_edit"
android:text="@string/edit"
android:padding="12dp" />
<TextView
android:id="@+id/revoked"
android:layout_width="wrap_content"

View File

@ -6,9 +6,13 @@
android:paddingRight="16dp"
android:stretchColumns="1">
<TableRow
android:layout_marginBottom="5dip"
>
<CheckBox
android:id="@+id/passphrase_no_passphrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_no_passphrase" />
<TableRow android:layout_marginBottom="5dip">
<TextView
android:id="@+id/passphrase_label_passphrase"
@ -26,9 +30,7 @@
android:padding="4dp" />
</TableRow>
<TableRow
android:layout_marginBottom="10dip"
>
<TableRow android:layout_marginBottom="10dip">
<TextView
android:id="@+id/passphrase_label_passphrase_again"

View File

@ -74,22 +74,6 @@
android:drawablePadding="8dp"
android:gravity="center_vertical" />
<TextView
android:id="@+id/view_key_action_edit_new"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:clickable="true"
style="@style/SelectableItem"
android:text="NEW EDIT"
android:layout_weight="1"
android:drawableRight="@drawable/ic_action_edit"
android:drawablePadding="8dp"
android:gravity="center_vertical" />
<View
android:id="@+id/view_key_action_edit_divider"
android:layout_width="match_parent"

View File

@ -6,13 +6,6 @@
android:orientation="horizontal"
android:singleLine="true">
<ImageView
android:id="@+id/has_changes"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="10dp"
android:background="@color/emphasis" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
@ -41,6 +34,8 @@
android:layout_gravity="center_vertical"
android:layout_width="0dip"
android:layout_marginLeft="8dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_height="wrap_content"
android:layout_weight="1">
@ -68,4 +63,13 @@
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/edit_image"
android:src="@drawable/ic_action_edit"
android:padding="8dp"
android:layout_gravity="center_horizontal" />
</LinearLayout>

View File

@ -40,7 +40,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
<li>viel mehr interne Arbeit an der API</li>
<li>zertifizieren von Benutzer IDs</li>
<li>Schlüsselserver Anfragen basieren auf Maschinenlesbaren Ausgaben.</li>
<li>lock navigation drawer on tablets</li>
<li>fixiere Navigationsmenu in Tabletcomputers</li>
<li>suggestions for emails on creation of keys</li>
<li>suchen in öffentlichen Schlüssellisten</li>
<li>und viele weitere Verbesserungen und Fehlerbehebungen...</li>
@ -63,7 +63,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
</ul>
<h2>2.2</h2>
<ul>
<li>new design with navigation drawer</li>
<li>neues Design mit Naivgationsmenu</li>
<li>Neus Design für die Liste der öffentlichen Schlüssel</li>
<li>Neue Ansicht für öffentliche Schlüssel</li>
<li>Fehler beim Schlüsselimport behoben</li>

View File

@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Los gehts</h2>
<p>Zuerst benötigen Sie einen geheimen privaten Schlüssel. Erstellen Sie einen Schlüssel über den Eintrag &quot;Schlüssel&quot; im Menu oder importieren Sie bestehende private Schlüssel. Anschließend können Sie die Schlüssel ihrer Freunde runterladen oder Sie über QR-Codes oder NFC austauschen.</p>
<p>Zuerst benötigen Sie einen privaten Schlüssel. Erstellen Sie einen Schlüssel über den Eintrag "Schlüssel" im Menu oder importieren Sie bestehende private Schlüssel. Anschließend können Sie die Schlüssel ihrer Freunde runterladen oder Sie über QR-Codes oder NFC austauschen.</p>
<p>Es wird empfohlen, dass Sie den <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> für ein verbessertes Dateihandling installieren, sowie den <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> installieren um erstellte QR-Codes zu scannen. Die Links führen entweder zu Google Play oder zu F-Droid zur Installation.</p>

View File

@ -0,0 +1,50 @@
<html>
<head></head>
<body>
<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
<p><a href="http://www.openkeychain.org">OpenKeychain</a> is an OpenPGP implementation for Android.</p>
<p>License: GPLv3+</p>
<h2>Developers OpenKeychain</h2>
<ul>
<li>Dominik Schürmann (Lead developer)</li>
<li>Ash Hughes (crypto patches)</li>
<li>Brian C. Barnes</li>
<li>Bahtiar 'kalkin' Gadimov (UI)</li>
<li>Daniel Hammann</li>
<li>Daniel Haß</li>
<li>Greg Witczak</li>
<li>Miroojin Bakshi</li>
<li>Nikhil Peter Raj</li>
<li>Paul Sarbinowski</li>
<li>Sreeram Boyapati</li>
<li>Vincent Breitmoser</li>
<li>Tim Bray</li>
</ul>
<h2>Developers APG 1.x</h2>
<ul>
<li>Thialfihar (Lead developer)</li>
<li>'Senecaso' (QRCode, sign key, upload key)</li>
<li>Markus Doits</li>
</ul>
<h2>Libraries</h2>
<ul>
<li>
<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
<li>
<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache License v2)</li>
<li>
<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache License v2)</li>
<li>
<a href="https://github.com/Bearded-Hen/Android-Bootstrap">Android-Bootstrap</a> (MIT License)</li>
<li>
<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache License v2)</li>
<li>
<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
<li>
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
<li>
<a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li>
</ul>
</body>
</html>

View File

@ -0,0 +1,156 @@
<html>
<head></head>
<body>
<h2>2.7</h2>
<ul>
<li>Purple! (Dominik, Vincent)</li>
<li>New key view design (Dominik, Vincent)</li>
<li>New flat Android buttons (Dominik, Vincent)</li>
<li>API fixes (Dominik)</li>
<li>Keybase.io import (Tim Bray)</li>
</ul>
<h2>2.6.1</h2>
<ul>
<li>some fixes for regression bugs</li>
</ul>
<h2>2.6</h2>
<ul>
<li>key certifications (thanks to Vincent Breitmoser)</li>
<li>support for GnuPG partial secret keys (thanks to Vincent Breitmoser)</li>
<li>new design for signature verification</li>
<li>custom key length (thanks to Greg Witczak)</li>
<li>fix share-functionality from other apps</li>
</ul>
<h2>2.5</h2>
<ul>
<li>fix decryption of symmetric pgp messages/files</li>
<li>refactored edit key screen (thanks to Ash Hughes)</li>
<li>new modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
</ul>
<h2>2.4</h2>
<p>Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free!
Besides several small patches, a notable number of patches are made by the following people (in alphabetical order):
Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
<ul>
<li>new unified key list</li>
<li>colorized key fingerprint</li>
<li>support for keyserver ports</li>
<li>deactivate possibility to generate weak keys</li>
<li>much more internal work on the API</li>
<li>certify user ids</li>
<li>keyserver query based on machine-readable output</li>
<li>lock navigation drawer on tablets</li>
<li>suggestions for emails on creation of keys</li>
<li>search in public key lists</li>
<li>and much more improvements and fixes…</li>
</ul>
<h2>2.3.1</h2>
<ul>
<li>hotfix for crash when upgrading from old versions</li>
</ul>
<h2>2.3</h2>
<ul>
<li>remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
<li>fix setting expiry dates on keys (thanks to Ash Hughes)</li>
<li>more internal fixes when editing keys (thanks to Ash Hughes)</li>
<li>querying keyservers directly from the import screen</li>
<li>fix layout and dialog style on Android 2.2-3.0</li>
<li>fix crash on keys with empty user ids</li>
<li>fix crash and empty lists when coming back from signing screen</li>
<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
<li>fix upload of key from signing screen</li>
</ul>
<h2>2.2</h2>
<ul>
<li>new design with navigation drawer</li>
<li>new public key list design</li>
<li>new public key view</li>
<li>bug fixes for importing of keys</li>
<li>key cross-certification (thanks to Ash Hughes)</li>
<li>handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
<li>first version with new languages (thanks to the contributors on Transifex)</li>
<li>sharing of keys via QR Codes fixed and improved</li>
<li>package signature verification for API</li>
</ul>
<h2>2.1.1</h2>
<ul>
<li>API Updates, preparation for K-9 Mail integration</li>
</ul>
<h2>2.1</h2>
<ul>
<li>lots of bug fixes</li>
<li>new API for developers</li>
<li>PRNG bug fix by Google</li>
</ul>
<h2>2.0</h2>
<ul>
<li>complete redesign</li>
<li>share public keys via qr codes, nfc beam</li>
<li>sign keys</li>
<li>upload keys to server</li>
<li>fixes import issues</li>
<li>new AIDL API</li>
</ul>
<h2>1.0.8</h2>
<ul>
<li>basic keyserver support</li>
<li>app2sd</li>
<li>more choices for pass phrase cache: 1, 2, 4, 8, hours</li>
<li>translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
<li>bugfixes</li>
<li>optimizations</li>
</ul>
<h2>1.0.7</h2>
<ul>
<li>fixed problem with signature verification of texts with trailing newline</li>
<li>more options for pass phrase cache time to live (20, 40, 60 mins)</li>
</ul>
<h2>1.0.6</h2>
<ul>
<li>account adding crash on Froyo fixed</li>
<li>secure file deletion</li>
<li>option to delete key file after import</li>
<li>stream encryption/decryption (gallery, etc.)</li>
<li>new options (language, force v3 signatures)</li>
<li>interface changes</li>
<li>bugfixes</li>
</ul>
<h2>1.0.5</h2>
<ul>
<li>German and Italian translation</li>
<li>much smaller package, due to reduced BC sources</li>
<li>new preferences GUI</li>
<li>layout adjustment for localization</li>
<li>signature bugfix</li>
</ul>
<h2>1.0.4</h2>
<ul>
<li>fixed another crash caused by some SDK bug with query builder</li>
</ul>
<h2>1.0.3</h2>
<ul>
<li>fixed crashes during encryption/signing and possibly key export</li>
</ul>
<h2>1.0.2</h2>
<ul>
<li>filterable key lists</li>
<li>smarter pre-selection of encryption keys</li>
<li>new Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
<li>fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
</ul>
<h2>1.0.1</h2>
<ul>
<li>GMail account listing was broken in 1.0.0, fixed again</li>
</ul>
<h2>1.0.0</h2>
<ul>
<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
<li>support of more file managers (including ASTRO)</li>
<li>Slovenian translation</li>
<li>new database, much faster, less memory usage</li>
<li>defined Intents and content provider for other apps</li>
<li>bugfixes</li>
</ul>
</body>
</html>

View File

@ -0,0 +1,12 @@
<html>
<head></head>
<body>
<h2>How to receive keys</h2>
<ol>
<li>Go to your partners contacts and open the contact you want to share.</li>
<li>Hold the two devices back to back (they have to be almost touching) and youll feel a vibration.</li>
<li>After it vibrates youll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
<li>Tap the card and the content will then load on the your device.</li>
</ol>
</body>
</html>

View File

@ -0,0 +1,22 @@
<html>
<head></head>
<body>
<h2>Getting started</h2>
<p>First you need a personal secret key. Create one via the option menus in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
<p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
<h2>Applications</h2>
<p>Several applications support OpenKeychain to encrypt/sign your private communication:<br><img src="apps_k9"><br>K-9 Mail: OpenKeychain support available in current <a href="https://github.com/k9mail/k-9/releases/tag/4.904">alpha build</a>!<br><a href="market://details?id=eu.siacs.conversations"><img src="apps_conversations"><br>Conversations</a>: Jabber/XMPP client<br><a href="market://details?id=org.lf_net.pgpunlocker"><img src="apps_pgpauth"><br>PGPAuth</a>: App to send a PGP-signed request to a server to open or close something, e.g. a door</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
<h2>Contribute</h2>
<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
<h2>Translations</h2>
<p>Help translating OpenKeychain! Everybody can participate at <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain on Transifex</a>.</p>
</body>
</html>

View File

@ -0,0 +1,17 @@
<html>
<head></head>
<body>
<h2>Web of Trust</h2>
<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
<h2>Trust Model</h2>
<p>Trust evaluation is based on the simple assumption that all keys which have secret keys available are trusted. Public keys which contain at least one user id certified by a trusted key will be marked with a green dot in the key listings. It is not (yet) possible to specify trust levels for certificates of other known public keys.</p>
<h2>Certifying keys</h2>
<p>Support for key certification is available, and user ids can be certified individually. It is not yet possible to specify the level of trust or create local and other special types of certificates.</p>
</body>
</html>

View File

@ -0,0 +1,11 @@
<html>
<head></head>
<body>
<ol>
<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
<li>Tap the card and the content will then load on the other persons device.</li>
</ol>
</body>
</html>

View File

@ -19,6 +19,7 @@
<!--compression-->
<!--Help-->
<!--Import-->
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<!--Share-->
@ -27,5 +28,10 @@
<!--Navigation Drawer-->
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -1,16 +1,150 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<!--title-->
<string name="title_select_recipients">Vybrat veřejný klíč</string>
<string name="title_select_secret_key">Vybrat veřjný klíč</string>
<string name="title_encrypt">Zašifrovat</string>
<string name="title_decrypt">Rozšifrovat</string>
<string name="title_authentication">Heslo</string>
<string name="title_create_key">Vytvořit klíč</string>
<string name="title_edit_key">Editovat klíč</string>
<string name="title_preferences">Možnosti</string>
<string name="title_api_registered_apps">Appky</string>
<string name="title_key_server_preference">Nastavení keyservrů</string>
<string name="title_set_passphrase">Nastavit heslo</string>
<string name="title_encrypt_to_file">Zašifrovat do souboru</string>
<string name="title_decrypt_to_file">Rozšifrovat do souboru</string>
<string name="title_import_keys">Importovat klíče</string>
<string name="title_export_key">Exportovat klíče</string>
<string name="title_export_keys">Exportovat klíče</string>
<string name="title_key_not_found">Klíč nebyl nalezen</string>
<string name="title_send_key">Nahrát na keyserver</string>
<string name="title_help">Nápověda</string>
<!--section-->
<string name="section_user_ids">Identity</string>
<string name="section_keys">Podklíče</string>
<string name="section_general">Obecné</string>
<string name="section_defaults">Výchozí hodnoty</string>
<string name="section_advanced">Pokročilé</string>
<!--button-->
<string name="btn_encrypt_file">Zaširovat a uložit soubor</string>
<string name="btn_save">Uložit</string>
<string name="btn_do_not_save">Zrušit</string>
<string name="btn_delete">Smazat</string>
<string name="btn_no_date">Nic</string>
<string name="btn_okay">OK</string>
<string name="btn_change_passphrase">Změnit nové heslo</string>
<string name="btn_set_passphrase">Nastavit nové heslo</string>
<string name="btn_export_to_server">Nahrát na keyserver</string>
<string name="btn_next">Další</string>
<string name="btn_back">Zpět</string>
<!--menu-->
<string name="menu_preferences">Nastavení</string>
<string name="menu_export_key">Exportovat do souboru</string>
<string name="menu_delete_key">Smazat klíč</string>
<string name="menu_create_key">Vytvořit klíč</string>
<string name="menu_create_key_expert">Vytvořit klíč (pokročilé)</string>
<string name="menu_search">Hledat</string>
<string name="menu_key_server">Keyserver...</string>
<string name="menu_update_key">Obnovit z keyservru</string>
<string name="menu_export_key_to_server">Obnovit na keyserveru</string>
<string name="menu_share">Sdílet...</string>
<string name="menu_share_qr_code">pomocí QR kódu</string>
<string name="menu_share_nfc">pomocí NFC</string>
<string name="menu_beam_preferences">Beam settings</string>
<!--label-->
<string name="label_sign">Podepsat</string>
<string name="label_message">Zpráva</string>
<string name="label_file">Soubor</string>
<string name="label_no_passphrase">Bez hesla</string>
<string name="label_passphrase">Heslo</string>
<string name="label_passphrase_again">Znovu</string>
<string name="label_algorithm">Algoritmus</string>
<string name="label_ascii_armor">ASCII Armor</string>
<string name="label_select_public_keys">Příjemci</string>
<string name="label_delete_after_encryption">Smazat po zašifrování</string>
<string name="label_delete_after_decryption">Smazat po rozšifrování</string>
<string name="label_encryption_algorithm">Šifrovací algoritmus</string>
<string name="label_hash_algorithm">Hashovací algoritmus</string>
<string name="label_asymmetric">veřejným klíčem</string>
<string name="label_symmetric">heslem</string>
<string name="label_passphrase_cache_ttl">Cache hesel</string>
<string name="label_message_compression">Komprimovat zprávu</string>
<string name="label_file_compression">Komprimovat soubor</string>
<string name="label_force_v3_signature">Vynutit staré OpenPGPv3 podpisy</string>
<string name="label_key_id">ID klíče</string>
<string name="label_creation">Vytvořeno</string>
<string name="label_expiry">Expirace</string>
<string name="label_usage">Použití</string>
<string name="label_key_size">Délka klíče</string>
<string name="label_main_user_id">Hlavní identita</string>
<string name="label_name">Jméno</string>
<string name="label_comment">Komentář</string>
<string name="label_email">Email</string>
<string name="label_send_key">Po vytvoření nahrt na vybraný keyserver</string>
<string name="none">&lt;žádný&gt;</string>
<string name="no_key">&lt;žádný klíč&gt;</string>
<string name="can_encrypt">slouží k šifrovní</string>
<string name="can_sign">slouží k podpisu</string>
<string name="expired">po epiraci</string>
<string name="secret_key">Tajný klíč:</string>
<!--choice-->
<string name="choice_none">Žádný</string>
<string name="choice_15secs">15 sekund</string>
<string name="choice_1min">1 minuta</string>
<string name="choice_3mins">3 minuty</string>
<string name="choice_5mins">5 minut</string>
<string name="choice_10mins">10 minut</string>
<string name="choice_20mins">20 minut</string>
<string name="choice_40mins">40 minut</string>
<string name="choice_1hour">1 hodina</string>
<string name="choice_2hours">2 hodiny</string>
<string name="choice_4hours">4 hodiny</string>
<string name="choice_8hours">8 hodin</string>
<string name="dsa">DSA</string>
<string name="filemanager_title_open">Otevřít...</string>
<string name="warning">Varovnání</string>
<string name="error">Chyba</string>
<string name="error_message">Chyba: %s</string>
<!--key flags-->
<!--sentences-->
<string name="wrong_passphrase">Špatné heslo.</string>
<string name="set_a_passphrase">Nejprve nastavit heslo.</string>
<string name="no_filemanager_installed">Není nainstalován žádný compatibilní správce souborů.</string>
<string name="passphrases_do_not_match">Hesla se neshodují.</string>
<string name="passphrase_must_not_be_empty">Prosím zadejte heslo.</string>
<string name="passphrase_for_symmetric_encryption">Symetrická šifra.</string>
<string name="passphrase_for">Zadejte heslo pro \'%s\'</string>
<string name="file_delete_confirmation">Určitě smazat\n%s?</string>
<string name="file_delete_successful">Úspěšně smazáno.</string>
<string name="no_file_selected">Nejprve vyberte soubor.</string>
<string name="enter_passphrase_twice">Heslo zadejte dvakrát.</string>
<string name="select_encryption_key">Vyberte alespoň jeden šifrovací klíč.</string>
<string name="select_encryption_or_signature_key">Vyberte alespoň jeden šifrovací nebo podpisový klíč.</string>
<string name="specify_file_to_encrypt_to">Prosím specifikujte do kterého souboru zašifrovat.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán.</string>
<string name="specify_file_to_decrypt_to">Prosím specifikujte do kterého souboru rozšifrovat.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán.</string>
<string name="specify_file_to_export_to">Prosím specifikujte do kterého souboru exportovat.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán.</string>
<string name="secret_key_deletion_confirmation">Opravdu chcete smazat TAJNÝ klíč \'%s\'?\nToto je nevratná operace!</string>
<string name="key_exported">Úspěšně exportován 1 klíč.</string>
<string name="keys_exported">Úspěšně exportován %d klíč.</string>
<string name="no_keys_exported">Žádný kláč pro export.</string>
<string name="key_creation_el_gamal_info">Žádný: pouze podklíče podporují ElGamal.</string>
<string name="key_not_found">Nemohu najít klíč %08X.</string>
<string name="key_send_success">Úspěšně nahráno na keyserver.</string>
<string name="list_empty">Seznam je prázný!</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
<string name="error_file_delete_failed">mazání \'%s\' selhalo</string>
<string name="error_file_not_found">soubor nenalezen</string>
<string name="error_no_secret_key_found">žádný vhodný tajný klíč nenalezen</string>
<string name="error_external_storage_not_ready">externí úložiště není připraveno</string>
<string name="error_key_size_minimum512bit">délka klíče musí být alespoň 512 bitů</string>
<string name="error_master_key_must_not_be_el_gamal">hlavní klíč nemůže být typu ElGamal</string>
<string name="error_unknown_algorithm_choice">neznámý typ algoritmu</string>
<string name="error_key_needs_a_user_id">potřebuji alespoň jednu identitu</string>
<string name="error_main_user_id_must_not_be_empty">hlavní identita nesmí být prázdná</string>
<string name="error_key_needs_master_key">potřebuji alespoň hlavní klíč</string>
<!--errors without preceeding Error:-->
<!--results shown after decryption/verification-->
<!--progress dialogs, usually ending in '…'-->
@ -19,6 +153,7 @@
<!--compression-->
<!--Help-->
<!--Import-->
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<!--Share-->
@ -27,5 +162,10 @@
<!--Navigation Drawer-->
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -9,7 +9,7 @@
<string name="title_create_key">Schlüssel erstellen</string>
<string name="title_edit_key">Schlüssel bearbeiten</string>
<string name="title_preferences">Einstellungen</string>
<string name="title_api_registered_apps">Registrierte Anwendungen</string>
<string name="title_api_registered_apps">Apps</string>
<string name="title_key_server_preference">Schlüsselserver</string>
<string name="title_change_passphrase">Passphrase ändern</string>
<string name="title_set_passphrase">Passwort setzen</string>
@ -65,21 +65,16 @@
<string name="btn_lookup_key">Schlüssel nachschlagen</string>
<string name="btn_encryption_advanced_settings_show">Erweiterte Einstellungen anzeigen</string>
<string name="btn_encryption_advanced_settings_hide">Erweiterte Einstellungen verbergen</string>
<string name="btn_share_encrypted_signed">Verschlüsselt/signierten Text teilen…</string>
<string name="btn_share_encrypted_signed">Verschlüsselt/signierte Nachricht teilen…</string>
<string name="btn_view_cert_key">Beglaubigungsschlüssel anzeigen</string>
<!--menu-->
<string name="menu_preferences">Einstellungen</string>
<string name="menu_help">Hilfe</string>
<string name="menu_import_from_file">Datei</string>
<string name="menu_import_from_qr_code">QR-Code</string>
<string name="menu_import_from_nfc">NFC</string>
<string name="menu_export_key">In Datei exportieren</string>
<string name="menu_delete_key">Schlüssel löschen</string>
<string name="menu_create_key">Schlüssel erstellen</string>
<string name="menu_create_key_expert">Schlüssel erstellen (Experte)</string>
<string name="menu_search">Suchen</string>
<string name="menu_import_from_key_server">Schlüsselserver</string>
<string name="menu_import_from_keybase">Keybase.io</string>
<string name="menu_key_server">Schlüsselserver…</string>
<string name="menu_update_key">Von einem Schlüsselserver aktualisieren</string>
<string name="menu_export_key_to_server">Auf Schlüsselserver hochladen</string>
@ -98,6 +93,7 @@
<string name="menu_select_all">Alles auswählen</string>
<string name="menu_add_keys">Schlüssel hinzufügen</string>
<string name="menu_export_all_keys">Alle Schlüssel exportieren</string>
<string name="menu_advanced">Erweiterte Info anzeigen</string>
<!--label-->
<string name="label_sign">Signieren</string>
<string name="label_message">Nachricht</string>
@ -206,33 +202,12 @@
<string name="ask_empty_id_ok">Es wurde eine leere Identität hinzugefügt. Wirklich fortfahren?</string>
<string name="public_key_deletetion_confirmation">Soll der öffentliche Schlüssel \'%s\' wirklich gelöscht werden?\nDies kann nicht rückgängig gemacht werden! </string>
<string name="also_export_secret_keys">Private Schlüssel auch exportieren</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">%d Schlüssel erfolgreich hinzugefügt</item>
<item quantity="other">%d Schlüssel erfolgreich hinzugefügt</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">und %d Schlüssel erfolgreich aktualisiert.</item>
<item quantity="other">und %d Schlüssel erfolgreich aktualisiert.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">%d Schlüssel erfolgreich hinzugefügt.</item>
<item quantity="other">%d Schlüssel erfolgreich hinzugefügt.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">%d Schlüssel erfolgreich aktualisiert.</item>
<item quantity="other">%d Schlüssel erfolgreich aktualisiert.</item>
</plurals>
<string name="import_error_nothing">Keine Schlüssel hinzugefügt oder aktualisiert.</string>
<string name="key_exported">1 Schlüssel erfolgreich exportiert.</string>
<string name="keys_exported">%d Schlüssel erfolgreich exportiert.</string>
<string name="no_keys_exported">Keine Schlüssel exportiert.</string>
<string name="key_creation_el_gamal_info">Beachte: Nur Unterschlüssel unterstützen ElGamal.</string>
<string name="key_creation_weak_rsa_info">Beachte: RSA-Schlüssel mit einer Schlüssellänge von 1024-Bits oder weniger werden als unsicher angesehen und können daher nicht für neue Schlüssel erstellt werden.</string>
<string name="key_not_found">Schlüssel %08X konnte nicht gefunden werden.</string>
<plurals name="keys_found">
<item quantity="one">%d Schlüssel gefunden.</item>
<item quantity="other">%d Schlüssel gefunden.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d schlechter privater Schlüssel ignoriert. Evtl. wurde er mit folgender Option exportiert:\n --export-secret-subkeys\nUnbedingt mit der Option \n --export-secret-keys\nexportieren.</item>
<item quantity="other">%d schlechte private Schlüssel ignoriert. Evtl. wurden sie mit folgender Option exportiert:\n --export-secret-subkeys\nUnbedingt mit der Option \n --export-secret-keys\nexportieren.</item>
@ -272,8 +247,8 @@
<string name="error_only_files_are_supported">Binäre Daten ohne ohne Datei im Dateisystem werden nicht unterstützt.</string>
<string name="error_jelly_bean_needed">Android 4.1 wird benötigt um Androids NFC Beam nutzen zu können!</string>
<string name="error_nfc_needed">NFC steht auf diesem Gerät nicht zur Verfügung!</string>
<string name="error_nothing_import">Nichts zu importieren!</string>
<string name="error_import_file_no_content">Datei ist leer</string>
<string name="error_keyserver_insufficient_query">zu kurze Schlüsselanfrage</string>
<string name="error_keyserver_too_many_responses">Die Schlüsselanfrage liefert zu viele Ergebnisse. Bitte verfeinern sie sie Anfrage.</string>
<string name="error_generic_report_bug">Ein allgemeiner Fehler trat auf, bitte schreiben Sie einen neuen Bugreport für OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Ein Teil der geladenen Datei ist ein gültiges OpenPGP Objekt aber kein OpenPGP Schlüssel</item>
@ -366,6 +341,7 @@
<string name="import_nfc_help_button">Hilfe</string>
<string name="import_clipboard_button">Schlüssel aus der Zwischenablage einfügen</string>
<string name="import_keybase_button">Schlüssel von Keybase.io erhalten</string>
<!--Import result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">Datei entschlüsseln mit OpenKeychain</string>
<string name="intent_import_key">Schlüssel importieren mit OpenKeychain</string>
@ -429,7 +405,7 @@
<string name="nav_encrypt">Signieren und Verschlüsseln</string>
<string name="nav_decrypt">Entschlüsseln und Verifizieren</string>
<string name="nav_import">Schlüssel Importieren</string>
<string name="nav_apps">Registrierte Anwendungen</string>
<string name="nav_apps">Apps</string>
<string name="drawer_open">Menü öffnen</string>
<string name="drawer_close">Menü schließen</string>
<string name="edit">Bearbeiten</string>
@ -438,8 +414,8 @@
<string name="secret_key_yes">verfügbar</string>
<string name="secret_key_no">nicht verfügbar</string>
<!--hints-->
<string name="encrypt_content_edit_text_hint">Hier den Text schreiben welche verschlüsselt und/oder signiert werden soll...</string>
<string name="decrypt_content_edit_text_hint">Hier den verschlüsselten Text eingeben um ihn zu entschlüsseln und/oder zu verifzieren…</string>
<string name="encrypt_content_edit_text_hint">Hier die Nachricht schreiben welche verschlüsselt und/oder signiert werden soll…</string>
<string name="decrypt_content_edit_text_hint">Hier die verschlüsselte Nachricht eingeben um sie zu entschlüsseln und/oder zu verifzieren…</string>
<!--certs-->
<string name="cert_default">normal</string>
<string name="cert_none">kein</string>
@ -450,6 +426,19 @@
<string name="cert_verify_failed">fehlgeschlagen!</string>
<string name="cert_verify_error">Fehler!</string>
<string name="cert_verify_unavailable">Schlüssel nicht verfügbar</string>
<!--Import Public log entries-->
<string name="msg_ip_delete_old_ok">Alte Schlüssel aus der Datenbank löschen</string>
<string name="msg_ip_encode_fail">Die Anwendung ist wegen Kodierungsfehler fehlgeschlagen</string>
<string name="msg_ip_fail_io_exc">Die Anwendung is wegen Eingabe/Ausgabe-Fehler fehlgeschlagen</string>
<string name="msg_ip_fail_remote_ex">Die Anwendung ist wegen internen Fehler fehlgeschlagen</string>
<string name="msg_ip_insert_keyring">Schlüsselbund-daten werden kodiert</string>
<string name="msg_ip_prepare">Datenbank-Transaktionen werden vorbereitet</string>
<string name="msg_ip_subkey">Unterschlüssel %s wird bearbeitet</string>
<!--Import Secret log entries-->
<string name="msg_is_importing_subkeys">Geheime Unterschlüssel werden bearbeitet</string>
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
<string name="section_certifier_id">Beglaubiger</string>
<string name="section_cert">Zertifikatdetails</string>
@ -468,5 +457,7 @@
<string name="title_view_cert">Zertifikatdetails anzeigen</string>
<string name="unknown_algorithm">unbekannt</string>
<string name="can_sign_not">Kann nicht unterschreiben</string>
<string name="error_encoding">Kodierungsfehler</string>
<string name="error_no_encrypt_subkey">Kein Unterschlüssel zum Verschlüsseln verfügbar!</string>
<string name="contact_show_key">Schlüssel anzeigen (%s)</string>
</resources>

View File

@ -41,6 +41,7 @@
<!--compression-->
<!--Help-->
<!--Import-->
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<!--Share-->
@ -49,5 +50,10 @@
<!--Navigation Drawer-->
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -8,8 +8,9 @@
<string name="title_authentication">Frase de contraseña</string>
<string name="title_create_key">Crear clave</string>
<string name="title_edit_key"> Editar clave</string>
<string name="title_wizard">Bienvenido a OpenKeychain</string>
<string name="title_preferences"> Preferencias</string>
<string name="title_api_registered_apps">Aplicaciones registradas</string>
<string name="title_api_registered_apps">Aplicaciones</string>
<string name="title_key_server_preference">Prioridad del servidor de claves</string>
<string name="title_change_passphrase">Cambiar frase de contraseña</string>
<string name="title_set_passphrase">Establecer frase de contraseña</string>
@ -27,6 +28,7 @@
<string name="title_certify_key">Certificar identidades</string>
<string name="title_key_details">Detalles de la clave</string>
<string name="title_help">Ayuda</string>
<string name="title_log_display">Registro (log)</string>
<!--section-->
<string name="section_user_ids">Identidades</string>
<string name="section_keys">Subclaves</string>
@ -70,16 +72,11 @@
<!--menu-->
<string name="menu_preferences">Ajustes</string>
<string name="menu_help">Ayuda</string>
<string name="menu_import_from_file">Importar desde archivo</string>
<string name="menu_import_from_qr_code">Importar desde código QR</string>
<string name="menu_import_from_nfc">Importar desde NFC</string>
<string name="menu_export_key">Exportar hacia archivo</string>
<string name="menu_delete_key">Borrar clave</string>
<string name="menu_create_key">Crear clave</string>
<string name="menu_create_key_expert">Crear clave (experto)</string>
<string name="menu_search">Buscar</string>
<string name="menu_import_from_key_server">Servidor de claves...</string>
<string name="menu_import_from_keybase">Importar desde Keybase.io</string>
<string name="menu_key_server">Servidor de claves...</string>
<string name="menu_update_key">Actualizar desde servidor de claves</string>
<string name="menu_export_key_to_server">Cargar al servidor de claves</string>
@ -98,6 +95,7 @@
<string name="menu_select_all">Seleccionar todo</string>
<string name="menu_add_keys">Añadir claves</string>
<string name="menu_export_all_keys">Exportar todas las claves</string>
<string name="menu_advanced">Mostrar información avanzada</string>
<!--label-->
<string name="label_sign">Firmar</string>
<string name="label_message">Mensaje</string>
@ -206,33 +204,12 @@
<string name="ask_empty_id_ok">Ha añadido una identidad vacía, ¿está seguro de que quiere continuar?</string>
<string name="public_key_deletetion_confirmation">¿De veras quiere borrar la clave pública \'%s\'?\n¡No puede deshacer esto!</string>
<string name="also_export_secret_keys">¿Exportar también las claves secretas?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">%d clave añadida satisfactoriamente</item>
<item quantity="other">%d claves añadidas satisfactoriamente</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">y actualizada %d clave.</item>
<item quantity="other">y actualizadas %d claves.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">%d clave añadida satisfactoriamente.</item>
<item quantity="other">%d claves añadidas satisfactoriamente.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">%d clave actualizada satisfactoriamente.</item>
<item quantity="other">%d claves actualizadas satisfactoriamente.</item>
</plurals>
<string name="import_error_nothing">No se han añadido o actualizado claves.</string>
<string name="key_exported">Se ha exportado 1 clave satisfactoriamente.</string>
<string name="keys_exported">%d claves exportadas satisfactoriamente.</string>
<string name="no_keys_exported">No se han exportado claves.</string>
<string name="key_creation_el_gamal_info">Nota: Sólo las subclaves soportan ElGamal.</string>
<string name="key_creation_weak_rsa_info">Nota: generar una clave RSA de longitud 1024-bit o menos está considerado inseguro y desactivado para generar nuevas claves.</string>
<string name="key_not_found">No se puede encontrar la clave %08X.</string>
<plurals name="keys_found">
<item quantity="one">Se ha encontrado %d clave.</item>
<item quantity="other">Se han encontrado %d claves.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d mala clave secreta ignorada. Quizás hayas exportado con la opción\n--export-secret-subkeys\nAsegúrate de que exportas con\n--export-secret-keys\nen su lugar.</item>
<item quantity="other">%d malas claves secretas ignoradas. Quizás hayas exportado con la opción\n--export-secret-subkeys\nAsegúrate de que exportas con\n--export-secret-keys\nen su lugar.</item>
@ -272,11 +249,11 @@
<string name="error_only_files_are_supported">Los datos binarios directos sin un fichero existente en el sistema de ficheros no están soportados.</string>
<string name="error_jelly_bean_needed">¡Necesita Android 4.1 para usar la característica NFC Beam (haz NFC) de Android!</string>
<string name="error_nfc_needed">¡NFC no está disponible en tu dispositivo!</string>
<string name="error_nothing_import">¡Nada que importar!</string>
<string name="error_nothing_import">¡No se encontraron claves!</string>
<string name="error_keyserver_insufficient_query">Petición de búsqueda de clave demasiado corta</string>
<string name="error_searching_keys">Error irrecuperable buscando claves en el servidor</string>
<string name="error_keyserver_too_many_responses">La petición de búsqueda de clave devolvió demasiados candidatos; por favor refine su petición</string>
<string name="error_import_file_no_content">El archivo está vacio</string>
<string name="error_import_file_no_content">El Fichero/Portapapeles está vacío</string>
<string name="error_generic_report_bug">Ha ocurrido un error genérico, por favor, informa de este bug a OpenKeychain</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">parte del archivo cargado es un objeto OpenPGP válido pero no una clave OpenPGP</item>
@ -327,10 +304,10 @@
<string name="progress_verifying_integrity">verificando la integridad...</string>
<string name="progress_deleting_securely">borrando \'%s\' de forma segura…</string>
<!--action strings-->
<string name="hint_public_keys">Buscar claves públicas</string>
<string name="hint_public_keys">Identidad de Nombre/Correo/Clave...</string>
<string name="hint_secret_keys">Buscar claves secretas</string>
<string name="action_share_key_with">Compartir la clave con...</string>
<string name="hint_keybase_search">Buscar en Keybase.io</string>
<string name="hint_keybase_search">Nombre de usuario de Nombre/Keybase.io...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -356,6 +333,10 @@
<string name="help_tab_about">A cerca de</string>
<string name="help_about_version">Versión:</string>
<!--Import-->
<string name="import_tab_keyserver">Servidor de claves</string>
<string name="import_tab_direct">Fichero/Portapapeles</string>
<string name="import_tab_qr_code">Código QR/NFC</string>
<string name="import_tab_keybase">Keybase.io</string>
<string name="import_import">Importar las claves seleccionadas</string>
<string name="import_from_clipboard">Importar desde el portapapeles</string>
<plurals name="import_qr_code_missing">
@ -369,8 +350,30 @@
<string name="import_qr_scan_button">Escanea el código QR con \'Barcode Scanner\'</string>
<string name="import_nfc_text">Para recibir las claves a través de NFC, el dispositivo tiene que estar desbloqueado.</string>
<string name="import_nfc_help_button">Ayuda</string>
<string name="import_qr_code_button">Escaneando código QR...</string>
<string name="import_clipboard_button">Tomar la clave desde el portapapeles</string>
<string name="import_keybase_button">Obtener clave desde Keybase.io</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Clave importada con éxito</item>
<item quantity="other">%1$d claves importadas con éxito</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one"> y clave%2$s actualizada.</item>
<item quantity="other"> y %1$d claves%2$s actualizadas.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">Clave%2$s importada con éxito.</item>
<item quantity="other">%1$d claves%2$s importadas con éxito.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">Clave%2$s importada con éxito.</item>
<item quantity="other">%1$d claves%2$s importadas con éxito.</item>
</plurals>
<string name="import_view_log">Ver registro (log)</string>
<string name="import_error_nothing">No hay nada que importar.</string>
<string name="import_error">¡Error importando claves!</string>
<string name="import_with_warnings">, con advertencias</string>
<!--Intent labels-->
<string name="intent_decrypt_file">Descifrar archivo con OpenKeychain</string>
<string name="intent_import_key">Importar clave con OpenKeychain</string>
@ -434,7 +437,7 @@
<string name="nav_encrypt">Firmar y cifrar</string>
<string name="nav_decrypt">Descifrar y verificar</string>
<string name="nav_import">Importar claves</string>
<string name="nav_apps">Aplicaciones registradas</string>
<string name="nav_apps">Aplicaciones</string>
<string name="drawer_open">Abrir el Navigation Drawer</string>
<string name="drawer_close">Cerrar el Navigation Drawer</string>
<string name="edit">Editar</string>
@ -455,6 +458,142 @@
<string name="cert_verify_failed">¡falló!</string>
<string name="cert_verify_error">¡error!</string>
<string name="cert_verify_unavailable">clave no disponible</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Aplicando operación de inserción por lote.</string>
<string name="msg_ip_bad_type_secret">Se intentó importar un juego de claves (keyring) secreto como público. Esto es un fallo, por favor ¡consigne un informe!</string>
<string name="msg_ip_delete_old_fail">No se borró ninguna clave antigua (¿crear una nueva?)</string>
<string name="msg_ip_delete_old_ok">Clave antigua borrada de la base de datos</string>
<string name="msg_ip_encode_fail">La operación falló debido a un error de codificación</string>
<string name="msg_ip_fail_io_exc">La operación falló debido a un error de E/S</string>
<string name="msg_ip_fail_op_exc">La operación falló debido a un error de la base de datos</string>
<string name="msg_ip_fail_remote_ex">La operación falló debido a un error interno</string>
<string name="msg_ip">Importando juego de claves públicas %s</string>
<string name="msg_ip_insert_keyring">Codificando datos del juego de claves (keyring)</string>
<string name="msg_ip_insert_keys">Analizando claves</string>
<string name="msg_ip_prepare">Preparando base de datos de operaciones</string>
<string name="msg_ip_master">Procesando clave maestra %s</string>
<string name="msg_ip_master_expired">El juego de claves expiró el %s</string>
<string name="msg_ip_master_expires">El juego de claves expira el %s</string>
<string name="msg_ip_master_flags_ces">Distintivos de clave maestra: certificar, cifrar, firmar</string>
<string name="msg_ip_master_flags_cex">Distintivos de clave maestra: certificar, cifrar</string>
<string name="msg_ip_master_flags_cxs">Distintivos de clave maestra: certificar, firmar</string>
<string name="msg_ip_master_flags_xes">Distintivos de clave maestra: cifrar, firmar</string>
<string name="msg_ip_master_flags_cxx">Distintivos de clave maestra: certificar</string>
<string name="msg_ip_master_flags_xex">Distintivos de clave maestra: cifrar</string>
<string name="msg_ip_master_flags_xxs">Distintivos de clave maestra: firmar</string>
<string name="msg_ip_master_flags_xxx">Distintivos de clave maestra: ninguno</string>
<string name="msg_ip_subkey">Procesando subclave %s</string>
<string name="msg_ip_subkey_expired">La subclave expiró el %s</string>
<string name="msg_ip_subkey_expires">La subclave expira el %s</string>
<string name="msg_ip_subkey_flags_ces">Distintivos de subclave: certificar, cifrar, firmar</string>
<string name="msg_ip_subkey_flags_cex">Distintivos de subclave: certificar, cifrar</string>
<string name="msg_ip_subkey_flags_cxs">Distintivos de subclave: certificar, firmar</string>
<string name="msg_ip_subkey_flags_xes">Distintivos de subclave: cifrar, firmar</string>
<string name="msg_ip_subkey_flags_cxx">Distintivos de subclave: certificar</string>
<string name="msg_ip_subkey_flags_xex">Distintivos de subclave: cifrar</string>
<string name="msg_ip_subkey_flags_xxs">Distintivos de subclave: firmar</string>
<string name="msg_ip_subkey_flags_xxx">Distintivos de subclave: ninguno</string>
<string name="msg_ip_success">Juego de claves públicas importado con éxito</string>
<string name="msg_ip_success_identical">El juego de claves no contiene nuevos datos, no hay nada que hacer</string>
<string name="msg_ip_reinsert_secret">Re-insertando clave secreta</string>
<string name="msg_ip_uid_cert_bad">¡Se encontró un certificado defectuoso!</string>
<string name="msg_ip_uid_cert_error">¡Error procesando certificado!</string>
<string name="msg_ip_uid_cert_good">La identificación de usuario está certificada por %1$s (%2$s)</string>
<plurals name="msg_ip_uid_certs_unknown">
<item quantity="one">Ignorando un certificado publicado por una clave pública desconocida</item>
<item quantity="other">Ignorando %s certificados publicados por claves públicas desconocidas</item>
</plurals>
<string name="msg_ip_uid_classifying_zero">Clasificando identidades de usuario (no hay claves de confianza disponibles)</string>
<plurals name="msg_ip_uid_classifying">
<item quantity="one">Clasificando identidades de usuario (usando una clave de confianza)</item>
<item quantity="other">Clasificando identidades de usuario (usando %s claves de confianza)</item>
</plurals>
<string name="msg_ip_uid_reorder">Re-ordenando identidades de usuario</string>
<string name="msg_ip_uid_processing">Procesando identidad (id) de usuario %s</string>
<string name="msg_ip_uid_revoked">La identificación de usuario está revocada</string>
<string name="msg_is_bad_type_public">Se intentó importar un juego de claves (keyring) público como secreto. Esto es un fallo, por favor ¡consigne un informe!</string>
<!--Import Secret log entries-->
<string name="msg_is">Importando clave secreta (privada) %s</string>
<string name="msg_is_db_exception">¡Error de base de datos!</string>
<string name="msg_is_importing_subkeys">Procesando subclaves secretas</string>
<string name="msg_is_io_exc">Error codificando el juego de claves</string>
<string name="msg_is_pubring_generate">Generando un juego de claves públicas desde el juego de claves secretas (privadas)</string>
<string name="msg_is_subkey_nonexistent">Subclave %s no disponible en la clave pública</string>
<string name="msg_is_subkey_ok">Se marcó %s como no disponible</string>
<string name="msg_is_subkey_stripped">Se marcó %s como desnudo (de subclave)</string>
<string name="msg_is_success_identical">El juego de claves no contiene nuevos datos, no hay nada que hacer</string>
<string name="msg_is_success">Juego de claves secretas (privadas) importado con éxito</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_public">Canonicalizando juego de claves público %s</string>
<string name="msg_kc_secret">Canonicalizando juego de claves secreto %s</string>
<string name="msg_kc_fatal_no_uid">Fallo en la canonicalización de juego de claves: El juego de claves no tiene identificaciones de usuario válidas</string>
<string name="msg_kc_master">Procesando clave maestra</string>
<string name="msg_kc_revoke_bad_err">Eliminando certificado defectuoso de revocación de juego de claves</string>
<string name="msg_kc_revoke_bad_local">Eliminando certificado de revocación de juego de claves, con distintivo \"local\"</string>
<string name="msg_kc_revoke_bad_time">Eliminando certificado de revocación de juego de claves, con marca de tiempo futura</string>
<string name="msg_kc_revoke_bad_type">Eliminando certificado de clave maestra, de tipo desconocido (%s)</string>
<string name="msg_kc_revoke_bad">Eliminando certificado defectuoso de revocación de juego de claves</string>
<string name="msg_kc_revoke_dup">Eliminando certificado redundante de revocación de juego de claves </string>
<string name="msg_kc_sub">Procesando subclave %s</string>
<string name="msg_kc_sub_bad">Eliminando certificado no válido de vinculación de subclave</string>
<string name="msg_kc_sub_bad_err">Eliminando certificado defectuoso de vinculación de subclave</string>
<string name="msg_kc_sub_bad_local">Eliminando certificado de vinculación de subclave, con distintivo \"local\"</string>
<string name="msg_kc_sub_bad_keyid">La identidad del publicante de la vinculación de subclave no coincide</string>
<string name="msg_kc_sub_bad_time">Eliminando certificado de vinculación de subclave, con marca de tiempo futura</string>
<string name="msg_kc_sub_bad_type">Tipo de certificado de subclave desconocido: %s</string>
<string name="msg_kc_sub_dup">Eliminando certificado redundante de vinculación de subclave</string>
<string name="msg_kc_sub_primary_bad">Eliminando certificado de vinculación de subclave debido a un certificado de vinculación primario no válido</string>
<string name="msg_kc_sub_primary_bad_err">Eliminando certificado de vinculación de subclave debido a un certificado de vinculación primario defectuoso</string>
<string name="msg_kc_sub_primary_none">Eliminando certificado de vinculación de subclave debido a un certificado de vinculación primario ausente</string>
<string name="msg_kc_sub_no_cert">No se encontró ningún certificado válido para %s, eliminándola del juego de claves</string>
<string name="msg_kc_sub_revoke_bad_err">Eliminando certificado defectuoso de revocación de subclave</string>
<string name="msg_kc_sub_revoke_bad">Eliminando certificado defectuoso de revocación de subclave</string>
<string name="msg_kc_sub_revoke_dup">Eliminando certificado redundante de revocación de subclave</string>
<string name="msg_kc_success">Canonicalización del juego de claves exitosa, no hay cambios</string>
<plurals name="msg_kc_success_bad">
<item quantity="one">Canonicalización de juego de claves completada, se eliminó un certificado erróneo</item>
<item quantity="other">Canonicalización de juego de claves completada, se eliminaron %d certificados erróneos</item>
</plurals>
<string name="msg_kc_success_bad_and_red">Canonicalización de juego de claves completada, eliminados %1$s certificados erróneos y %2$s redundantes </string>
<plurals name="msg_kc_success_redundant">
<item quantity="one">Canonicalización de juego de claves completada, se eliminó un certificado redundante</item>
<item quantity="other">Canonicalización de juego de claves completada, se eliminaron %d certificados redundantes</item>
</plurals>
<string name="msg_kc_uid_bad_err">Eliminando auto-certificado defectuoso para la identidad de usuario %s</string>
<string name="msg_kc_uid_bad_local">Eliminando certificado de identidad de usuario, con distintivo \"local\"</string>
<string name="msg_kc_uid_bad_time">Eliminando identidad de usuario con marca de tiempo futura</string>
<string name="msg_kc_uid_bad_type">Eliminando certificado de identidad de usuario, de tipo desconocido (%s)</string>
<string name="msg_kc_uid_bad">Eliminando auto-certificado defectuoso para la identidad de usuario \"%s\"</string>
<string name="msg_kc_uid_dup">Eliminando auto-certificado desactualizado para el identificador de usuario \"%s\"</string>
<string name="msg_kc_uid_foreign">Eliminando certificado ajeno de identidad de usuario por %s</string>
<string name="msg_kc_uid_revoke_dup">Eliminando certificado redundate de revocación para la identidad de usuario \"%s\"</string>
<string name="msg_kc_uid_revoke_old">Eliminando certificado desactualizado de revocación para la identidad de usuario \"%s\"</string>
<string name="msg_kc_uid_no_cert">No se encontró ningún auto-certificado válido para la identificación de usuario %s, eliminándola del juego de claves.</string>
<!--Keyring merging log entries-->
<string name="msg_mg_public">Incorporándolas en el juego de claves públicas %s</string>
<string name="msg_mg_secret">Incorporándolas en el juego de claves secretas (privadas) %s</string>
<string name="msg_mg_fatal_encode">Error fatal codificando la firma</string>
<string name="msg_mg_heterogeneous">Se intentaron consolidar juegos de claves heterogéneos</string>
<string name="msg_mg_new_subkey">Añadiendo nueva subclave %s</string>
<string name="msg_mg_found_new">Se encontraron %s nuevos certificados en el juego de claves</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modificando el juego de claves %s</string>
<string name="msg_mf_error_encode">¡Excepción en la codificación!</string>
<string name="msg_mf_error_pgp">¡Excepción interna de PGP!</string>
<string name="msg_mf_error_sig">¡Excepción con la firma!</string>
<string name="msg_mf_passphrase">Cambiando frase contraseña</string>
<string name="msg_mf_subkey_change">Modificando subclave %s</string>
<string name="msg_mf_subkey_missing">¡Intentó operar sobre una subclave ausente %s!</string>
<string name="msg_mf_subkey_new">Generando nueva subclave %2$s de %1$s bits</string>
<string name="msg_mf_subkey_new_id">Nueva identidad de subclave: %s</string>
<string name="msg_mf_subkey_past_expiry">¡La fecha de expiración no puede ser del pasado!</string>
<string name="msg_mf_subkey_revoke">Revocando subclave %s</string>
<string name="msg_mf_success">Juego de claves modificado con éxito</string>
<string name="msg_mf_uid_add">Añadiendo identidad de usuario %s</string>
<string name="msg_mf_uid_primary">Cambiando identidad de usuario (uid) primaria a %s</string>
<string name="msg_mf_uid_revoke">Revocando identidad de usuario %s</string>
<string name="msg_mf_unlock_error">¡Error desbloqueando juego de claves!</string>
<string name="msg_mf_unlock">Desbloqueando juego de claves</string>
<!--unsorted-->
<string name="section_certifier_id">Certificador</string>
<string name="section_cert">Detalles del certificado</string>
@ -473,5 +612,8 @@
<string name="title_view_cert">Ver detalles del certificado</string>
<string name="unknown_algorithm">desconocido</string>
<string name="can_sign_not">no puede firmarse</string>
<string name="error_encoding">Error de codificación</string>
<string name="error_no_encrypt_subkey">¡No hay subclave de cifrado disponible!</string>
<string name="info_no_manual_account_creation">No cree Cuentas-OpenKeychain manualmente.\nPara más información, vea la Ayuda.</string>
<string name="contact_show_key">Mostrar clave (%s)</string>
</resources>

View File

@ -9,7 +9,6 @@
<string name="title_create_key">Loo võti</string>
<string name="title_edit_key">Muuda võtit</string>
<string name="title_preferences">Seaded</string>
<string name="title_api_registered_apps">Registreeritud rakendused</string>
<string name="title_key_server_preference">Võtmeserveri seaded</string>
<string name="title_set_passphrase">Määra salasõne</string>
<string name="title_import_keys">Impordi võtmeid</string>
@ -94,6 +93,7 @@
<!--compression-->
<!--Help-->
<!--Import-->
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<!--Share-->
@ -102,5 +102,10 @@
<!--Navigation Drawer-->
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -8,8 +8,9 @@
<string name="title_authentication">Phrase de passe</string>
<string name="title_create_key">Créer une clef</string>
<string name="title_edit_key">Modifier une clef</string>
<string name="title_wizard">Bienvenue à OpenKeychain</string>
<string name="title_preferences">Préférences</string>
<string name="title_api_registered_apps">Applications enregistrées</string>
<string name="title_api_registered_apps">Applis</string>
<string name="title_key_server_preference">Préférences du serveur de clefs</string>
<string name="title_change_passphrase">Modifier la phrase de passe</string>
<string name="title_set_passphrase">Définir la phrase de passe</string>
@ -27,6 +28,7 @@
<string name="title_certify_key">Certifier les identités</string>
<string name="title_key_details">Détails sur la clef</string>
<string name="title_help">Aide</string>
<string name="title_log_display">Journal</string>
<!--section-->
<string name="section_user_ids">identités</string>
<string name="section_keys">Sous-clefs</string>
@ -70,16 +72,11 @@
<!--menu-->
<string name="menu_preferences">Paramètres</string>
<string name="menu_help">Aide</string>
<string name="menu_import_from_file">Importer depuis un fichier</string>
<string name="menu_import_from_qr_code">Importer depuis un code QR</string>
<string name="menu_import_from_nfc">Importer avec la NFC</string>
<string name="menu_export_key">Exporter vers un fichier</string>
<string name="menu_delete_key">Supprimer la clef</string>
<string name="menu_create_key">Créer une clef</string>
<string name="menu_create_key_expert">Créer une clef (expert)</string>
<string name="menu_search">Rechercher</string>
<string name="menu_import_from_key_server">Serveur de clefs</string>
<string name="menu_import_from_keybase">Importer depuis Keybase.io</string>
<string name="menu_key_server">Serveur de clefs...</string>
<string name="menu_update_key">Mettre à jour depuis le serveur de clefs</string>
<string name="menu_export_key_to_server">Téléverser vers le serveur de clefs</string>
@ -98,6 +95,7 @@
<string name="menu_select_all">Tout sélectionner</string>
<string name="menu_add_keys">Ajouter des clefs</string>
<string name="menu_export_all_keys">Exporter toutes les clefs</string>
<string name="menu_advanced">Afficher les infos avancées</string>
<!--label-->
<string name="label_sign">Signer</string>
<string name="label_message">Message</string>
@ -206,33 +204,12 @@
<string name="ask_empty_id_ok">Vous avez ajouté une identité vide, êtes-vous certain de vouloir continuer ?</string>
<string name="public_key_deletetion_confirmation">Voulez-vous vraiment supprimer la clef publique %s ?\nCeci est irréversible !</string>
<string name="also_export_secret_keys">Exporter aussi les clefs secrètes ?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">%d clef ajoutée avec succès</item>
<item quantity="other">%d clefs ajoutées avec succès</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">et %d clef mise à jour.</item>
<item quantity="other">et %d clefs mises à jour.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">%d clef ajoutée avec succès.</item>
<item quantity="other">%d clefs ajoutées avec succès.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">%d clef mise à jour avec succès.</item>
<item quantity="other">%d clefs mises à jour avec succès.</item>
</plurals>
<string name="import_error_nothing">Aucune clef ajoutée ou mise à jour.</string>
<string name="key_exported">1 clef exportée avec succès.</string>
<string name="keys_exported">%d clefs exportées avec succès.</string>
<string name="no_keys_exported">Aucune clef exportée.</string>
<string name="key_creation_el_gamal_info">Note : seules les sous-clefs prennent en charge ElGamal.</string>
<string name="key_creation_weak_rsa_info">Note : générer des clefs RSA d\'une longueur de 1024 bits ou moins est considéré non sécuritaire et est désactivé pour la génération de nouvelles clefs.</string>
<string name="key_not_found">Clef %08X introuvable.</string>
<plurals name="keys_found">
<item quantity="one">%d clef trouvée.</item>
<item quantity="other">%d clefs trouvées.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d mauvaise clef ignorée. Vous avez peut-être exporté avec l\'option\n --export-secret-subkeys\nAssurez-vous d\'exporter plutôt avec\n --export-secret-keys.</item>
<item quantity="other">%d mauvaises clefs ignorées. Vous avez peut-être exporté avec l\'option\n --export-secret-subkeys\nAssurez-vous d\'exporter plutôt avec\n --export-secret-keys.</item>
@ -272,11 +249,11 @@
<string name="error_only_files_are_supported">Les données binaires directes sans fichier dans le système de fichiers ne sont pas prises en charge.</string>
<string name="error_jelly_bean_needed">Il vous faut Android 4.1 pour utiliser la fonction Beam NFC d\'Android !</string>
<string name="error_nfc_needed">La NFC n\'est pas disponible sur votre appareil !</string>
<string name="error_nothing_import">Rien à importer !</string>
<string name="error_nothing_import">Aucune clef trouvée !</string>
<string name="error_keyserver_insufficient_query">La requête de recherche de clef est trop courte</string>
<string name="error_searching_keys">Erreur irrécupérable lors de la recherche de clef sur le serveur</string>
<string name="error_keyserver_too_many_responses">La requête de recherche de clef a retourné trop de candidats. Veuillez raffiner la requête</string>
<string name="error_import_file_no_content">Le fichier n\'a pas de contenu</string>
<string name="error_import_file_no_content">Le fichier/le presse-papiers est vide</string>
<string name="error_generic_report_bug">Une erreur générique est survenue, veuillez créer un nouveau rapport de bogue pour OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">une partie du fichier chargé est un objet OpenPGP valide mais pas une clef OpenPGP</item>
@ -327,10 +304,10 @@
<string name="progress_verifying_integrity">vérification de l\'intégrité...</string>
<string name="progress_deleting_securely">suppression sûre de « %s »...</string>
<!--action strings-->
<string name="hint_public_keys">Rechercher des clefs publiques</string>
<string name="hint_public_keys">Nom/courriel/ ID clef...</string>
<string name="hint_secret_keys">Rechercher des clefs secrètes</string>
<string name="action_share_key_with">Partager la clef avec...</string>
<string name="hint_keybase_search">Rechercher dans Keybase.io</string>
<string name="hint_keybase_search">Nom/nom d\'utilisateur keybase.io...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -356,6 +333,10 @@
<string name="help_tab_about">À propos de</string>
<string name="help_about_version">Version :</string>
<!--Import-->
<string name="import_tab_keyserver">Serveur de clefs</string>
<string name="import_tab_direct">Fichier/presse-papiers</string>
<string name="import_tab_qr_code">Code QR/NFC</string>
<string name="import_tab_keybase">Keybase.io</string>
<string name="import_import">Importer les clefs choisies</string>
<string name="import_from_clipboard">Importer à partir du presse-papiers</string>
<plurals name="import_qr_code_missing">
@ -369,8 +350,18 @@
<string name="import_qr_scan_button">Numériser le code QR avec le lecteur de code-barres</string>
<string name="import_nfc_text">Pour recevoir des clefs par la NFC, les appareils doivent être déverrouillés.</string>
<string name="import_nfc_help_button">Aide</string>
<string name="import_qr_code_button">Balayer le code QR...</string>
<string name="import_clipboard_button">Obtenir la clef depuis le presse-papiers</string>
<string name="import_keybase_button">Obtenir la clef depuis Keybase.io</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Clef importée avec succès</item>
<item quantity="other">%1$d clefs importées avec succès</item>
</plurals>
<string name="import_view_log">Consulter le journal</string>
<string name="import_error_nothing">Rien à importer.</string>
<string name="import_error">Erreur lors de l\'importation des clefs !</string>
<string name="import_with_warnings">, avec des avertissements</string>
<!--Intent labels-->
<string name="intent_decrypt_file">Déchiffrer le fichier avec OpenKeychain</string>
<string name="intent_import_key">Importer la clef avec OpenKeychain</string>
@ -434,7 +425,7 @@
<string name="nav_encrypt">Signer et chiffrer</string>
<string name="nav_decrypt">Déchiffrer et vérifier</string>
<string name="nav_import">Importer les clefs</string>
<string name="nav_apps">Applis enregistrées</string>
<string name="nav_apps">Applis</string>
<string name="drawer_open">Ouvrir le tiroir de navigation</string>
<string name="drawer_close">Fermer le tiroir de navigation</string>
<string name="edit">Modifier</string>
@ -455,6 +446,146 @@
<string name="cert_verify_failed">échec!</string>
<string name="cert_verify_error">erreur!</string>
<string name="cert_verify_unavailable">clef non disponible</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Application de l\'opération d\'insertion par lot.</string>
<string name="msg_ip_bad_type_secret">Tentative d\'importer le trousseau secret comme public. Ceci est un bogue, veuillez remplir un rapport !</string>
<string name="msg_ip_delete_old_fail">Aucune ancienne clef de supprimée (création d\'une nouvelle ?)</string>
<string name="msg_ip_delete_old_ok">L\'ancienne clef a été supprimée de la base de données</string>
<string name="msg_ip_encode_fail">Échec de l\'opération causé par une erreur d\'encodage</string>
<string name="msg_ip_fail_io_exc">Échec de l\'opération causé par une erreur d\'e/s</string>
<string name="msg_ip_fail_op_exc">Échec de l\'opération causé par une erreur de base de données</string>
<string name="msg_ip_fail_remote_ex">Échec de l\'opération causé par une erreur interne</string>
<string name="msg_ip">Importation du trousseau public %s</string>
<string name="msg_ip_insert_keyring">Encodage des données du trousseau</string>
<string name="msg_ip_insert_keys">Analyse des clefs</string>
<string name="msg_ip_prepare">Préparation des opérations sur la base de données</string>
<string name="msg_ip_master">Traitement de la clef maîtresse %s</string>
<string name="msg_ip_master_expired">Trousseau expiré le %s</string>
<string name="msg_ip_master_expires">Le trousseau expire le %s</string>
<string name="msg_ip_master_flags_ces">Drapeaux de la clef maîtresse : certifier, chiffrer, signer</string>
<string name="msg_ip_master_flags_cex">Drapeaux de la clef maîtresse : certifier, chiffrer</string>
<string name="msg_ip_master_flags_cxs">Drapeaux de la clef maîtresse : certifier, signer</string>
<string name="msg_ip_master_flags_xes">Drapeaux de la clef maîtresse : chiffrer, signer</string>
<string name="msg_ip_master_flags_cxx">Drapeaux de la clef maîtresse : certifier</string>
<string name="msg_ip_master_flags_xex">Drapeaux de la clef maîtresse : chiffrer</string>
<string name="msg_ip_master_flags_xxs">Drapeaux de la clef maîtresse : signer</string>
<string name="msg_ip_master_flags_xxx">Drapeaux de la clef maîtresse : aucun</string>
<string name="msg_ip_subkey">Traitement de la sous-clef %s</string>
<string name="msg_ip_subkey_expired">La sous-clef a expiré le %s</string>
<string name="msg_ip_subkey_expires">La sous-clef expire le %s</string>
<string name="msg_ip_subkey_flags_ces">Drapeaux de sous-clef : certifier, chiffrer, signer</string>
<string name="msg_ip_subkey_flags_cex">Drapeaux de sous-clef : certifier, chiffrer</string>
<string name="msg_ip_subkey_flags_cxs">Drapeaux de sous-clef : certifier, signer</string>
<string name="msg_ip_subkey_flags_xes">Drapeaux de sous-clef : chiffrer, signer</string>
<string name="msg_ip_subkey_flags_cxx">Drapeaux de sous-clef : certifier</string>
<string name="msg_ip_subkey_flags_xex">Drapeaux de sous-clef : chiffrer</string>
<string name="msg_ip_subkey_flags_xxs">Drapeaux de sous-clef : signer</string>
<string name="msg_ip_subkey_flags_xxx">Drapeaux de sous-clef : aucun</string>
<string name="msg_ip_success">Importation du trousseau public réussie</string>
<string name="msg_ip_success_identical">Le trousseau ne contient pas de nouvelle donnée, rien à faire</string>
<string name="msg_ip_reinsert_secret">Réinsertion de la clef secrète</string>
<string name="msg_ip_uid_cert_bad">Un mauvais certificat a été rencontré !</string>
<string name="msg_ip_uid_cert_error">Erreur lors du traitement du certificat !</string>
<string name="msg_ip_uid_cert_good">L\'ID utilisateur est certifié par %1$s (%2$s)</string>
<plurals name="msg_ip_uid_certs_unknown">
<item quantity="one">Un certificat ignoré provenant d\'une clef publique inconnue</item>
<item quantity="other">%s certificats ignorés provenant de clefs publiques inconnues</item>
</plurals>
<string name="msg_ip_uid_classifying_zero">Classification des ID utilisateurs (aucune clef de confiance disponible)</string>
<plurals name="msg_ip_uid_classifying">
<item quantity="one">Classification des ID utilisateurs (en utilisant une clef de confiance)</item>
<item quantity="other">Classification des ID utilisateurs (en utilisant %s clefs de confiance)</item>
</plurals>
<string name="msg_ip_uid_reorder">Réorganisation des ID utilisateurs</string>
<string name="msg_ip_uid_processing">Traitement de l\'ID utilisateur %s</string>
<string name="msg_ip_uid_revoked">L\'ID utilisateur est révoqué</string>
<string name="msg_is_bad_type_public">Tentative d\'importer le trousseau public comme secret. Ceci est un bogue, veuillez remplir un rapport !</string>
<!--Import Secret log entries-->
<string name="msg_is">Importation de la clef secrète %s</string>
<string name="msg_is_db_exception">Erreur de base de données!</string>
<string name="msg_is_importing_subkeys">Traitement des sous-clefs secrètes</string>
<string name="msg_is_io_exc">Erreur lors de l\'encodage du trousseau</string>
<string name="msg_is_pubring_generate">Génération du trousseau public à partir du trousseau secret</string>
<string name="msg_is_subkey_nonexistent">La sous-clef %s n\'est pas disponible dans la clef publique</string>
<string name="msg_is_subkey_ok">%s marqué comme disponible</string>
<string name="msg_is_subkey_stripped">%s marqué comme dépouillée</string>
<string name="msg_is_success_identical">Le trousseau ne contient pas de nouvelle donnée, rien à faire</string>
<string name="msg_is_success">Importation du trousseau secret réussie</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_public">Canonicalisation du trousseau public %s</string>
<string name="msg_kc_secret">Canonicalisation du trousseau secret %s</string>
<string name="msg_kc_fatal_no_uid">La canonicalisation du trousseau a échoué : le trousseau n\'a pas d\'ID utilisateur valides</string>
<string name="msg_kc_master">Traitement de la clef maîtresse</string>
<string name="msg_kc_revoke_bad_err">Suppression du mauvais certificat de révocation du trousseau</string>
<string name="msg_kc_revoke_bad_local">Suppression du certificat de révocation du trousseau ayant le drapeau « local »</string>
<string name="msg_kc_revoke_bad_time">Suppression du certificat de révocation du trousseau ayant une estampille temporelle dans le futur</string>
<string name="msg_kc_revoke_bad_type">Suppression du certificat de clef maîtresse de type inconnu (%s)</string>
<string name="msg_kc_revoke_bad">Suppression du mauvais certificat de révocation du trousseau</string>
<string name="msg_kc_revoke_dup"> Suppression du certificat redondant de révocation du trousseau</string>
<string name="msg_kc_sub">Traitement de la sous-clef %s</string>
<string name="msg_kc_sub_bad">Suppression du certificat invalide de liaison de la sous-clef</string>
<string name="msg_kc_sub_bad_err">Suppression du mauvais certificat de liaison de la sous-clef</string>
<string name="msg_kc_sub_bad_local">Suppression du certificat de liaison de la sous-clef ayant le drapeau « local »</string>
<string name="msg_kc_sub_bad_keyid">L\'ID de l\'émetteur de la liaison de la sous-clef ne correspond pas</string>
<string name="msg_kc_sub_bad_time">Suppression du certificat de liaison de la sous-clef ayant une estampille temporelle dans le futur</string>
<string name="msg_kc_sub_bad_type">Type de certificat de sous-clef inconnu : %s</string>
<string name="msg_kc_sub_dup">Suppression du certificat redondant de liaison de sous-clef</string>
<string name="msg_kc_sub_primary_bad">Suppression du certificat de liaison de la sous-clef à cause d\'un certificat de liaison primaire invalide</string>
<string name="msg_kc_sub_primary_bad_err">Suppression du certificat de liaison de la sous-clef due à un mauvais certificat de liaison</string>
<string name="msg_kc_sub_primary_none">Suppression du certificat de liaison de la sous-clef due à un certificat de liaison primaire manquant</string>
<string name="msg_kc_sub_no_cert">Aucun certificat valide trouvé pour %s, qui est maintenant enlevé du trousseau</string>
<string name="msg_kc_sub_revoke_bad_err">Suppression du certificat de révocation de la mauvaise sous-clef</string>
<string name="msg_kc_sub_revoke_bad">Suppression du certificat de révocation de la mauvaise sous-clef</string>
<string name="msg_kc_sub_revoke_dup">Suppression du certificat de révocation de la sous-clef redondante</string>
<string name="msg_kc_success">Canonicalisation du trousseau réussie, aucun changement</string>
<plurals name="msg_kc_success_bad">
<item quantity="one">Canonicalisation du trousseau réussie, un certificat erroné supprimé</item>
<item quantity="other">Canonicalisation du trousseau réussie, %d certificats erronés supprimés</item>
</plurals>
<string name="msg_kc_success_bad_and_red">Canonicalisation du trousseau réussie, %1$s certificats erronés et %2$s certificats redondants supprimés</string>
<plurals name="msg_kc_success_redundant">
<item quantity="one">Canonicalisation du trousseau réussie, un certificat redondant supprimé</item>
<item quantity="other">Canonicalisation du trousseau réussie, %d certificats redondants supprimés</item>
</plurals>
<string name="msg_kc_uid_bad_err">Suppression du mauvais auto-certificat pour l\'ID utilisateur %s</string>
<string name="msg_kc_uid_bad_local">Suppression du certificat d\'ID utilisateur ayant le drapeau « local »</string>
<string name="msg_kc_uid_bad_time">Suppression de l\'ID utilisateur ayant une estampille temporelle dans le futur</string>
<string name="msg_kc_uid_bad_type">Suppression du certificat d\'ID utilisateur de type inconnu (%s)</string>
<string name="msg_kc_uid_bad">Suppression du mauvais auto-certificat pour l\'ID utilisateur « %s »</string>
<string name="msg_kc_uid_dup">Suppression de l\'auto-certificat périmé pour l\'ID utilisateur « %s »</string>
<string name="msg_kc_uid_foreign">Suppression du certificat étranger d\'ID utilisateur par %s</string>
<string name="msg_kc_uid_revoke_dup">Suppression du certificat de révocation redondant pour l\'ID utilisateur « %s »</string>
<string name="msg_kc_uid_revoke_old">Suppression du certificat de révocation périmé pour l\'ID utilisateur « %s »</string>
<string name="msg_kc_uid_no_cert">Aucun auto-certificat valide trouvé pour l\'ID utilisateur %s, qui est maintenant enlevé du trousseau</string>
<!--Keyring merging log entries-->
<string name="msg_mg_public">Fusion vers le trousseau public %s</string>
<string name="msg_mg_secret">Fusion vers le trousseau secret %s</string>
<string name="msg_mg_fatal_encode">Erreur fatale lors de l\'encodage de la signature</string>
<string name="msg_mg_heterogeneous">Il a été tenté de consolider les trousseaux hétérogènes</string>
<string name="msg_mg_new_subkey">Ajout de la nouvelle sous-clef %s</string>
<string name="msg_mg_found_new">%s nouveaux certificats trouvés dans le trousseau</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modification du trousseau %s</string>
<string name="msg_mf_error_encode">Exception d\'encodage !</string>
<string name="msg_mf_error_fingerprint">L\'empreinte de clef effective ne correspond pas à celle attendue !</string>
<string name="msg_mf_error_keyid">Aucune ID de clef. Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
<string name="msg_mf_error_integrity">Erreur interne, le contrôle d\'intégrité a échoué !</string>
<string name="msg_mf_error_revoked_primary">Les IDs d\'un utilisateur révoqué ne peuvent pas être primaires !</string>
<string name="msg_mf_error_pgp">Exception interne PGP !</string>
<string name="msg_mf_error_sig">Exception de signature !</string>
<string name="msg_mf_passphrase">Changement de la phrase de passe</string>
<string name="msg_mf_subkey_change">Modification de la sous-clef %s</string>
<string name="msg_mf_subkey_missing">Une action a été tentée sur la sous-clef manquante %s !</string>
<string name="msg_mf_subkey_new">Génération d\'une nouvelle sous-clef %2$s de %1$s bit</string>
<string name="msg_mf_subkey_new_id">ID de la nouvelle sous-clef : %s</string>
<string name="msg_mf_subkey_past_expiry">La date d\'expiration ne peut pas être dans le passé !</string>
<string name="msg_mf_subkey_revoke">Révocation de la sous-clef %s</string>
<string name="msg_mf_success">Trousseau modifié avec succès</string>
<string name="msg_mf_uid_add">Ajout de l\'ID utilisateur %s</string>
<string name="msg_mf_uid_primary">Changement de l\'UID primaire en %s</string>
<string name="msg_mf_uid_revoke">Révocation de l\'ID utilisateur %s</string>
<string name="msg_mf_unlock_error">Erreur lors du déverrouillage du trousseau !</string>
<string name="msg_mf_unlock">Déverrouillage du trousseau</string>
<!--unsorted-->
<string name="section_certifier_id">Certificateur</string>
<string name="section_cert">Détails du certificat</string>
@ -473,5 +604,8 @@
<string name="title_view_cert">Voir les détails du certificat</string>
<string name="unknown_algorithm">inconnu</string>
<string name="can_sign_not">impossible de signer</string>
<string name="error_encoding">Erreur d\'encodage</string>
<string name="error_no_encrypt_subkey">Aucune sous-clef de chiffrement n\'est disponible !</string>
<string name="info_no_manual_account_creation">Ne pas créer de comptes-OpenKeychain manuellement.\nPour plus d\'informations, consultez l\'aide.</string>
<string name="contact_show_key">Montrer la clef (%s)</string>
</resources>

View File

@ -8,8 +8,9 @@
<string name="title_authentication">Frase di accesso</string>
<string name="title_create_key">Crea Chiave</string>
<string name="title_edit_key">Modifica Chiave</string>
<string name="title_wizard">Benvenuto in OpenKeychain</string>
<string name="title_preferences">Preferenze</string>
<string name="title_api_registered_apps">App Registrate</string>
<string name="title_api_registered_apps">Apps</string>
<string name="title_key_server_preference">Preferenze Server delle Chiavi</string>
<string name="title_change_passphrase">Cambia Frase Di Accesso</string>
<string name="title_set_passphrase">Imposta Frase di Accesso</string>
@ -27,6 +28,7 @@
<string name="title_certify_key">Certifica identità</string>
<string name="title_key_details">Dettagli Chiave</string>
<string name="title_help">Aiuto</string>
<string name="title_log_display">Registro</string>
<!--section-->
<string name="section_user_ids">Identità</string>
<string name="section_keys">Sottochiavi</string>
@ -70,16 +72,11 @@
<!--menu-->
<string name="menu_preferences">Impostazioni</string>
<string name="menu_help">Aiuto</string>
<string name="menu_import_from_file">Importa da file</string>
<string name="menu_import_from_qr_code">Importa da Codice QR</string>
<string name="menu_import_from_nfc">Importa tramite NFC</string>
<string name="menu_export_key">Esporta su un file</string>
<string name="menu_delete_key">Cancella chiave</string>
<string name="menu_create_key">Crea chiave</string>
<string name="menu_create_key_expert">Crea chiave (avanzato)</string>
<string name="menu_search">Cerca</string>
<string name="menu_import_from_key_server">Server delle Chiavi</string>
<string name="menu_import_from_keybase">Importa da Keybase.io</string>
<string name="menu_key_server">Server delle Chiavi...</string>
<string name="menu_update_key">Aggiorna dal server delle chiavi</string>
<string name="menu_export_key_to_server">Carica chiave nel server</string>
@ -98,6 +95,7 @@
<string name="menu_select_all">Seleziona tutto</string>
<string name="menu_add_keys">Aggiungi chiavi</string>
<string name="menu_export_all_keys">Esporta tutte le chiavi</string>
<string name="menu_advanced">Mostra informazioni avanzate</string>
<!--label-->
<string name="label_sign">Firma</string>
<string name="label_message">Messaggio</string>
@ -206,33 +204,12 @@
<string name="ask_empty_id_ok">Hai aggiunto una identità vuota, sei sicuro di voler continuare?</string>
<string name="public_key_deletetion_confirmation">Vuoi veramente eliminare la chiave pubblica \'%s\'?\nNon potrai annullare!</string>
<string name="also_export_secret_keys">Esportare anche le chiavi segrete?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">%d chiave aggiunta correttamente</item>
<item quantity="other">%d chiavi aggiunte correttamente</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">e %d chiave aggiornata.</item>
<item quantity="other">e %d chiavi aggiornate.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">%d chiave aggiunta correttamente.</item>
<item quantity="other">%d chiavi aggiunte correttamente.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">%d chiave aggiornata correttamente.</item>
<item quantity="other">%d chiavi aggiornate correttamente.</item>
</plurals>
<string name="import_error_nothing">Nessuna chiave aggiunta o aggiornata.</string>
<string name="key_exported">1 chiave esportata correttamente.</string>
<string name="keys_exported">%d chiavi esportate correttamente.</string>
<string name="no_keys_exported">Nessuna chiave esportata.</string>
<string name="key_creation_el_gamal_info">Nota: supporto sottochiavi solo per ElGamal.</string>
<string name="key_creation_weak_rsa_info">Nota: la generazione di chiavi RSA con lunghezza pari a 1024 bit o inferiore è considerata non sicura ed è disabilitata per la generazione di nuove chiavi.</string>
<string name="key_not_found">Impossibile trovare la chiave %08X.</string>
<plurals name="keys_found">
<item quantity="one">Trovata %d chiave.</item>
<item quantity="other">Trovate %d chiavi.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d chiave segreta non valida ignorata. Forse hai esportato con opzione\n--export-secret-subkeys\nAssicurati di esportare con\n--export-secret-keys\ninvece.</item>
<item quantity="other">%d chiavi private non valide ignorate. Forse hai esportato con opzione\n--export-secret-subkeys\nAssicurati di esportare con\n--export-secret-keys\ninvece.</item>
@ -272,8 +249,11 @@
<string name="error_only_files_are_supported">Flusso di dati diretto senza file corrispettivo nel filesystem non e\' supportato.</string>
<string name="error_jelly_bean_needed">Devi avere Android 4.1 per usare Android NFC Beam!</string>
<string name="error_nfc_needed">NFC non disponibile nel tuo dispositivo!</string>
<string name="error_nothing_import">Niente da importare!</string>
<string name="error_import_file_no_content">Il File non ha contenuti</string>
<string name="error_nothing_import">Nessuna chiave trovata!</string>
<string name="error_keyserver_insufficient_query">Chiave della query di ricerca troppo corta</string>
<string name="error_searching_keys">Errore irreversibile nella ricerca di chiavi sul server</string>
<string name="error_keyserver_too_many_responses">Chiave della query di ricerca ha generato troppi candidati; Si prega di perfezionare la ricerca</string>
<string name="error_import_file_no_content">File/Appunti vuoti</string>
<string name="error_generic_report_bug">Si è verificato un errore generico, si prega di creare una nuova segnalazione di errore per OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">parte del file caricato e\' un oggetto OpenPGP valido, ma non una chave OpenPGP</item>
@ -324,10 +304,10 @@
<string name="progress_verifying_integrity">verifica integrita\'...</string>
<string name="progress_deleting_securely">eliminazione sicura di \'%s\'...</string>
<!--action strings-->
<string name="hint_public_keys">Ricerca Chiavi Pubbliche</string>
<string name="hint_public_keys">Nome/Email/ID Chiave...</string>
<string name="hint_secret_keys">Cerca Chiave Privata</string>
<string name="action_share_key_with">Condividi chiave con...</string>
<string name="hint_keybase_search">Cerca Keybase.io</string>
<string name="hint_keybase_search">Nome/Keybase.io nome utente...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -353,6 +333,10 @@
<string name="help_tab_about">Info</string>
<string name="help_about_version">Versione:</string>
<!--Import-->
<string name="import_tab_keyserver">Server delle chiavi</string>
<string name="import_tab_direct">File/Appunti</string>
<string name="import_tab_qr_code">Codice QR/NFC</string>
<string name="import_tab_keybase">Keybase.io</string>
<string name="import_import">Importa chiavi selezionate</string>
<string name="import_from_clipboard">Importa dagli appunti</string>
<plurals name="import_qr_code_missing">
@ -366,8 +350,14 @@
<string name="import_qr_scan_button">Scansiona il Codice QR con \'Barcode Scanner\'</string>
<string name="import_nfc_text">Per ricevere le chiavi via NFC, il dispositivo deve essere sbloccato.</string>
<string name="import_nfc_help_button">Aiuto</string>
<string name="import_qr_code_button">Scansione Codice QR</string>
<string name="import_clipboard_button">Ottieni chiave dagli appunti</string>
<string name="import_keybase_button">Ottieni chiave da Keybase.io</string>
<!--Import result toast-->
<string name="import_view_log">Mostra registro</string>
<string name="import_error_nothing">Niente da importare</string>
<string name="import_error">Errore di importazione chiavi!</string>
<string name="import_with_warnings">, con avvisi</string>
<!--Intent labels-->
<string name="intent_decrypt_file">Decodifica File con OpenKeychain</string>
<string name="intent_import_key">Importa Chiave con OpenKeychain</string>
@ -431,7 +421,7 @@
<string name="nav_encrypt">Firma e Codifica</string>
<string name="nav_decrypt">Decodifica e Verifica</string>
<string name="nav_import">Importa Chiavi</string>
<string name="nav_apps">App Registrate</string>
<string name="nav_apps">Apps</string>
<string name="drawer_open">Apri drawer di navigazione</string>
<string name="drawer_close">Chiudi drawer di navigazione</string>
<string name="edit">Modifica</string>
@ -452,6 +442,125 @@
<string name="cert_verify_failed">fallito!</string>
<string name="cert_verify_error">errore!</string>
<string name="cert_verify_unavailable">chiave non disponibile</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Applicazione inserimento operazioni in batch.</string>
<string name="msg_ip_bad_type_secret">Ho cercato di importare portachiavi privato come pubblico. Questo è un bug, per cortesia inviateci un rapporto!</string>
<string name="msg_ip_delete_old_fail">Nessuna vecchia chiave cancellata (stai creando una nuova?)</string>
<string name="msg_ip_delete_old_ok">Cancellate vecchie chiavi dal database</string>
<string name="msg_ip_encode_fail">Operazione fallita a causa di un errore di codifica</string>
<string name="msg_ip_fail_io_exc">Operazione fallita a causa di un errore di i/o</string>
<string name="msg_ip_fail_op_exc">Operazione fallita a causa di un errore della banca dati</string>
<string name="msg_ip_fail_remote_ex">Operazione fallita a causa di un errore interno</string>
<string name="msg_ip">Importazione portachiavi pubblico %s</string>
<string name="msg_ip_insert_keyring">Codifica dati del portachiavi</string>
<string name="msg_ip_insert_keys">Elaborazione chiavi</string>
<string name="msg_ip_prepare">Preparazione operazioni banca dati</string>
<string name="msg_ip_master">Elaborazione chiave principale %s</string>
<string name="msg_ip_master_expired">Portachiavi scaduto il %s</string>
<string name="msg_ip_master_expires">Il portachiavi scade il %s</string>
<string name="msg_ip_master_flags_ces">Caratteristiche chiave principale: certifica, codifica, firma</string>
<string name="msg_ip_master_flags_cex">Caratteristiche chiave principale: certifica, codifica</string>
<string name="msg_ip_master_flags_cxs">Caratteristiche chiave principale: certifica, firma</string>
<string name="msg_ip_master_flags_xes">Caratteristiche chiave principale: codifica, firma</string>
<string name="msg_ip_master_flags_cxx">Caratteristiche chiave principale: certifica</string>
<string name="msg_ip_master_flags_xex">Caratteristiche chiave principale: codifica</string>
<string name="msg_ip_master_flags_xxs">Caratteristiche chiave principale: firma</string>
<string name="msg_ip_master_flags_xxx">Caratteristiche chiave principale: nessuna</string>
<string name="msg_ip_subkey">Elaborazione sottochiave %s</string>
<string name="msg_ip_subkey_expired">Sottochiave scaduta il %s</string>
<string name="msg_ip_subkey_expires">La sottochiave scade il %s</string>
<string name="msg_ip_subkey_flags_ces">Caratteristiche sottochiave: certifica, codifica, firma</string>
<string name="msg_ip_subkey_flags_cex">Caratteristiche sottochiave: certifica, codifica</string>
<string name="msg_ip_subkey_flags_cxs">Caratteristiche sottochiave: certifica, firma</string>
<string name="msg_ip_subkey_flags_xes">Caratteristiche sottochiave: codifica, firma</string>
<string name="msg_ip_subkey_flags_cxx">Caratteristiche sottochiave: certifica</string>
<string name="msg_ip_subkey_flags_xex">Caratteristiche sottochiave: codifica</string>
<string name="msg_ip_subkey_flags_xxs">Caratteristiche sottochiave: firma</string>
<string name="msg_ip_subkey_flags_xxx">Caratteristiche sottochiave: nessuna</string>
<string name="msg_ip_success">Portachiavi pubblico importato con successo</string>
<string name="msg_ip_success_identical">Il portachiavi non contiene nuovi dati, nulla da eseguire</string>
<string name="msg_ip_reinsert_secret">Reinserimento chiave segreta</string>
<string name="msg_ip_uid_cert_bad">Riscontrato certificato sbagliato!</string>
<string name="msg_ip_uid_cert_error">Errore elaborazione certificato!</string>
<string name="msg_ip_uid_cert_good">ID utente certificato da %1$s (%2$s)</string>
<string name="msg_ip_uid_reorder">Riordinamento ID utenti</string>
<string name="msg_ip_uid_processing">Elaborazione ID utente %s</string>
<string name="msg_ip_uid_revoked">ID utente revocato</string>
<string name="msg_is_bad_type_public">Ho cercato di importare portachiavi pubblico come privato. Questo è un bug, per cortesia inviateci un rapporto!</string>
<!--Import Secret log entries-->
<string name="msg_is">Importazione chiave segreta %s</string>
<string name="msg_is_db_exception">Errore Banca Dati!</string>
<string name="msg_is_importing_subkeys">Elaborazione sottochiavi segrete</string>
<string name="msg_is_io_exc">Errore codifica portachiavi</string>
<string name="msg_is_pubring_generate">Generazione portachiavi pubblico da portachiavi privato</string>
<string name="msg_is_subkey_nonexistent">Sottochiave %s non disponibile nella chiave pubblica</string>
<string name="msg_is_subkey_ok">%s marcate come disponibili</string>
<string name="msg_is_subkey_stripped">%s marcate come ripulite</string>
<string name="msg_is_success_identical">Il portachiavi non contiene nuovi dati, nulla da eseguire</string>
<string name="msg_is_success">Portachiavi segreto importato con successo</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_public">Canonicalizzazione portachiavi pubblico %s</string>
<string name="msg_kc_secret">Canonicalizzazione portachiavi segreto %s</string>
<string name="msg_kc_fatal_no_uid">Canonicalizzazione portachiavi fallita: il portachiavi non ha ID utenti validi</string>
<string name="msg_kc_master">Elaborazione chiave principale</string>
<string name="msg_kc_revoke_bad_err">Rimozione di certificato di revoca del portachiavi corrotto</string>
<string name="msg_kc_revoke_bad_local">Rimozione certificato di revoca del portachiavi con caratteristica \"locale\"</string>
<string name="msg_kc_revoke_bad_time">Rimozione certificato di revoca del portachiavi con marca temporale futura</string>
<string name="msg_kc_revoke_bad_type">Rimozione certificato della chiave principale di tipo sconosciuto (%s)</string>
<string name="msg_kc_revoke_bad">Rimozione certificato di revoca del portachiavi corrotto</string>
<string name="msg_kc_revoke_dup">Rimozione certificato di revoca del portachiavi ridondante</string>
<string name="msg_kc_sub">Elaborazione sottochiave %s</string>
<string name="msg_kc_sub_bad">Rimozione certificato vincolante di sottochiave non valido</string>
<string name="msg_kc_sub_bad_err">Rimozione certificato vincolante di sottochiave corrotto</string>
<string name="msg_kc_sub_bad_local">Rimozione certificato di sottochiave con caratteristica \"locale\"</string>
<string name="msg_kc_sub_bad_keyid">ID emittente vincolante della sottochiave non corrispondente</string>
<string name="msg_kc_sub_bad_time">Rimozione certificato vincolante della sottochiave con marca temporale futura</string>
<string name="msg_kc_sub_bad_type">Tipo di certificato della sottochiave sconosciuto: %s</string>
<string name="msg_kc_sub_dup">Rimozione certificato vincolante di sottochiave ridondante</string>
<string name="msg_kc_sub_primary_bad">Rimozione certificato vincolante della sottochiave a causa di certificato vincolante primario non valido</string>
<string name="msg_kc_sub_primary_bad_err">Rimozione certificato vincolante della sottochiave a causa di certificato vincolante primario corrotto</string>
<string name="msg_kc_sub_primary_none">Rimozione certificato vincolante della sottochiave a causa di certificato vincolante primario mancante</string>
<string name="msg_kc_sub_no_cert">Certificato valido non trovato per %s, rimozione dal portachiavi</string>
<string name="msg_kc_sub_revoke_bad_err">Rimozione certificato di revoca corrotto della sottochiave</string>
<string name="msg_kc_sub_revoke_bad">Rimozione certificato di revoca corrotto della sottochiave</string>
<string name="msg_kc_sub_revoke_dup">Rimozione certificato di revoca ridondante della sottochiave</string>
<string name="msg_kc_success">Canonicalizzazione del portachiavi avvenuta con successo, nessuna modifica</string>
<string name="msg_kc_success_bad_and_red">Canonicalizzazione portachiavi con successo, rimossi %1$s certificati errati e %2$s certificati ridondanti</string>
<string name="msg_kc_uid_bad_err">Rimozione autocertificazione corrotta per ID utente %s</string>
<string name="msg_kc_uid_bad_local">Rimozione certificato ID utente con caratteristica \"locale\"</string>
<string name="msg_kc_uid_bad_time">Rimozione ID utente con marca temporale futura</string>
<string name="msg_kc_uid_bad_type">Rimozione certificato ID utente di tipo sconosciuto (%s)</string>
<string name="msg_kc_uid_bad">Rimozione autocertificazione corrotta per ID utente \"%s\"</string>
<string name="msg_kc_uid_dup">Rimozione autocertificazione scaduta per ID utente \"%s\"</string>
<string name="msg_kc_uid_foreign">Rimozione certificato ID utente estraneo di %s</string>
<string name="msg_kc_uid_revoke_dup">Rimozione certificato di revoca ridondante per ID utente \"%s\"</string>
<string name="msg_kc_uid_revoke_old">Rimozione certificato di revoca scaduto per ID utente \"%s\"</string>
<string name="msg_kc_uid_no_cert">Nessuna autocertificazione valida trovata per ID utente %s, rimozione dal portachiavi</string>
<!--Keyring merging log entries-->
<string name="msg_mg_public">Fusione nel portachiavi pubblico %s</string>
<string name="msg_mg_secret">Fusione nel portachiavi privato %s</string>
<string name="msg_mg_fatal_encode">Errore fatale nella codifica della firma</string>
<string name="msg_mg_heterogeneous">Tentativo di consolidare portachiavi eterogenei</string>
<string name="msg_mg_new_subkey">Aggiunta nuova sottochiave %s</string>
<string name="msg_mg_found_new">Trovati %s nuovi certificati nel portachiavi</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modifica del portachiavi %s</string>
<string name="msg_mf_error_encode">Eccezione di codifica!</string>
<string name="msg_mf_error_pgp">Eccezione interna di PGP!</string>
<string name="msg_mf_error_sig">Eccezione di firma!</string>
<string name="msg_mf_passphrase">Cambio frase di accesso</string>
<string name="msg_mf_subkey_change">Modifica sottochiave %s</string>
<string name="msg_mf_subkey_missing">Tentativo di operare su sottochiave mancante %s!</string>
<string name="msg_mf_subkey_new">Generazione nuovi %1$s bit %2$s sottochiave</string>
<string name="msg_mf_subkey_new_id">Nuovo ID sottochiave: %s</string>
<string name="msg_mf_subkey_past_expiry">La data di scadenza non può essere passata!</string>
<string name="msg_mf_subkey_revoke">Revoca sottochiave %s</string>
<string name="msg_mf_success">Portachiavi modificato con successo</string>
<string name="msg_mf_uid_add">Aggiunta id utente %s</string>
<string name="msg_mf_uid_primary">Cambio UID primario in %s</string>
<string name="msg_mf_uid_revoke">Revoca ID utente %s</string>
<string name="msg_mf_unlock_error">Errore di apertura portachiavi!</string>
<string name="msg_mf_unlock">Apertura portachiavi</string>
<!--unsorted-->
<string name="section_certifier_id">Certificatore</string>
<string name="section_cert">Dettagli Certificato</string>
@ -470,5 +579,8 @@
<string name="title_view_cert">Visualizza Dettagli Certificati</string>
<string name="unknown_algorithm">sconosciuto</string>
<string name="can_sign_not">non può firmare</string>
<string name="error_encoding">Errore di codifica</string>
<string name="error_no_encrypt_subkey">Nessuna sottochiave di codifica disponibile!</string>
<string name="info_no_manual_account_creation">Non creare account OpenKeychain manualmente\nPer ulteriori informazioni, vedere la Guida.</string>
<string name="contact_show_key">Mostra chiave (%s)</string>
</resources>

View File

@ -8,8 +8,9 @@
<string name="title_authentication">パスフレーズ</string>
<string name="title_create_key">鍵の生成</string>
<string name="title_edit_key">鍵の編集</string>
<string name="title_wizard">OpenKeychainへようこそ</string>
<string name="title_preferences">設定</string>
<string name="title_api_registered_apps">登録済みのアプリケーション</string>
<string name="title_api_registered_apps">アプリ</string>
<string name="title_key_server_preference">鍵サーバ設定</string>
<string name="title_change_passphrase">パスフレーズの変更</string>
<string name="title_set_passphrase">パスフレーズの設定</string>
@ -27,6 +28,7 @@
<string name="title_certify_key">ユーザID検証</string>
<string name="title_key_details">鍵の概要</string>
<string name="title_help">ヘルプ</string>
<string name="title_log_display">ログ</string>
<!--section-->
<string name="section_user_ids">ユーザID</string>
<string name="section_keys">副鍵</string>
@ -70,16 +72,11 @@
<!--menu-->
<string name="menu_preferences">設定</string>
<string name="menu_help">ヘルプ</string>
<string name="menu_import_from_file">ファイルからインポート</string>
<string name="menu_import_from_qr_code">QRコードからインポート</string>
<string name="menu_import_from_nfc">NFCからインポート</string>
<string name="menu_export_key">ファイルへのエクスポート</string>
<string name="menu_delete_key">鍵の削除</string>
<string name="menu_create_key">鍵の生成</string>
<string name="menu_create_key_expert">鍵の生成(上級)</string>
<string name="menu_search">検索</string>
<string name="menu_import_from_key_server">鍵サーバ</string>
<string name="menu_import_from_keybase">Keybase.ioからのインポート</string>
<string name="menu_key_server">鍵サーバ...</string>
<string name="menu_update_key">鍵サーバからの更新</string>
<string name="menu_export_key_to_server">鍵サーバへのアップロード</string>
@ -98,6 +95,7 @@
<string name="menu_select_all">すべて選択</string>
<string name="menu_add_keys">鍵の追加</string>
<string name="menu_export_all_keys">すべての鍵のエクスポート</string>
<string name="menu_advanced">詳細情報を表示</string>
<!--label-->
<string name="label_sign">署名</string>
<string name="label_message">メッセージ</string>
@ -203,28 +201,12 @@
<string name="ask_empty_id_ok">あなたは空のユーザIDを追加しました、このまま続けますか?</string>
<string name="public_key_deletetion_confirmation">公開鍵\'%s\'を本当に削除してもよいですか?\nこれは元に戻せません!</string>
<string name="also_export_secret_keys">秘密鍵もエクスポートしますか?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="other">%d の鍵を追加しました</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="other">そして %d の鍵をアップロードしました。</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="other">%d の鍵を追加しました。</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="other">%d の鍵をアップロードしました。</item>
</plurals>
<string name="import_error_nothing">鍵の追加もしくは更新はありませんでした。</string>
<string name="key_exported">1つの鍵をエクスポートしました。</string>
<string name="keys_exported">%d の鍵をエクスポートしました。</string>
<string name="no_keys_exported">鍵をエクスポートしていません。</string>
<string name="key_creation_el_gamal_info">ノート: 副鍵はElGamalでのみサポートされます。</string>
<string name="key_creation_weak_rsa_info">付記: 長さ1024bitかそれ以下で生成されたRSA鍵は安全とはみなされず、新な鍵の生成は無効にされています。</string>
<string name="key_not_found">鍵 %08X は見付かりませんでした。</string>
<plurals name="keys_found">
<item quantity="other">%d の鍵を発見。</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="other">%d の問題ある鍵を無視しました。 おそらく次のオプションでエクスポートしています\n --export-secret-subkeys\n代りに次のオプションでエクスポートしてください。\n --export-secret-keys</item>
</plurals>
@ -263,11 +245,11 @@
<string name="error_only_files_are_supported">ファイルシステムに存在するファイルではないバイナリデータはサポートされません。</string>
<string name="error_jelly_bean_needed">Android NFC Beam機能を使うにはAndroid 4.1 が必要です!</string>
<string name="error_nfc_needed">あなたのデバイスにはNFCが存在しません!</string>
<string name="error_nothing_import">インポートするものがありません!</string>
<string name="error_nothing_import">鍵が見当りません!</string>
<string name="error_keyserver_insufficient_query">鍵検索のクエリが短かすぎます</string>
<string name="error_searching_keys">サーバでの鍵の検索が回復不可能なエラーになりました</string>
<string name="error_keyserver_too_many_responses">鍵検索のクエリが沢山の候補を返しました; クエリを精密化してください</string>
<string name="error_import_file_no_content">ファイルに内容がありません</string>
<string name="error_import_file_no_content">ファイル/クリップボードが空です</string>
<string name="error_generic_report_bug">一般エラーが発生しました、この新しいバグの情報をOpenKeychainプロジェクトに送ってください</string>
<plurals name="error_import_non_pgp_part">
<item quantity="other">読み込んだファイルのOpenPGPオブジェクト部分は正しいですが、OpenPGPの鍵ではありません</item>
@ -315,10 +297,10 @@
<string name="progress_verifying_integrity">完全性の検証中...</string>
<string name="progress_deleting_securely">\'%s\' を完全に削除中…</string>
<!--action strings-->
<string name="hint_public_keys">公開鍵の検索</string>
<string name="hint_public_keys">名前/メール/鍵ID...</string>
<string name="hint_secret_keys">秘密鍵の検索</string>
<string name="action_share_key_with">...で鍵の共有</string>
<string name="hint_keybase_search">Keybase.ioでの検索</string>
<string name="hint_keybase_search">名前/Keybase.io名...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -344,6 +326,10 @@
<string name="help_tab_about">これについて</string>
<string name="help_about_version">バージョン:</string>
<!--Import-->
<string name="import_tab_keyserver">鍵サーバ</string>
<string name="import_tab_direct">ファイル/クリップボード</string>
<string name="import_tab_qr_code">QRコード/NFC</string>
<string name="import_tab_keybase">Keybase.io</string>
<string name="import_import">選択した鍵のインポート</string>
<string name="import_from_clipboard">クリップボードからインポート</string>
<plurals name="import_qr_code_missing">
@ -356,8 +342,26 @@
<string name="import_qr_scan_button">\'バーコードスキャナー\'でQRコードをスキャンする</string>
<string name="import_nfc_text">NFCで鍵を受信しました、デバイスのロックを解除する必要があります。</string>
<string name="import_nfc_help_button">ヘルプ</string>
<string name="import_qr_code_button">QCコードのスキャン...</string>
<string name="import_clipboard_button">クリップボードから鍵を取得</string>
<string name="import_keybase_button">Keybase.ioから鍵を取得</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="other">%1$d の鍵のインポートに成功</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="other">そして%1$d の鍵%2$s をアップデート。</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="other">%1$d の鍵%2$sのインポートに成功。</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="other">%1$d の鍵%2$sのアップデートに成功。</item>
</plurals>
<string name="import_view_log">ログを見る</string>
<string name="import_error_nothing">インポートするものがありません。</string>
<string name="import_error">鍵のインポートのエラー!</string>
<string name="import_with_warnings">、とワーニング</string>
<!--Intent labels-->
<string name="intent_decrypt_file">OpenKeychainでファイルを復号化</string>
<string name="intent_import_key">OpenKeychainに鍵をインポート</string>
@ -420,7 +424,7 @@
<string name="nav_encrypt">署名と暗号化</string>
<string name="nav_decrypt">復号化と検証</string>
<string name="nav_import">鍵のインポート</string>
<string name="nav_apps">登録済みのアプリ</string>
<string name="nav_apps">アプリ</string>
<string name="drawer_open">ナビゲーションドロワーを開く</string>
<string name="drawer_close">ナビゲーションドロワーを閉める</string>
<string name="edit">編集</string>
@ -441,6 +445,142 @@
<string name="cert_verify_failed">失敗!</string>
<string name="cert_verify_error">エラー!</string>
<string name="cert_verify_unavailable">鍵がありません</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">連続挿入処理を適用する。</string>
<string name="msg_ip_bad_type_secret">秘密鍵の鍵輪を公開鍵としてインポートを試行しました。これはバグで、ファイルをレポートしてください!</string>
<string name="msg_ip_delete_old_fail">削除された古い鍵はありません (新しく作りますか?)</string>
<string name="msg_ip_delete_old_ok">データベースから古い鍵を削除しました</string>
<string name="msg_ip_encode_fail">エンコードエラーにより操作が失敗しました</string>
<string name="msg_ip_fail_io_exc">I/Oエラーにより操作が失敗しました</string>
<string name="msg_ip_fail_op_exc">データベースエラーにより操作が失敗しました</string>
<string name="msg_ip_fail_remote_ex">内部エラーにより操作が失敗しました</string>
<string name="msg_ip">公開鍵の鍵輪 %s をインポート</string>
<string name="msg_ip_insert_keyring">鍵輪データのエンコード中</string>
<string name="msg_ip_insert_keys">鍵の解析中</string>
<string name="msg_ip_prepare">データベース操作の準備</string>
<string name="msg_ip_master">主鍵処理中 %s</string>
<string name="msg_ip_master_expired">%s が鍵輪の期限切れ</string>
<string name="msg_ip_master_expires">%s に鍵輪が期限切れ</string>
<string name="msg_ip_master_flags_ces">主鍵のフラグ: 検証、暗号化、署名</string>
<string name="msg_ip_master_flags_cex">主鍵のフラグ: 検証、暗号化</string>
<string name="msg_ip_master_flags_cxs">主鍵のフラグ: 検証、署名</string>
<string name="msg_ip_master_flags_xes">主鍵のフラグ: 暗号化、署名</string>
<string name="msg_ip_master_flags_cxx">主鍵のフラグ: 検証</string>
<string name="msg_ip_master_flags_xex">主鍵のフラグ: 暗号化</string>
<string name="msg_ip_master_flags_xxs">主鍵のフラグ: 署名</string>
<string name="msg_ip_master_flags_xxx">主鍵のフラグ: なし</string>
<string name="msg_ip_subkey">副鍵 %s の処理中</string>
<string name="msg_ip_subkey_expired">%s が副鍵の期限切れ</string>
<string name="msg_ip_subkey_expires">%s に副鍵が期限切れ</string>
<string name="msg_ip_subkey_flags_ces">副鍵のフラグ: 検証、暗号化、署名</string>
<string name="msg_ip_subkey_flags_cex">副鍵のフラグ: 検証、暗号化</string>
<string name="msg_ip_subkey_flags_cxs">副鍵のフラグ: 検証、署名</string>
<string name="msg_ip_subkey_flags_xes">副鍵のフラグ: 暗号化、署名</string>
<string name="msg_ip_subkey_flags_cxx">副鍵のフラグ: 検証</string>
<string name="msg_ip_subkey_flags_xex">副鍵のフラグ: 暗号化</string>
<string name="msg_ip_subkey_flags_xxs">副鍵のフラグ: 署名</string>
<string name="msg_ip_subkey_flags_xxx">副鍵のフラグ: なし</string>
<string name="msg_ip_success">公開鍵の鍵輪のインポートに成功</string>
<string name="msg_ip_success_identical">鍵輪にデータがないため、なにもしません</string>
<string name="msg_ip_reinsert_secret">秘密鍵を再挿入中</string>
<string name="msg_ip_uid_cert_bad">問題のある検証と遭遇しました!</string>
<string name="msg_ip_uid_cert_error">検証の処理中にエラーしました!</string>
<string name="msg_ip_uid_cert_good">ユーザIDは %1$s (%2$s) によって検証されました</string>
<plurals name="msg_ip_uid_certs_unknown">
<item quantity="other">不明な公開鍵から %s の検証を無視</item>
</plurals>
<string name="msg_ip_uid_classifying_zero">ユーザIDを検証 (信頼された鍵がありません)</string>
<plurals name="msg_ip_uid_classifying">
<item quantity="other">ユーザIDを検証 ( %s の信頼された鍵を使いました)</item>
</plurals>
<string name="msg_ip_uid_reorder">ユーザIDの並べ直し</string>
<string name="msg_ip_uid_processing">ユーザID %s の処理中</string>
<string name="msg_ip_uid_revoked">ユーザIDは破棄されました</string>
<string name="msg_is_bad_type_public">公開鍵の鍵輪を秘密鍵としてインポートを試行しました。これはバグで、ファイルをレポートしてください\"</string>
<!--Import Secret log entries-->
<string name="msg_is">秘密鍵 %s のインポート中</string>
<string name="msg_is_db_exception">データベースエラー!</string>
<string name="msg_is_importing_subkeys">秘密鍵の副鍵の処理中</string>
<string name="msg_is_io_exc">鍵輪のエンコードエラー</string>
<string name="msg_is_pubring_generate">秘密鍵の鍵輪から公開鍵の鍵輪を生成中</string>
<string name="msg_is_subkey_nonexistent">公開鍵の中の副鍵 %s が利用不可能</string>
<string name="msg_is_subkey_ok"> %s を利用可能としてマーク</string>
<string name="msg_is_subkey_stripped">%s をストリップとしてマーク</string>
<string name="msg_is_success_identical">鍵輪にデータがないため、なにもしません</string>
<string name="msg_is_success">秘密鍵の鍵輪のインポートに成功</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_public">公開鍵の鍵輪 %s の正規化中</string>
<string name="msg_kc_secret">秘密鍵の鍵輪 %s の正規化中</string>
<string name="msg_kc_fatal_no_uid">鍵輪の正規化に失敗: 鍵輪が正しいユーザIDを含んでいませんでした</string>
<string name="msg_kc_master">主鍵処理中</string>
<string name="msg_kc_revoke_bad_err">問題のある鍵輪の破棄証明を破棄中</string>
<string name="msg_kc_revoke_bad_local">鍵輪のローカルフラグ付き破棄証明を破棄中</string>
<string name="msg_kc_revoke_bad_time">鍵輪の未来にタイムスタンプがある破棄証明を破棄中</string>
<string name="msg_kc_revoke_bad_type">問題のある主鍵の不明な型 (%s) の証明を破棄中</string>
<string name="msg_kc_revoke_bad">問題のある鍵輪の破棄証明を破棄中</string>
<string name="msg_kc_revoke_dup">重複している鍵輪の破棄証明を破棄中</string>
<string name="msg_kc_sub">副鍵 %s の処理中</string>
<string name="msg_kc_sub_bad">証明が付随する不正な副鍵を破棄中</string>
<string name="msg_kc_sub_bad_err">証明が付随する問題のある副鍵を破棄中</string>
<string name="msg_kc_sub_bad_local">ローカルフラグ付きの証明が付随する副鍵を破棄中</string>
<string name="msg_kc_sub_bad_keyid">副鍵の発行者のIDと付随するIDがミスマッチ</string>
<string name="msg_kc_sub_bad_time">未来にタイムスタンプがある証明が付随する副鍵を破棄中</string>
<string name="msg_kc_sub_bad_type">不明な検証のタイプ: %sの副鍵</string>
<string name="msg_kc_sub_dup">証明が付随する重複する副鍵を破棄中</string>
<string name="msg_kc_sub_primary_bad">付随する主たる証明が正しくない証明が付随する副鍵を破棄中</string>
<string name="msg_kc_sub_primary_bad_err">付随する主たる証明に問題がある証明が付随する副鍵を破棄中</string>
<string name="msg_kc_sub_primary_none">付随する主たる証明が失なわれている証明が付随する副鍵を破棄中</string>
<string name="msg_kc_sub_no_cert">%s から正常な検証が見付かりません、鍵輪から除外します</string>
<string name="msg_kc_sub_revoke_bad_err">問題のある副鍵の破棄証明を破棄中</string>
<string name="msg_kc_sub_revoke_bad">問題のある副鍵の破棄証明を破棄中</string>
<string name="msg_kc_sub_revoke_dup">重複している副鍵の破棄証明を破棄中</string>
<string name="msg_kc_success">鍵輪の正規化に成功、変更なし</string>
<plurals name="msg_kc_success_bad">
<item quantity="other">鍵輪の認可に成功、 %d 個のエラーのある証明を除去</item>
</plurals>
<string name="msg_kc_success_bad_and_red">鍵輪の認可に成功、 %1$s なエラーのある証明と %2$s の重複を除去</string>
<plurals name="msg_kc_success_redundant">
<item quantity="other">鍵輪の認可に成功、 %d 個の重複を除去</item>
</plurals>
<string name="msg_kc_uid_bad_err">ユーザID %s による問題のある自己検証を破棄中</string>
<string name="msg_kc_uid_bad_local">ローカルフラグ付きのユーザID検証を破棄中</string>
<string name="msg_kc_uid_bad_time">未来にタイムスタンプがあるユーザIDを破棄中</string>
<string name="msg_kc_uid_bad_type">不明な型 (%s) でのユーザID検証を破棄中</string>
<string name="msg_kc_uid_bad">ユーザID \"%s\" による問題のある自己検証を破棄中</string>
<string name="msg_kc_uid_dup">期限の切れたユーザID \"%s\" による自己検証を破棄中</string>
<string name="msg_kc_uid_foreign">%s によって検証されている外部ユーザIDを破棄中</string>
<string name="msg_kc_uid_revoke_dup">ユーザID \"%s\" による重複した破棄証明を破棄中</string>
<string name="msg_kc_uid_revoke_old">ユーザID \"%s\" による期限切れ破棄証明を破棄中</string>
<string name="msg_kc_uid_no_cert">ユーザID %s の正常な自己署名が見付かりませんでした、鍵輪から除去しました</string>
<!--Keyring merging log entries-->
<string name="msg_mg_public">公開鍵の鍵輪 %s にマージ中</string>
<string name="msg_mg_secret">秘密鍵の鍵輪 %s にマージ中</string>
<string name="msg_mg_fatal_encode">署名のエンコードでの致命的なエラー</string>
<string name="msg_mg_heterogeneous">種類の異なる鍵輪を統合しようとした</string>
<string name="msg_mg_new_subkey">新しい副鍵 %s を追加中</string>
<string name="msg_mg_found_new">鍵輪に新しい検証を %s 発見</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">鍵輪 %s を変更中</string>
<string name="msg_mf_error_encode">エンコード例外!</string>
<string name="msg_mf_error_fingerprint">現実の鍵指紋が予想と合致しませんでした!</string>
<string name="msg_mf_error_keyid">鍵IDがない。 これはプログラミングのエラーで、バグレポートの提出をお願いします!</string>
<string name="msg_mf_error_integrity">内部エラー、完全性チェックが失敗!</string>
<string name="msg_mf_error_revoked_primary">主ユーザIDの破棄はできません!</string>
<string name="msg_mf_error_pgp">PGP内部例外!</string>
<string name="msg_mf_error_sig">署名例外!</string>
<string name="msg_mf_passphrase">パスフレーズの変更中</string>
<string name="msg_mf_subkey_change">副鍵 %s を変更中</string>
<string name="msg_mf_subkey_missing">遺失した副鍵 %s の操作をしようとした!</string>
<string name="msg_mf_subkey_new">新しい %1$s ビットの %2$s 副鍵の生成中</string>
<string name="msg_mf_subkey_new_id">新しい副鍵 ID: %s</string>
<string name="msg_mf_subkey_past_expiry">期限切れ日を過去にはできません!</string>
<string name="msg_mf_subkey_revoke">副鍵 %s を破棄中</string>
<string name="msg_mf_success">鍵輪の変更に成功</string>
<string name="msg_mf_uid_add">ユーザID %s を追加中</string>
<string name="msg_mf_uid_primary">主UIDを %s に変更中</string>
<string name="msg_mf_uid_revoke">ユーザID %s を破棄中</string>
<string name="msg_mf_unlock_error">鍵輪のロック解除エラー!</string>
<string name="msg_mf_unlock">鍵輪のロック解除中</string>
<!--unsorted-->
<string name="section_certifier_id">検証者</string>
<string name="section_cert">証明の詳細</string>
@ -452,12 +592,15 @@
<string name="label_verify_status">検証ステータス</string>
<string name="label_cert_type">種別</string>
<string name="error_key_not_found">鍵が見当りません!</string>
<string name="error_key_processing">鍵処理のエラー!</string>
<string name="error_key_processing">鍵処理のエラー!</string>
<string name="no_subkey">副鍵がありません</string>
<string name="key_stripped">スリム化</string>
<string name="secret_cannot_multiple">秘密鍵は個別にしか削除できません!</string>
<string name="title_view_cert">証明の詳細を見る</string>
<string name="unknown_algorithm">不明</string>
<string name="can_sign_not">署名不可</string>
<string name="error_encoding">エンコードエラー</string>
<string name="error_no_encrypt_subkey">暗号化の副鍵がありません!</string>
<string name="info_no_manual_account_creation">OpenKeychainのアカウントを手動では生成できません.\nより詳細は、ヘルプを参照のこと。</string>
<string name="contact_show_key">鍵 (%s) を表示</string>
</resources>

View File

@ -19,6 +19,7 @@
<!--compression-->
<!--Help-->
<!--Import-->
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<!--Share-->
@ -27,5 +28,10 @@
<!--Navigation Drawer-->
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -9,7 +9,6 @@
<string name="title_create_key">Sleutel aanmaken</string>
<string name="title_edit_key">Sleutel bewerken</string>
<string name="title_preferences">Instellingen</string>
<string name="title_api_registered_apps">Geregistreerde apps</string>
<string name="title_key_server_preference">Sleutelserver Voorkeur</string>
<string name="title_change_passphrase">Wachtwoord wijzigen</string>
<string name="title_set_passphrase">Wachtwoord instellen</string>
@ -70,16 +69,11 @@
<!--menu-->
<string name="menu_preferences">Instellingen</string>
<string name="menu_help">Help</string>
<string name="menu_import_from_file">Importeren uit bestand</string>
<string name="menu_import_from_qr_code">Importeren met QR-code</string>
<string name="menu_import_from_nfc">Importeren met NFC</string>
<string name="menu_export_key">Exporteren naar bestand</string>
<string name="menu_delete_key">Sleutel verwijderen</string>
<string name="menu_create_key">Sleutel aanmaken</string>
<string name="menu_create_key_expert">Sleutel aanmaken (expert)</string>
<string name="menu_search">Zoeken</string>
<string name="menu_import_from_key_server">Sleutelserver</string>
<string name="menu_import_from_keybase">Importeren uit Keybase.io</string>
<string name="menu_key_server">Sleutelserver...</string>
<string name="menu_update_key">Update van sleutelserver</string>
<string name="menu_export_key_to_server">Upload naar sleutelserver</string>
@ -206,33 +200,12 @@
<string name="ask_empty_id_ok">U heeft een lege identiteit toegevoegd, weet u zeker dat u wilt doorgaan?</string>
<string name="public_key_deletetion_confirmation">Wilt u echt de publieke sleutel \'%s\' verwijderen?\nDit kunt u niet ongedaan maken!</string>
<string name="also_export_secret_keys">Ook geheime sleutels exporteren?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Succesvol %d sleutel toegevoegd</item>
<item quantity="other">Succesvol %d sleutels toegevoegd</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">en %d sleutel bijgewerkt.</item>
<item quantity="other">en %d sleutels bijgewerkt.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">Succesvol %d sleutel toegevoegd.</item>
<item quantity="other">Succesvol %d sleutels toegevoegd.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">Succesvol %d sleutel bijgewerkt.</item>
<item quantity="other">Succesvol %d sleutels bijgewerkt.</item>
</plurals>
<string name="import_error_nothing">Geen sleutels toegevoegd of bijgewerkt.</string>
<string name="key_exported">1 sleutel succesvol geëxporteerd.</string>
<string name="keys_exported">Succesvol %d sleutels geëxporteerd.</string>
<string name="no_keys_exported">Geen sleutels geëxporteerd.</string>
<string name="key_creation_el_gamal_info">Opmerking: alleen subsleutels ondersteunen ElGamal.</string>
<string name="key_creation_weak_rsa_info">Opmerking: RSA sleutel met lengte 1024-bit en minder genereren wordt als onveilig beschouwd en is uitgeschakeld voor het genereren van nieuwe sleutels.</string>
<string name="key_not_found">Kan de sleutel %08X niet vinden.</string>
<plurals name="keys_found">
<item quantity="one">%d sleutel gevonden.</item>
<item quantity="other">%d sleutels gevonden.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d slechte geheime sleutel genegeerd. Misschien heeft u geëxporteerd met de optie\n --export-secret-subkeys\nZorg ervoor dat u in plaats daarvan met\n --export-secret-keys\nexporteert.</item>
<item quantity="other">%d slechte geheime sleutels genegeerd. Misschien heeft u geëxporteerd met de optie\n --export-secret-subkeys\nZorg ervoor dat u in plaats daarvan met\n --export-secret-keys\nexporteert.</item>
@ -272,8 +245,6 @@
<string name="error_only_files_are_supported">Directe binaire data zonder eigenlijke bestand in bestandssysteem wordt niet ondersteund.</string>
<string name="error_jelly_bean_needed">U heeft minstens Android 4.1 nodig om Androids NFC Beam eigenschap te gebruiken!</string>
<string name="error_nfc_needed">Uw apparaat biedt geen ondersteuning voor NFC</string>
<string name="error_nothing_import">Niets te importeren</string>
<string name="error_import_file_no_content">Bestand heeft geen inhoud</string>
<string name="error_generic_report_bug">Een algemene fout is opgetreden, maak alstublieft een nieuwe bug report voor OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Deel van het geladen bestand is geldig OpenPGP object maar niet een OpenPGP sleutel</item>
@ -324,10 +295,8 @@
<string name="progress_verifying_integrity">integriteit verifiëren...</string>
<string name="progress_deleting_securely">\'%s\' veilig verwijderen...</string>
<!--action strings-->
<string name="hint_public_keys">Publieke sleutels zoeken</string>
<string name="hint_secret_keys">Privésleutels zoeken</string>
<string name="action_share_key_with">Sleutel delen met...</string>
<string name="hint_keybase_search">Doorzoek Keybase.io</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -368,6 +337,7 @@
<string name="import_nfc_help_button">Help</string>
<string name="import_clipboard_button">Verkrijg sleutel uit klembord</string>
<string name="import_keybase_button">Verkrijg sleutel uit Keybase.io</string>
<!--Import result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">Decodeer bestand met OpenKeychain</string>
<string name="intent_import_key">Importeer Sleutel met OpenKeychain</string>
@ -431,7 +401,6 @@
<string name="nav_encrypt">Ondertekenen en Versleutelen</string>
<string name="nav_decrypt">Decoderen en Verifiëren</string>
<string name="nav_import">Importeer Sleutels</string>
<string name="nav_apps">Geregistreerde apps</string>
<string name="drawer_open">Open navigatiemenu</string>
<string name="drawer_close">Sluit navigatiemenu</string>
<string name="edit">Bewerken</string>
@ -452,6 +421,11 @@
<string name="cert_verify_failed">mislukt!</string>
<string name="cert_verify_error">fout!</string>
<string name="cert_verify_unavailable">sleutel onbeschikbaar</string>
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
<string name="section_certifier_id">Certificeer</string>
<string name="section_cert">Certificaat Details</string>

View File

@ -9,7 +9,6 @@
<string name="title_create_key">Utwórz Klucz</string>
<string name="title_edit_key">Edytuj Klucz</string>
<string name="title_preferences">Właściwości</string>
<string name="title_api_registered_apps">Zarejestrowane Aplikacje</string>
<string name="title_key_server_preference">Właściwości serwera kluczy</string>
<string name="title_change_passphrase">Zmień hasło</string>
<string name="title_set_passphrase">Ustaw hasło</string>
@ -55,15 +54,11 @@
<!--menu-->
<string name="menu_preferences">Ustawienia</string>
<string name="menu_help">Pomoc</string>
<string name="menu_import_from_file">Zaimportuj z pliku</string>
<string name="menu_import_from_qr_code">Zaimportuj z kodu QR</string>
<string name="menu_import_from_nfc">Zaimportuj przy użyciu NFC</string>
<string name="menu_export_key">Eksportuj do pliku</string>
<string name="menu_delete_key">Usuń klucz</string>
<string name="menu_create_key">Stwórz klucz</string>
<string name="menu_create_key_expert">Stwórz klucz (tryb zaawansowany)</string>
<string name="menu_search">Znajdź</string>
<string name="menu_import_from_key_server">Serwer kluczy</string>
<string name="menu_key_server">Serwer kluczy...</string>
<string name="menu_update_key">Aktualizuj z serwera kluczy</string>
<string name="menu_export_key_to_server">Wyślij do serwera kluczy</string>
@ -191,38 +186,12 @@
<string name="ask_save_changed_key">Zostały dokonane zmiany w pęku kluczy, czy chcesz je zachować?</string>
<string name="public_key_deletetion_confirmation">Czy na pewno chcesz usunąć klucz publiczny \'%s\'?\nNie można cofnąć tej operacji!</string>
<string name="also_export_secret_keys">Czy wyeksportować również klucze prywatne?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Pomyślnie dodano %d klucz</item>
<item quantity="few">Pomyślnie dodano %d kluczy</item>
<item quantity="other">Pomyślnie dodano %d kluczy</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">i zaktualizowano %d klucz.</item>
<item quantity="few">i zaktualizowano %d kluczy.</item>
<item quantity="other">i zaktualizowano %d kluczy.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">Pomyślnie dodano %d klucz.</item>
<item quantity="few">Pomyślnie dodano %d kluczy.</item>
<item quantity="other">Pomyślnie dodano %d kluczy.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">Pomyślnie zaktualizowano %d klucz.</item>
<item quantity="few">Pomyślnie zaktualizowano %d kluczy.</item>
<item quantity="other">Pomyślnie zaktualizowano %d kluczy.</item>
</plurals>
<string name="import_error_nothing">Nie dodano ani zaktualizowano żadnych kluczy.</string>
<string name="key_exported">Pomyślnie wyeksportowano 1 klucz.</string>
<string name="keys_exported">Pomyślnie wyeksportowano %d kluczy.</string>
<string name="no_keys_exported">Nie wyeksportowano żadnych kluczy.</string>
<string name="key_creation_el_gamal_info">Informacja: tylko podklucze mogą być tworzone przy użyciu algorytmu ElGamal.</string>
<string name="key_creation_weak_rsa_info">Uwaga: generowanie klucza RSA o długości 1024 bity i mniejszej jest uważane za niebezpieczne i wyłączone dla tworzenia nowych kluczy.</string>
<string name="key_not_found">Nie można znaleźć klucza %08X.</string>
<plurals name="keys_found">
<item quantity="one">Znaleziono %d klucz.</item>
<item quantity="few">Znaleziono %d kluczy.</item>
<item quantity="other">Znaleziono %d kluczy.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">Zignorowano %d niepoprawny klucz prywatny. Prawdopodobnie został wyeksportowany przy uzyciu opcji\n --export-secret-subkeys\nUpewnij się że eksportujesz go z opcją\n --export-secret-keys\nktóra jest poprawna.</item>
<item quantity="few">Zignorowano %d niepoprawnych kluczy prywatnych. Prawdopodobnie zostały wyeksportowane przy uzyciu opcji\n --export-secret-subkeys\nUpewnij się że eksportujesz je z opcją\n --export-secret-keys\nktóra jest poprawna.</item>
@ -258,8 +227,6 @@
<string name="error_only_files_are_supported">Dane binarne pozbawione pliku nie są obsługiwane.</string>
<string name="error_jelly_bean_needed">Potrzebujesz Androida 4.1 aby korzystać z Android NFC Beam</string>
<string name="error_nfc_needed">NCF jest niedostępne na twoim urządzeniu</string>
<string name="error_nothing_import">Nie ma nic do zaimportowania!</string>
<string name="error_import_file_no_content">Plik jest pusty</string>
<string name="error_generic_report_bug">Wystąpił błąd ogólny, proszę zgłoś go autorom OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Część wczytanego pliku jest poprawnym obiektem OpenPGP, ale nie jest kluczem OpenPGP</item>
@ -313,7 +280,6 @@
<string name="progress_verifying_integrity">weryfikacja spójności...</string>
<string name="progress_deleting_securely">usuwanie \'%s\' bezpiecznie…</string>
<!--action strings-->
<string name="hint_public_keys">Wyszukaj klucze publiczne</string>
<string name="hint_secret_keys">Wyszukaj klucze prywatne</string>
<string name="action_share_key_with">Udostępnij klucz...</string>
<!--key bit length selections-->
@ -356,6 +322,7 @@
<string name="import_nfc_text">Aby odbierać klucze przez NFC, urządzenie musi być odblokowane.</string>
<string name="import_nfc_help_button">Pomoc</string>
<string name="import_clipboard_button">Odczytaj klucz ze schowka</string>
<!--Import result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">Deszyfruj plik korzystając z OpenKeychain</string>
<string name="intent_import_key">Importuj klucz korzystając z OpenKeychain</string>
@ -408,7 +375,6 @@
<string name="nav_encrypt">Podpisz i zaszyfruj</string>
<string name="nav_decrypt">Deszyfruj i weryfikuj</string>
<string name="nav_import">Importuj klucze</string>
<string name="nav_apps">Zarejestrowane aplikacje</string>
<string name="drawer_open">Otwórz panel nawigacji</string>
<string name="drawer_close">Zamknij panel nawigacji</string>
<string name="edit">Edytuj</string>
@ -428,6 +394,11 @@
<string name="cert_verify_failed">niepowodzenie!</string>
<string name="cert_verify_error">błąd!</string>
<string name="cert_verify_unavailable">klucz niedostępny</string>
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
<string name="section_cert">Szczegóły certyfikatu</string>
<string name="unknown_uid">&lt;nieznany&gt;</string>

View File

@ -8,8 +8,9 @@
<string name="title_authentication">Пароль</string>
<string name="title_create_key">Создать ключ</string>
<string name="title_edit_key">Изменить ключ</string>
<string name="title_wizard">Добро пожаловать в OpenKeychain</string>
<string name="title_preferences">Настройки</string>
<string name="title_api_registered_apps">Связанные приложения</string>
<string name="title_api_registered_apps">Приложения</string>
<string name="title_key_server_preference">Настройки сервера ключей</string>
<string name="title_change_passphrase">Изменить пароль</string>
<string name="title_set_passphrase">Задать пароль</string>
@ -27,6 +28,7 @@
<string name="title_certify_key">Сертифицировать</string>
<string name="title_key_details">Сведения о ключе</string>
<string name="title_help">Помощь</string>
<string name="title_log_display">Журнал</string>
<!--section-->
<string name="section_user_ids">Идентификаторы</string>
<string name="section_keys">Доп. ключи</string>
@ -70,16 +72,11 @@
<!--menu-->
<string name="menu_preferences">Настройки</string>
<string name="menu_help">Помощь</string>
<string name="menu_import_from_file">Импорт из файла</string>
<string name="menu_import_from_qr_code">Импорт из QR кода</string>
<string name="menu_import_from_nfc">Импорт из NFC</string>
<string name="menu_export_key">Экспорт в файл</string>
<string name="menu_delete_key">Удалить ключ</string>
<string name="menu_create_key">Создать ключ</string>
<string name="menu_create_key_expert">Создать ключ (эксперт)</string>
<string name="menu_search">Поиск</string>
<string name="menu_import_from_key_server">Сервер ключей</string>
<string name="menu_import_from_keybase">Импорт с сервера Keybase.io</string>
<string name="menu_key_server">Сервер ключей...</string>
<string name="menu_update_key">Обновить с сервера ключей</string>
<string name="menu_export_key_to_server">Загрузить на сервер ключей</string>
@ -98,6 +95,7 @@
<string name="menu_select_all">Выбрать все</string>
<string name="menu_add_keys">Добавить ключи</string>
<string name="menu_export_all_keys">Экспорт всех ключей</string>
<string name="menu_advanced">Подробные данные</string>
<!--label-->
<string name="label_sign">Подписать</string>
<string name="label_message">Сообщение</string>
@ -122,7 +120,7 @@
<string name="label_keyservers">Серверы ключей</string>
<string name="label_key_id">ID ключа</string>
<string name="label_creation">Создан</string>
<string name="label_expiry">Годен до...</string>
<string name="label_expiry">Годен до</string>
<string name="label_usage">Применение</string>
<string name="label_key_size">Размер ключа</string>
<string name="label_main_user_id">Основной идентификатор</string>
@ -143,6 +141,8 @@
<string name="no_key">&lt;нет ключа&gt;</string>
<string name="can_encrypt">шифрование</string>
<string name="can_sign">подпись</string>
<string name="can_certify">сертификация</string>
<string name="can_certify_not">не для сертификации</string>
<string name="expired">просрочен</string>
<string name="revoked">отозван</string>
<plurals name="n_keys">
@ -178,9 +178,10 @@
<string name="error">Ошибка</string>
<string name="error_message">Ошибка: %s</string>
<!--key flags-->
<string name="flag_certify">Сертифицировать</string>
<string name="flag_sign">Подписать</string>
<string name="flag_encrypt">Зашифровать</string>
<string name="flag_certify">Сертификация</string>
<string name="flag_sign">Подписание</string>
<string name="flag_encrypt">Шифрование</string>
<string name="flag_authenticate">Аутентификация</string>
<!--sentences-->
<string name="wrong_passphrase">Неправ. пароль</string>
<string name="set_a_passphrase">Сначала задайте пароль</string>
@ -206,38 +207,12 @@
<string name="ask_empty_id_ok">Вы добавили пустой идентификатор. Вы уверены, что хотите продолжить?</string>
<string name="public_key_deletetion_confirmation">Вы правда хотите удалить публичный ключ \'%s\'?\nЭто действие нельзя отменить!</string>
<string name="also_export_secret_keys">Экспортировать секретные ключи?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Успешно добавлено %d ключ</item>
<item quantity="few">Успешно добавлено %d ключей</item>
<item quantity="other">Успешно добавлено %d ключей</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">и обновлен %d ключ.</item>
<item quantity="few">и обновлено %d ключей.</item>
<item quantity="other">и обновлено %d ключей.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">Добавлен %d ключ</item>
<item quantity="few">Добавлено %d ключей</item>
<item quantity="other">Добавлено %d ключей</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">Обновлен %d ключ.</item>
<item quantity="few">Обновлено %d ключей.</item>
<item quantity="other">Обновлено %d ключей.</item>
</plurals>
<string name="import_error_nothing">Нет обновленных или добавленных ключей</string>
<string name="key_exported">Успешный экспорт 1 ключа.</string>
<string name="keys_exported">Экспортировано %d ключей.</string>
<string name="no_keys_exported">Ключи не были экспортированы.</string>
<string name="key_creation_el_gamal_info">Прим.: только вторичные ключи поддерживают ElGamal.</string>
<string name="key_creation_weak_rsa_info">Внимание: создание ключей RSA длиной 1024 бита и менее признано небезопасным. Данная возможность отключена.</string>
<string name="key_not_found">Не удается найти ключ %08X.</string>
<plurals name="keys_found">
<item quantity="one">Найден %d ключ.</item>
<item quantity="few">Найдено %d ключей.</item>
<item quantity="other">Найдено %d ключей.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d плохой секретный ключ проигнорирован. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys</item>
<item quantity="few">%d плохих секретных ключей проигнорировано. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys\n</item>
@ -278,11 +253,11 @@
<string name="error_only_files_are_supported">Прямая передача данных без использования файла в памяти устройства не поддерживается.</string>
<string name="error_jelly_bean_needed">Для использования NFC Beam требуется Android 4.1+ !</string>
<string name="error_nfc_needed">Ваше устройство не поддерживает NFC!</string>
<string name="error_nothing_import">Нет данных для импорта!</string>
<string name="error_nothing_import">Ключи не найдены!</string>
<string name="error_keyserver_insufficient_query">Запрос слишком короткий</string>
<string name="error_searching_keys">Ошибка поиска ключей на сервере</string>
<string name="error_keyserver_too_many_responses">Поиск ключа вернул слишком много вариантов; Пожалуйста, уточните запрос</string>
<string name="error_import_file_no_content">Файл пуст</string>
<string name="error_import_file_no_content">Файл/Буфер пуст</string>
<string name="error_generic_report_bug">Выявлена ошибка. Пожалуйста, сообщите о ней разработчику.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">часть загруженного файла содержит данные OpenPGP, но это не ключ</item>
@ -336,10 +311,9 @@
<string name="progress_verifying_integrity">проверка целостности...</string>
<string name="progress_deleting_securely">безопасное удаление \'%s\'...</string>
<!--action strings-->
<string name="hint_public_keys">Найти публичные ключи</string>
<string name="hint_public_keys">Имя/Email/ID ключа…</string>
<string name="hint_secret_keys">Найти секретные ключи</string>
<string name="action_share_key_with">Отправить...</string>
<string name="hint_keybase_search">Поиск на сервере Keybase.io</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -365,6 +339,10 @@
<string name="help_tab_about">О программе</string>
<string name="help_about_version">Версия:</string>
<!--Import-->
<string name="import_tab_keyserver">Сервер ключей</string>
<string name="import_tab_direct">Файл/Буфер</string>
<string name="import_tab_qr_code">QR код/NFC</string>
<string name="import_tab_keybase">Keybase.io</string>
<string name="import_import">Импорт выбранных ключей</string>
<string name="import_from_clipboard">Импорт из буфера обмена</string>
<plurals name="import_qr_code_missing">
@ -379,8 +357,24 @@
<string name="import_qr_scan_button">Сканировать QR код с \'Barcode Scanner\'</string>
<string name="import_nfc_text">Разблокируйте устройство, что бы получить ключ через NFC.</string>
<string name="import_nfc_help_button">Помощь</string>
<string name="import_qr_code_button">Сканировать QR код...</string>
<string name="import_clipboard_button">Получить ключ из буфера</string>
<string name="import_keybase_button">Получить ключ с сервера Keybase.io</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Ключ успешно импортирован</item>
<item quantity="few">Успешно добавлено %1$d ключей</item>
<item quantity="other">Успешно добавлено %1$d ключей</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">и обновлен ключ%2$s.</item>
<item quantity="few">и обновлено %1$d ключей%2$s.</item>
<item quantity="other">и обновлено %1$d ключей%2$s.</item>
</plurals>
<string name="import_view_log">Смотреть журнал</string>
<string name="import_error_nothing">Нет данных для импорта.</string>
<string name="import_error">Ошибка импорта ключей!</string>
<string name="import_with_warnings">, с предупреждениями</string>
<!--Intent labels-->
<string name="intent_decrypt_file">OpenKeychain: Расшифровать файл</string>
<string name="intent_import_key">OpenKeychain: Импортировать ключ</string>
@ -445,7 +439,7 @@
<string name="nav_encrypt">Подписать и зашифровать</string>
<string name="nav_decrypt">Расшифровать и проверить</string>
<string name="nav_import">Импорт ключей</string>
<string name="nav_apps">Связанные приложения</string>
<string name="nav_apps">Приложения</string>
<string name="drawer_open">Открыть панель навигации</string>
<string name="drawer_close">Закрыть панель навигации</string>
<string name="edit">Изменить</string>
@ -464,6 +458,46 @@
<string name="cert_verify_failed">сбой!</string>
<string name="cert_verify_error">ошибка!</string>
<string name="cert_verify_unavailable">ключ не доступен</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Выполнение пакетной вставки.</string>
<string name="msg_ip_bad_type_secret">Попытка импорта секретной связки как публичной. Это ошибка, пожалуйста, сообщите об этом.</string>
<string name="msg_ip_delete_old_fail">Старый ключ не удален (создать новый?)</string>
<string name="msg_ip_delete_old_ok">Старый ключ удален из базы</string>
<string name="msg_ip_encode_fail">Действие прервано из-за ошибки кодировки</string>
<string name="msg_ip_fail_io_exc">Действие прервано из-за ошибки ввода/вывода</string>
<string name="msg_ip_fail_remote_ex">Действие прервано из-за внутренней ошибки</string>
<string name="msg_ip">Импорт связки публичных ключей %s</string>
<string name="msg_ip_prepare">Подготовка операций</string>
<string name="msg_ip_success">Успешно внесена связка публичных ключей</string>
<string name="msg_ip_reinsert_secret">Повторное внесение секретного ключа</string>
<string name="msg_ip_uid_cert_bad">Плохой сертификат!</string>
<string name="msg_ip_uid_cert_error">Ошибка обработки сертификата!</string>
<string name="msg_ip_uid_processing">Обработка id %s</string>
<string name="msg_ip_uid_revoked">id аннулирован</string>
<string name="msg_is_bad_type_public">Попытка импорта публичной связки как секретной. Это ошибка, пожалуйста, сообщите об этом.</string>
<!--Import Secret log entries-->
<string name="msg_is">Импорт секретного ключа %s</string>
<string name="msg_is_db_exception">Ошибка базы данных!</string>
<string name="msg_is_importing_subkeys">Обработка секретных ключей</string>
<string name="msg_is_success">Успешно добавлена связка секретных ключей</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_master">Подготовка основного ключа</string>
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<string name="msg_mf_error_encode">Ошибка кодирования!</string>
<string name="msg_mf_error_keyid">Нет ID ключа. Это программная ошибка. Пожалуйста, сообщите об этом!</string>
<string name="msg_mf_error_integrity">Внутренняя ошибка, сбой проверки целостности!</string>
<string name="msg_mf_error_revoked_primary">Аннулированные идентификаторы не могут быть основными!</string>
<string name="msg_mf_error_pgp">Внутренняя ошибка PGP!</string>
<string name="msg_mf_error_sig">Ошибка подписи!</string>
<string name="msg_mf_passphrase">Изменение пароля</string>
<string name="msg_mf_subkey_past_expiry">Срок годности не может быть в прошлом!</string>
<string name="msg_mf_success">Связка успешно изменена</string>
<string name="msg_mf_uid_add">Добавление id %s</string>
<string name="msg_mf_uid_primary">Изменение основного uid на %s</string>
<string name="msg_mf_uid_revoke">Аннулирование id %s</string>
<string name="msg_mf_unlock_error">Ошибка разблокирования связки!</string>
<string name="msg_mf_unlock">Разблокирование связки</string>
<!--unsorted-->
<string name="section_certifier_id">Кем подписан</string>
<string name="section_cert">Детали сертификации</string>
@ -480,5 +514,9 @@
<string name="secret_cannot_multiple">Секретные ключи можно удалять только по одному!</string>
<string name="title_view_cert">Просмотреть детали сертификации</string>
<string name="unknown_algorithm">неизв.</string>
<string name="can_sign_not">не для подписания</string>
<string name="error_encoding">Ошибка кодировки</string>
<string name="error_no_encrypt_subkey">Нет доп. ключа для шифрования!</string>
<string name="info_no_manual_account_creation">Не создавать аккаунт OpenKeychain вручную.\nДля подробной информации, смотрите раздел Помощь.</string>
<string name="contact_show_key">Показать ключ (%s)</string>
</resources>

View File

@ -0,0 +1,37 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<!--title-->
<!--section-->
<!--button-->
<!--menu-->
<!--label-->
<!--choice-->
<!--key flags-->
<!--sentences-->
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
<!--errors without preceeding Error:-->
<!--results shown after decryption/verification-->
<!--progress dialogs, usually ending in '…'-->
<!--action strings-->
<!--key bit length selections-->
<!--compression-->
<!--Help-->
<!--Import-->
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<!--Share-->
<!--Key list-->
<!--Key view-->
<!--Navigation Drawer-->
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -9,7 +9,6 @@
<string name="title_create_key">Ustvari kluč</string>
<string name="title_edit_key">Uredi ključ</string>
<string name="title_preferences">Nastavitve</string>
<string name="title_api_registered_apps">Prijavljene aplikacije</string>
<string name="title_key_server_preference">Nastavitve strežnikov</string>
<string name="title_change_passphrase">Spremeni geslo</string>
<string name="title_set_passphrase">Določi geslo</string>
@ -70,16 +69,11 @@
<!--menu-->
<string name="menu_preferences">Nastavitve</string>
<string name="menu_help">Pomoč</string>
<string name="menu_import_from_file">Uvozi iz datoteke</string>
<string name="menu_import_from_qr_code">Uvozi iz kode QR</string>
<string name="menu_import_from_nfc">Uvozi preko NFC</string>
<string name="menu_export_key">Izvozi v datoteko</string>
<string name="menu_delete_key">Izbriši ključ</string>
<string name="menu_create_key">Ustvari ključ</string>
<string name="menu_create_key_expert">Ustvari ključ (napredno)</string>
<string name="menu_search">Išči</string>
<string name="menu_import_from_key_server">Strežnik</string>
<string name="menu_import_from_keybase">Uvozi iz Keybase.io</string>
<string name="menu_key_server">Strežnik...</string>
<string name="menu_update_key">Posodobi s strežnika</string>
<string name="menu_export_key_to_server">Naloži na strežnik</string>
@ -98,6 +92,7 @@
<string name="menu_select_all">Izberi vse</string>
<string name="menu_add_keys">Dodaj ključe</string>
<string name="menu_export_all_keys">Izvozi vse ključe</string>
<string name="menu_advanced">Prikaži dodatne informacije</string>
<!--label-->
<string name="label_sign">Podpiši</string>
<string name="label_message">Sporočilo</string>
@ -208,47 +203,16 @@
<string name="specify_file_to_export_to">Določite datoteko, kamor želite izvoziti vsebino.\nPOZOR: če datoteka že obstaja, bo prepisana.</string>
<string name="key_deletion_confirmation_multi">Ali res želite izbrisati vse izbrane javne ključe?\nTega koraka ne boste mogli preklicati!</string>
<string name="secret_key_deletion_confirmation">Ali res želite izbrisati ZASEBNI ključ \'%s\'?\nTega koraka ne boste mogli preklicati!</string>
<string name="ask_save_changed_key">Vnesli ste spremembe v vaš \'keyring\'. Jih želite shraniti?</string>
<string name="ask_save_changed_key">Vnesli ste spremembe v zbirko ključev. Jih želite shraniti?</string>
<string name="ask_empty_id_ok">Dodali ste prazno identiteto, ali res želite nadaljevati?</string>
<string name="public_key_deletetion_confirmation">Ali res želite izbrisati javni ključ \'%s\'?\nTega koraka ne boste mogli preklicati!</string>
<string name="also_export_secret_keys">Želite izvoziti tudi zasebne ključe?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Uspešno dodan %d ključ</item>
<item quantity="two">Uspešno dodana %d ključa</item>
<item quantity="few">Uspešno dodani %d ključi</item>
<item quantity="other">Uspešno dodanih %d ključev</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">in posodbljen %d.</item>
<item quantity="two">in posodobljena %d.</item>
<item quantity="few">in posodobljeni %d.</item>
<item quantity="other">in posodobljenih %d.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">Uspešno dodan %d ključ.</item>
<item quantity="two">Uspešno dodana %d ključa.</item>
<item quantity="few">Uspešno dodani %d ključi.</item>
<item quantity="other">Uspešno dodanih %d ključev.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">Uspešno posodobljen %d ključ.</item>
<item quantity="two">Uspešno posodobljena %d ključa.</item>
<item quantity="few">Uspešno posodobljeni %d ključi.</item>
<item quantity="other">Uspešno posodobljenih %d ključev.</item>
</plurals>
<string name="import_error_nothing">Noben ključ ni bil dodan ali posodobljen.</string>
<string name="key_exported">Uspešno izvožen 1 ključ.</string>
<string name="keys_exported">Uspešno izvoženih ključev: %d</string>
<string name="no_keys_exported">Noben ključ ni bil izvožen.</string>
<string name="key_creation_el_gamal_info">Pozor: ELGamal podpirajo samo podključi.</string>
<string name="key_creation_weak_rsa_info">Pozor: ključi RSA dolžine 1024 bitov ali manj ne veljajo več za varne, zato je njihovo ustvarjanje onemogočeno.</string>
<string name="key_not_found">Ne najdem ključa %08X.</string>
<plurals name="keys_found">
<item quantity="one">Najden %d ključ.</item>
<item quantity="two">Najdena %d ključa.</item>
<item quantity="few">Najdeni %d ključi.</item>
<item quantity="other">Najdeno %d ključev.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">Neupoštevan %d slab zasebni ključ. Morda je bil izvožen na način\n --export-secret-subkeys\nPoskrbite, da bo izvožen z\n --export-secret-keys</item>
<item quantity="two">Neupoštevana %d slaba zasebna ključa. Morda sta bila izvožena na način\n --export-secret-subkeys\nPoskrbite, da bosta izvožena z\n --export-secret-keys</item>
@ -290,8 +254,9 @@
<string name="error_only_files_are_supported">Neposredni binarni podatki brez dejanske datoteke v datotečnem sistemu niso podprti.</string>
<string name="error_jelly_bean_needed">Za uporabo storitve NFC Beam potrebujete najmanj Android 4.1!</string>
<string name="error_nfc_needed">NFC ni na voljo na vaši napravi!</string>
<string name="error_nothing_import">Ni česa uvoziti!</string>
<string name="error_import_file_no_content">Datoteka nima vsebine</string>
<string name="error_keyserver_insufficient_query">Iskalni pojem je prekratek</string>
<string name="error_searching_keys">Nepremostljiva napaka pri iskanju ključev na strežniku</string>
<string name="error_keyserver_too_many_responses">Iskanje ključev je vrnilo preveč zadetkov; prosimo redefinirajte iskalni pojem</string>
<string name="error_generic_report_bug">Pripetila se je splošna napaka, prosimo ustvarite poročilo o \'hrošču\'.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Del naložene datoteke je veljavnen objekt OpenPGP a ni ključ.</item>
@ -299,7 +264,7 @@
<item quantity="few">Deli naložene datoteke so veljavni objekti OpenPGP a niso ključi.</item>
<item quantity="other">Deli naložene datoteke so veljavni objekti OpenPGP a niso ključi.</item>
</plurals>
<string name="error_change_something_first">V \'keyring\' morate vnesti spremembe, šele nato ga lahko shranite</string>
<string name="error_change_something_first">V zbirko ključev morate najprej vnesti spremembe, šele nato jo lahko shranite</string>
<!--results shown after decryption/verification-->
<string name="decrypt_result_invalid_signature">Neveljaven podpis!</string>
<string name="decrypt_result_signature_unknown_pub_key">Neznan javni ključ</string>
@ -348,10 +313,8 @@
<string name="progress_verifying_integrity">preverjam neokrnjenost...</string>
<string name="progress_deleting_securely">varno brišem \'%s\'…</string>
<!--action strings-->
<string name="hint_public_keys">Iskanje javnih ključev</string>
<string name="hint_secret_keys">Iskanje zasebnih ključev</string>
<string name="action_share_key_with">Deli ključ z...</string>
<string name="hint_keybase_search">Išči v Keybase.io</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -394,6 +357,7 @@
<string name="import_nfc_help_button">Pomoč</string>
<string name="import_clipboard_button">Pridobi ključ iz odložišča</string>
<string name="import_keybase_button">Pridobi ključ iz Keybase.io</string>
<!--Import result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">Dešifriraj datoteko z OpenKeychain</string>
<string name="intent_import_key">Uvozi ključ z OpenKeychain</string>
@ -459,7 +423,6 @@
<string name="nav_encrypt">Podpiši in šifriraj</string>
<string name="nav_decrypt">Dešifriraj in preveri</string>
<string name="nav_import">Uvozi ključe</string>
<string name="nav_apps">Prijavljene aplikacije</string>
<string name="drawer_open">Odprite navigacijski poteznik</string>
<string name="drawer_close">Zaprite navigacijski poteznik</string>
<string name="edit">Uredi</string>
@ -480,6 +443,27 @@
<string name="cert_verify_failed">neuspešno!</string>
<string name="cert_verify_error">napaka!</string>
<string name="cert_verify_unavailable">ključ ni na voljo</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Uveljavljam serijsko dodajanje.</string>
<string name="msg_ip_bad_type_secret">Poskus uvoza zasebne zbirke ključev kot javne. Prosimo prijavite dogodek kot \"hrošč\" (napako).</string>
<string name="msg_ip_delete_old_fail">Noben star ključ ni bil izbrisan (ustvarim novega?)</string>
<string name="msg_ip_delete_old_ok">Star ključ je bil izbrisan iz baze</string>
<string name="msg_ip_encode_fail">Operacija ni uspela zaradi napake</string>
<string name="msg_ip_fail_io_exc">Operacija ni uspela zaradi napake pri branju/pisanju</string>
<string name="msg_ip_fail_remote_ex">Operacija ni uspela zaradi notranje napake</string>
<string name="msg_ip_reinsert_secret">Ponovno vnašam zasebni ključ</string>
<string name="msg_ip_uid_cert_bad">Naleteli ste na slab certifikat!</string>
<string name="msg_ip_uid_cert_error">Napaka pri obdelavi certifikata!</string>
<string name="msg_ip_uid_processing">Procesiram uporabniško identiteto %s</string>
<string name="msg_is_bad_type_public">Poskus uvoza javne zbirke ključev kot zasebne. Prosimo prijavite dogodek kot \'hrošč\' (napako).</string>
<!--Import Secret log entries-->
<string name="msg_is_importing_subkeys">Procesiram zasebne podključe</string>
<string name="msg_is_subkey_nonexistent">Podključ %s ni na voljo v javnem ključu</string>
<string name="msg_is_subkey_ok">%s označen kot razpoložljiv</string>
<string name="msg_is_subkey_stripped">%s označen kot slečen</string>
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
<string name="section_certifier_id">Overovitelj</string>
<string name="section_cert">Podrobnosti potrdil</string>
@ -498,5 +482,8 @@
<string name="title_view_cert">Preglej podrobosti certifikata</string>
<string name="unknown_algorithm">neznan</string>
<string name="can_sign_not">ne more podpisati</string>
<string name="error_encoding">Napaka pri šifriranju</string>
<string name="error_no_encrypt_subkey">Ni nobenega podključa za šifriranje!</string>
<string name="info_no_manual_account_creation">Ne ustvari računov OpenKeychain ročno.\nZa več informacij poglej poglavje Pomoč.</string>
<string name="contact_show_key">Prikaži ključ (%s)</string>
</resources>

View File

@ -32,15 +32,11 @@
<!--menu-->
<string name="menu_preferences">Ayarlar</string>
<string name="menu_help">Yardım</string>
<string name="menu_import_from_file">Dosyadan al</string>
<string name="menu_import_from_qr_code">QR Kodundan al</string>
<string name="menu_import_from_nfc">NFCden al</string>
<string name="menu_export_key">Dosyaya ver</string>
<string name="menu_delete_key">Anahtar sil</string>
<string name="menu_create_key">Anahtar oluştur</string>
<string name="menu_create_key_expert">Anahtar oluştur (uzman)</string>
<string name="menu_search">Ara</string>
<string name="menu_import_from_key_server">Anahtar Sunucusu</string>
<string name="menu_share">Paylaş...</string>
<string name="menu_share_qr_code">QR Kod ile</string>
<string name="menu_share_nfc">NFC ile</string>
@ -105,7 +101,6 @@
<string name="error_key_size_minimum512bit">anahtar uzunluğu en az 512bit olmalı</string>
<string name="error_user_id_no_email">eposta bulunamadı</string>
<!--errors without preceeding Error:-->
<string name="error_import_file_no_content">Dosyanın içeriği boş</string>
<!--results shown after decryption/verification-->
<string name="decrypt_result_invalid_signature">Geçersiz imza!</string>
<!--progress dialogs, usually ending in '…'-->
@ -148,6 +143,7 @@
<!--Import-->
<string name="import_import">Seçili anahtarları al</string>
<string name="import_nfc_help_button">Yardım</string>
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<string name="api_settings_no_key">Anahtar seçilmedi</string>
@ -179,6 +175,11 @@
<string name="cert_verify_failed">başarısız!</string>
<string name="cert_verify_error">hata!</string>
<string name="cert_verify_unavailable">anahtar mevcut değil</string>
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
<string name="can_sign_not">imzalanamadı</string>
</resources>

View File

@ -9,7 +9,6 @@
<string name="title_create_key">Створити ключ</string>
<string name="title_edit_key">Редагувати ключ</string>
<string name="title_preferences">Налаштування</string>
<string name="title_api_registered_apps">Зареєстровані програми</string>
<string name="title_key_server_preference">Налаштування сервера ключів</string>
<string name="title_change_passphrase">Змінити парольну фразу</string>
<string name="title_set_passphrase">Задати парольну фразу</string>
@ -27,6 +26,7 @@
<string name="title_certify_key">Сертифікувати сутності</string>
<string name="title_key_details">Подробиці про ключ</string>
<string name="title_help">Довідка</string>
<string name="title_log_display">Журнал</string>
<!--section-->
<string name="section_user_ids">Сутності</string>
<string name="section_keys">Підключі</string>
@ -70,16 +70,11 @@
<!--menu-->
<string name="menu_preferences">Параметри</string>
<string name="menu_help">Довідка</string>
<string name="menu_import_from_file">Імпорт з файлу</string>
<string name="menu_import_from_qr_code">Імпорт з штрих-коду</string>
<string name="menu_import_from_nfc">Імпорт з NFC</string>
<string name="menu_export_key">Експорт до файлу</string>
<string name="menu_delete_key">Вилучити ключ</string>
<string name="menu_create_key">Створити ключ</string>
<string name="menu_create_key_expert">Створити ключ (експерт)</string>
<string name="menu_search">Пошук</string>
<string name="menu_import_from_key_server">Сервер ключів</string>
<string name="menu_import_from_keybase">Імпорт із Keybase.io</string>
<string name="menu_key_server">Сервер ключів…</string>
<string name="menu_update_key">Оновити з сервера ключів</string>
<string name="menu_export_key_to_server">Завантажити на сервер ключів</string>
@ -98,6 +93,7 @@
<string name="menu_select_all">Вибрати усе</string>
<string name="menu_add_keys">Додати ключі</string>
<string name="menu_export_all_keys">Експортувати усі ключі</string>
<string name="menu_advanced">Показати додаткову інформацію</string>
<!--label-->
<string name="label_sign">Підпис</string>
<string name="label_message">Повідомлення</string>
@ -209,38 +205,12 @@
<string name="ask_empty_id_ok">Ви вже додали порожню сутність. Ви справді хочете продовжити?</string>
<string name="public_key_deletetion_confirmation">Ви справді хочете вилучити відкритий ключ \'%s\'?\nВи не зможете це відмінити!</string>
<string name="also_export_secret_keys">Також експортувати секретні ключі?</string>
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Успішно додано %d ключ</item>
<item quantity="few">Успішно додано %d ключі</item>
<item quantity="other">Успішно додано %d ключів</item>
</plurals>
<plurals name="import_keys_added_and_updated_2">
<item quantity="one">і оновлено %d ключ.</item>
<item quantity="few">і оновлено %d ключі.</item>
<item quantity="other">і оновлено %d ключів.</item>
</plurals>
<plurals name="import_keys_added">
<item quantity="one">Успішно додано %d ключ.</item>
<item quantity="few">Успішно додано %d ключі.</item>
<item quantity="other">Успішно додано %d ключів.</item>
</plurals>
<plurals name="import_keys_updated">
<item quantity="one">Успішно оновлено %d ключ.</item>
<item quantity="few">Успішно оновлено %d ключі.</item>
<item quantity="other">Успішно оновлено %d ключів.</item>
</plurals>
<string name="import_error_nothing">Жодного ключа не додано та не оновлено.</string>
<string name="key_exported">Успішно експортовано 1 ключ.</string>
<string name="keys_exported">Успішно експортовано %d ключів.</string>
<string name="no_keys_exported">Жодного ключа не експортовано.</string>
<string name="key_creation_el_gamal_info">Примітка: лише підключі підтримують ElGamal.</string>
<string name="key_creation_weak_rsa_info">Примітка: генерація ключа RSA з довжиною 1024 біти і менше вважається небезпечною і вона вимкнена для генерації нових ключів.</string>
<string name="key_not_found">Не можливо знайти ключ %08X.</string>
<plurals name="keys_found">
<item quantity="one">Знайдено %d ключ.</item>
<item quantity="few">Знайдено %d ключі.</item>
<item quantity="other">Знайдено %d ключів.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d поганий секретний ключ проігнорований. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість.</item>
<item quantity="few">%d погані секретні ключі проігноровані. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість.</item>
@ -281,11 +251,10 @@
<string name="error_only_files_are_supported">Пряма передача даних без використання файлу в пам\'яті пристрою не підтримується.</string>
<string name="error_jelly_bean_needed">Вам потрібний Android 4.1 для використання функції Androids NFC промінь!</string>
<string name="error_nfc_needed">NFC недоступний на вашому пристрої!</string>
<string name="error_nothing_import">Нема що імпортувати!</string>
<string name="error_nothing_import">Ключ не знайдено!</string>
<string name="error_keyserver_insufficient_query">Запит пошуку ключа надто короткий</string>
<string name="error_searching_keys">Невиправна помилка пошуку ключів в сервері</string>
<string name="error_keyserver_too_many_responses">Запит пошуку ключа видав надто багато варіантів. Уточніть пошуковий запит</string>
<string name="error_import_file_no_content">Файл не має вмісту</string>
<string name="error_generic_report_bug">Трапилася загальна помилка, будь ласка, створіть новий звіт про помилку для OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">частина завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP</item>
@ -339,10 +308,8 @@
<string name="progress_verifying_integrity">перевірка цілісності…</string>
<string name="progress_deleting_securely">вилучення безпечно \'%s\'…</string>
<!--action strings-->
<string name="hint_public_keys">Пошук публічних ключів</string>
<string name="hint_secret_keys">Пошук секретних ключів</string>
<string name="action_share_key_with">Поділитися ключем з…</string>
<string name="hint_keybase_search">Пошук Keybase.io</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@ -384,6 +351,10 @@
<string name="import_nfc_help_button">Довідка</string>
<string name="import_clipboard_button">Отримати ключ з буфера обміну</string>
<string name="import_keybase_button">Отримати ключ із Keybase.io</string>
<!--Import result toast-->
<string name="import_view_log">Переглянути журнал</string>
<string name="import_error_nothing">Нема що імпортувати.</string>
<string name="import_error">Помилка імпорту ключів!</string>
<!--Intent labels-->
<string name="intent_decrypt_file">Розшифрувати файл з OpenKeychain</string>
<string name="intent_import_key">Імпортувати ключ з OpenKeychain</string>
@ -448,7 +419,6 @@
<string name="nav_encrypt">Підписати і зашифрувати</string>
<string name="nav_decrypt">Розшифрувати і Перевірити</string>
<string name="nav_import">Імпортувати ключі</string>
<string name="nav_apps">Зареєстровані програми</string>
<string name="drawer_open">Відкрити панель навігації</string>
<string name="drawer_close">Закрити панель навігації</string>
<string name="edit">Редагувати</string>
@ -469,6 +439,26 @@
<string name="cert_verify_failed">Невдача!</string>
<string name="cert_verify_error">Помилка!</string>
<string name="cert_verify_unavailable">Недоступний ключ</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Застосовується пакетна операція вставки.</string>
<string name="msg_ip_delete_old_fail">Нема вилученого старого ключа (створюється новий?)</string>
<string name="msg_ip_delete_old_ok">Вилучений старий ключ з бази даних</string>
<string name="msg_ip_encode_fail">Операція не вдалася через помилку кодування</string>
<string name="msg_ip_fail_io_exc">Операція не вдалася через помилку вводу/виводу</string>
<string name="msg_ip_fail_remote_ex">Операція не вдалася через внутрішню помилку</string>
<string name="msg_ip_prepare">Підготовка операцій з базою даних</string>
<string name="msg_ip_subkey">Опрацьовується підключ %s</string>
<string name="msg_ip_reinsert_secret">Повторне вставлення секретного ключа</string>
<string name="msg_ip_uid_cert_bad">Виявлено поганий сертифікат!</string>
<string name="msg_ip_uid_cert_error">Помилка опрацювання сертифікату!</string>
<string name="msg_ip_uid_processing">Обробляється ІД користувача %s</string>
<!--Import Secret log entries-->
<string name="msg_is_importing_subkeys">Опрацьовуються секретні підключі</string>
<string name="msg_is_subkey_nonexistent">Підключ %s недоступний у публічному ключі</string>
<string name="msg_is_subkey_ok">Позначено %s як доступно</string>
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
<string name="section_certifier_id">Ким підписаний</string>
<string name="section_cert">Дані сертифікату</string>
@ -482,9 +472,13 @@
<string name="error_key_not_found">Ключ не знайдено!</string>
<string name="error_key_processing">Помилка опрацювання ключа!</string>
<string name="no_subkey">підключ недоступний</string>
<string name="key_stripped">голий</string>
<string name="secret_cannot_multiple">Секретні ключі можна вилучити лише окремо!</string>
<string name="title_view_cert">Переглянути дані сертифікату</string>
<string name="unknown_algorithm">невідомий</string>
<string name="can_sign_not">не можна підписати</string>
<string name="error_encoding">Помилка шифрування</string>
<string name="error_no_encrypt_subkey">Жодний підключ шифрування недоступний!</string>
<string name="info_no_manual_account_creation">Вручну не створюються профілі OpenKeychain.\nЗа подробицями дивіться Довідку.</string>
<string name="contact_show_key">Показати ключ (%s)</string>
</resources>

View File

@ -9,7 +9,6 @@
<string name="title_create_key">创建密钥</string>
<string name="title_edit_key">编辑密钥</string>
<string name="title_preferences">参数</string>
<string name="title_api_registered_apps">已注册应用</string>
<string name="title_key_server_preference">密钥服务器偏好</string>
<string name="title_set_passphrase">设置密码短语</string>
<string name="title_encrypt_to_file">加密至文件</string>
@ -134,6 +133,7 @@
<string name="import_from_clipboard">从剪贴板导入</string>
<string name="import_qr_code_finished">二维码扫描完成!</string>
<string name="import_nfc_help_button">帮助</string>
<!--Import result toast-->
<!--Intent labels-->
<!--Remote API-->
<string name="api_settings_show_advanced">显示高级设置</string>
@ -156,5 +156,10 @@
<string name="nav_import">导入密钥</string>
<!--hints-->
<!--certs-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--modifySecretKeyRing-->
<!--unsorted-->
</resources>

View File

@ -226,7 +226,6 @@
<string name="keys_exported">Successfully exported %d keys.</string>
<string name="no_keys_exported">No keys exported.</string>
<string name="key_creation_el_gamal_info">Note: only subkeys support ElGamal.</string>
<string name="key_creation_weak_rsa_info">Note: generating RSA key with length 1024-bit and less is considered unsafe and it\'s disabled for generating new keys.</string>
<string name="key_not_found">Couldn\'t find key %08X.</string>
<plurals name="bad_keys_encountered">
@ -419,7 +418,7 @@
<string name="intent_send_decrypt">Decrypt with OpenKeychain</string>
<!-- Remote API -->
<string name="api_no_apps">No registered applications!\n\nA list of supported third-party applications can be found in \'Help\'!</string>
<string name="api_no_apps">No registered apps!\n\nA list of supported third-party applications can be found in \'Help\'!</string>
<string name="api_settings_show_info">Show advanced information</string>
<string name="api_settings_hide_info">Hide advanced information</string>
<string name="api_settings_show_advanced">Show advanced settings</string>
@ -435,9 +434,9 @@
<string name="api_settings_package_name">Package Name</string>
<string name="api_settings_package_signature">SHA-256 of Package Signature</string>
<string name="api_settings_accounts">Accounts</string>
<string name="api_settings_accounts_empty">No accounts attached to this application.</string>
<string name="api_create_account_text">The application requests the creation of a new account. Please select an existing private key or create a new one.\nApplications are restricted to the usage of keys you select here!</string>
<string name="api_register_text">The displayed application requests access to OpenKeychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen.</string>
<string name="api_settings_accounts_empty">No accounts attached to this app.</string>
<string name="api_create_account_text">The app requests the creation of a new account. Please select an existing private key or create a new one.\nApps are restricted to the usage of keys you select here!</string>
<string name="api_register_text">The displayed app wants to encrypt/decrypt messages and sign them in your name.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Apps\' screen.</string>
<string name="api_register_allow">Allow access</string>
<string name="api_register_disallow">Disallow access</string>
<string name="api_register_error_select_key">Please select a key!</string>
@ -476,6 +475,16 @@
<string name="key_view_tab_keys">Subkeys</string>
<string name="key_view_tab_certs">Certificates</string>
<!-- Edit key -->
<string name="edit_key_action_change_passphrase">Change Passphrase</string>
<string name="edit_key_action_add_identity">Add Identity</string>
<string name="edit_key_action_add_subkey">Add Subkey</string>
<string name="edit_key_edit_user_id_title">Select an action!</string>
<string-array name="edit_key_edit_user_id">
<item>Change to Primary Identity</item>
<item>Revoke Identity</item>
</string-array>
<!-- Navigation Drawer -->
<string name="nav_keys">Keys</string>
<string name="nav_encrypt">Sign and Encrypt</string>
@ -550,8 +559,8 @@
<item quantity="one">Ignoring one certificate issued by an unknown public key</item>
<item quantity="other">Ignoring %s certificates issued by unknown public keys</item>
</plurals>
<string name="msg_ip_uid_classifying_zero">Classifying user ids (no trusted keys available)</string>
<plurals name="msg_ip_uid_classifying">
<item quantity="zero">Classifying user ids (no trusted keys available)</item>
<item quantity="one">Classifying user ids (using one trusted key)</item>
<item quantity="other">Classifying user ids (using %s trusted keys)</item>
</plurals>
@ -630,13 +639,17 @@
<!-- modifySecretKeyRing -->
<string name="msg_mr">Modifying keyring %s</string>
<string name="msg_mf_error_encode">Encoding exception!</string>
<string name="msg_mf_error_fingerprint">Actual key fingerprint does not match the expected one!</string>
<string name="msg_mf_error_keyid">No key ID. This is an internal error, please file a bug report!</string>
<string name="msg_mf_error_integrity">Internal error, integrity check failed!</string>
<string name="msg_mf_error_revoked_primary">Revoked user ids cannot be primary!</string>
<string name="msg_mf_error_pgp">PGP internal exception!</string>
<string name="msg_mf_error_sig">Signature exception!</string>
<string name="msg_mf_passphrase">Changing passphrase</string>
<string name="msg_mf_subkey_change">Modifying subkey %s</string>
<string name="msg_mf_subkey_missing">Tried to operate on missing subkey %s!</string>
<string name="msg_mf_subkey_new">Generating new %1$s bit %2$s subkey</string>
<string name="msg_mf_subkey_new_id">New subkey id: %s</string>
<string name="msg_mf_subkey_new_id">New subkey ID: %s</string>
<string name="msg_mf_subkey_past_expiry">Expiry date cannot be in the past!</string>
<string name="msg_mf_subkey_revoke">Revoking subkey %s</string>
<string name="msg_mf_success">Keyring successfully modified</string>

View File

@ -22,7 +22,6 @@ public class PgpDecryptVerifyTest {
Assert.assertEquals(expectedSignatureResult, status);
}
@Test
public void testVerifyFailure() throws Exception {

View File

@ -0,0 +1,13 @@
Source files for GnuPG infographic
==================================
These are the source graphics for the Email Self-Defense infographic from the
Free Software Foundation, available at <http://EmailSelfDefense.fsf.org>.
License
-------
Copyright (c) 2014 Free Software Foundation, Inc.
Licensed under the Creative Commons Attribution license (CC-BY). See full
source and attribution text at the above site.

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 579 KiB

2
extern/spongycastle vendored

@ -1 +1 @@
Subproject commit 09d85b7d7a64b3003210d065c4210ff7fb7a8c6d
Subproject commit 968405ee5d4272330cffdf75f7eee4cd9f5c8646