add PIN as a SecretKeyType

This commit is contained in:
Vincent Breitmoser 2014-12-30 12:34:24 +01:00
parent 7524881a01
commit 438405d3d2
8 changed files with 38 additions and 5 deletions

View File

@ -359,6 +359,7 @@ public abstract class OperationResult implements Parcelable {
MSG_IS_SUBKEY_STRIPPED (LogLevel.DEBUG, R.string.msg_is_subkey_stripped), MSG_IS_SUBKEY_STRIPPED (LogLevel.DEBUG, R.string.msg_is_subkey_stripped),
MSG_IS_SUBKEY_DIVERT (LogLevel.DEBUG, R.string.msg_is_subkey_divert), MSG_IS_SUBKEY_DIVERT (LogLevel.DEBUG, R.string.msg_is_subkey_divert),
MSG_IS_SUBKEY_EMPTY (LogLevel.DEBUG, R.string.msg_is_subkey_empty), MSG_IS_SUBKEY_EMPTY (LogLevel.DEBUG, R.string.msg_is_subkey_empty),
MSG_IS_SUBKEY_PIN (LogLevel.DEBUG, R.string.msg_is_subkey_pin),
MSG_IS_SUCCESS_IDENTICAL (LogLevel.OK, R.string.msg_is_success_identical), MSG_IS_SUCCESS_IDENTICAL (LogLevel.OK, R.string.msg_is_success_identical),
MSG_IS_SUCCESS (LogLevel.OK, R.string.msg_is_success), MSG_IS_SUCCESS (LogLevel.OK, R.string.msg_is_success),

View File

@ -49,6 +49,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -83,7 +84,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
} }
public enum SecretKeyType { public enum SecretKeyType {
UNAVAILABLE(0), GNU_DUMMY(1), PASSPHRASE(2), PASSPHRASE_EMPTY(3), DIVERT_TO_CARD(4); UNAVAILABLE(0), GNU_DUMMY(1), PASSPHRASE(2), PASSPHRASE_EMPTY(3), DIVERT_TO_CARD(4), PIN(5);
final int mNum; final int mNum;
@ -101,6 +102,8 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
return PASSPHRASE_EMPTY; return PASSPHRASE_EMPTY;
case 4: case 4:
return DIVERT_TO_CARD; return DIVERT_TO_CARD;
case 5:
return PIN;
// if this case happens, it's probably a check from a database value // if this case happens, it's probably a check from a database value
default: default:
return UNAVAILABLE; return UNAVAILABLE;
@ -135,6 +138,11 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
// It means the passphrase is empty // It means the passphrase is empty
return SecretKeyType.PASSPHRASE_EMPTY; return SecretKeyType.PASSPHRASE_EMPTY;
} catch (PGPException e) { } catch (PGPException e) {
HashMap<String,String> notation = getRing().getLocalNotationData();
if (notation.containsKey("unlock.pin@sufficientlysecure.org")
&& "1".equals(notation.get("unlock.pin@sufficientlysecure.org"))) {
return SecretKeyType.PIN;
}
// Otherwise, it's just a regular ol' passphrase // Otherwise, it's just a regular ol' passphrase
return SecretKeyType.PASSPHRASE; return SecretKeyType.PASSPHRASE;
} }

View File

@ -26,6 +26,7 @@ import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
@ -36,6 +37,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -130,4 +132,16 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
}); });
} }
public HashMap<String,String> getLocalNotationData() {
HashMap<String,String> result = new HashMap<String,String>();
Iterator<PGPSignature> it = getRing().getPublicKey().getKeySignatures();
while (it.hasNext()) {
WrappedSignature sig = new WrappedSignature(it.next());
if (sig.isLocal()) {
result.putAll(sig.getNotation());
}
}
return result;
}
} }

View File

@ -949,7 +949,7 @@ public class PgpKeyOperation {
{ // set subpackets { // set subpackets
PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
hashedPacketsGen.setExportable(false, false); hashedPacketsGen.setExportable(false, false);
hashedPacketsGen.setNotationData(false, false, "pin@unlock.sufficientlysecure.org", "1"); hashedPacketsGen.setNotationData(false, true, "unlock.pin@sufficientlysecure.org", "1");
sGen.setHashedSubpackets(hashedPacketsGen.generate()); sGen.setHashedSubpackets(hashedPacketsGen.generate());
} }
sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey); sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey);

View File

@ -242,15 +242,15 @@ public class WrappedSignature {
return ! ((Exportable) p).isExportable(); return ! ((Exportable) p).isExportable();
} }
public HashMap<String,byte[]> getNotation() { public HashMap<String,String> getNotation() {
HashMap<String,byte[]> result = new HashMap<String,byte[]>(); HashMap<String,String> result = new HashMap<String,String>();
// If there is any notation data // If there is any notation data
if (mSig.getHashedSubPackets() != null if (mSig.getHashedSubPackets() != null
&& mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.NOTATION_DATA)) { && mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.NOTATION_DATA)) {
// Iterate over notation data // Iterate over notation data
for (NotationData data : mSig.getHashedSubPackets().getNotationDataOccurrences()) { for (NotationData data : mSig.getHashedSubPackets().getNotationDataOccurrences()) {
result.put(data.getNotationName(), data.getNotationValueBytes()); result.put(data.getNotationName(), data.getNotationValue());
} }
} }

View File

@ -682,6 +682,11 @@ public class ProviderHelper {
KeyFormattingUtils.convertKeyIdToHex(id) KeyFormattingUtils.convertKeyIdToHex(id)
); );
break; break;
case PIN:
log(LogType.MSG_IS_SUBKEY_PIN,
KeyFormattingUtils.convertKeyIdToHex(id)
);
break;
case GNU_DUMMY: case GNU_DUMMY:
log(LogType.MSG_IS_SUBKEY_STRIPPED, log(LogType.MSG_IS_SUBKEY_STRIPPED,
KeyFormattingUtils.convertKeyIdToHex(id) KeyFormattingUtils.convertKeyIdToHex(id)

View File

@ -170,6 +170,9 @@ public class PassphraseDialogActivity extends FragmentActivity {
case PASSPHRASE: case PASSPHRASE:
message = getString(R.string.passphrase_for, userId); message = getString(R.string.passphrase_for, userId);
break; break;
case PIN:
message = getString(R.string.pin_for, userId);
break;
case DIVERT_TO_CARD: case DIVERT_TO_CARD:
message = getString(R.string.yubikey_pin, userId); message = getString(R.string.yubikey_pin, userId);
break; break;

View File

@ -205,6 +205,7 @@
<string name="passphrase_must_not_be_empty">"Please enter a passphrase."</string> <string name="passphrase_must_not_be_empty">"Please enter a passphrase."</string>
<string name="passphrase_for_symmetric_encryption">"Symmetric encryption."</string> <string name="passphrase_for_symmetric_encryption">"Symmetric encryption."</string>
<string name="passphrase_for">"Enter passphrase for '%s'"</string> <string name="passphrase_for">"Enter passphrase for '%s'"</string>
<string name="pin_for">"Enter pin for '%s'"</string>
<string name="yubikey_pin">"Enter PIN to access YubiKey for '%s'"</string> <string name="yubikey_pin">"Enter PIN to access YubiKey for '%s'"</string>
<string name="nfc_text">"Hold YubiKey against the back of your device."</string> <string name="nfc_text">"Hold YubiKey against the back of your device."</string>
<string name="file_delete_confirmation">"Are you sure you want to delete\n%s?"</string> <string name="file_delete_confirmation">"Are you sure you want to delete\n%s?"</string>
@ -696,6 +697,7 @@
<string name="msg_is_subkey_nonexistent">"Subkey %s unavailable in secret key"</string> <string name="msg_is_subkey_nonexistent">"Subkey %s unavailable in secret key"</string>
<string name="msg_is_subkey_ok">"Marked secret subkey %s as available"</string> <string name="msg_is_subkey_ok">"Marked secret subkey %s as available"</string>
<string name="msg_is_subkey_empty">"Marked secret subkey %s as available, with empty passphrase"</string> <string name="msg_is_subkey_empty">"Marked secret subkey %s as available, with empty passphrase"</string>
<string name="msg_is_subkey_pin">"Marked secret subkey %s as available, with pin passphrase"</string>
<string name="msg_is_subkey_stripped">"Marked secret subkey %s as stripped"</string> <string name="msg_is_subkey_stripped">"Marked secret subkey %s as stripped"</string>
<string name="msg_is_subkey_divert">"Marked secret subkey %s as 'divert to smartcard/NFC'"</string> <string name="msg_is_subkey_divert">"Marked secret subkey %s as 'divert to smartcard/NFC'"</string>
<string name="msg_is_success_identical">"Keyring contains no new data, nothing to do"</string> <string name="msg_is_success_identical">"Keyring contains no new data, nothing to do"</string>