Fix key id and fingerprint handling, use full key ids
This commit is contained in:
@@ -228,7 +228,7 @@ public class PgpImportExport {
|
|||||||
for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(
|
for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(
|
||||||
secretKeyRing.getSecretKeys())) {
|
secretKeyRing.getSecretKeys())) {
|
||||||
if (!testSecretKey.isMasterKey()) {
|
if (!testSecretKey.isMasterKey()) {
|
||||||
if (PgpKeyHelper.isSecretKeyPrivateEmpty(testSecretKey)) {
|
if (testSecretKey.isPrivateKeyEmpty()) {
|
||||||
// this is bad, something is very wrong...
|
// this is bad, something is very wrong...
|
||||||
save = false;
|
save = false;
|
||||||
status = Id.return_value.bad;
|
status = Id.return_value.bad;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.spongycastle.openpgp.PGPSecretKey;
|
|||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSignature;
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
@@ -415,57 +416,32 @@ public class PgpKeyHelper {
|
|||||||
String algorithmStr = null;
|
String algorithmStr = null;
|
||||||
|
|
||||||
switch (algorithm) {
|
switch (algorithm) {
|
||||||
case PGPPublicKey.RSA_ENCRYPT:
|
case PGPPublicKey.RSA_ENCRYPT:
|
||||||
case PGPPublicKey.RSA_GENERAL:
|
case PGPPublicKey.RSA_GENERAL:
|
||||||
case PGPPublicKey.RSA_SIGN: {
|
case PGPPublicKey.RSA_SIGN: {
|
||||||
algorithmStr = "RSA";
|
algorithmStr = "RSA";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PGPPublicKey.DSA: {
|
case PGPPublicKey.DSA: {
|
||||||
algorithmStr = "DSA";
|
algorithmStr = "DSA";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PGPPublicKey.ELGAMAL_ENCRYPT:
|
case PGPPublicKey.ELGAMAL_ENCRYPT:
|
||||||
case PGPPublicKey.ELGAMAL_GENERAL: {
|
case PGPPublicKey.ELGAMAL_GENERAL: {
|
||||||
algorithmStr = "ElGamal";
|
algorithmStr = "ElGamal";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
algorithmStr = "Unknown";
|
algorithmStr = "Unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return algorithmStr + ", " + keySize + " bit";
|
return algorithmStr + ", " + keySize + " bit";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts fingerprint to hex with whitespaces after 4 characters
|
|
||||||
*
|
|
||||||
* @param fp
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String convertFingerprintToHex(byte[] fp, boolean chunked) {
|
|
||||||
String fingerPrint = "";
|
|
||||||
for (int i = 0; i < fp.length; ++i) {
|
|
||||||
if (chunked && i != 0 && i % 10 == 0) {
|
|
||||||
fingerPrint += " ";
|
|
||||||
} else if (chunked && i != 0 && i % 2 == 0) {
|
|
||||||
fingerPrint += " ";
|
|
||||||
}
|
|
||||||
String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US);
|
|
||||||
while (chunk.length() < 2) {
|
|
||||||
chunk = "0" + chunk;
|
|
||||||
}
|
|
||||||
fingerPrint += chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fingerPrint;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFingerPrint(Context context, long keyId) {
|
public static String getFingerPrint(Context context, long keyId) {
|
||||||
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId);
|
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId);
|
||||||
// if it is no public key get it from your own keys...
|
// if it is no public key get it from your own keys...
|
||||||
@@ -481,52 +457,68 @@ public class PgpKeyHelper {
|
|||||||
return convertFingerprintToHex(key.getFingerprint(), true);
|
return convertFingerprintToHex(key.getFingerprint(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) {
|
/**
|
||||||
return secretKey.isPrivateKeyEmpty();
|
* Converts fingerprint to hex (optional: with whitespaces after 4 characters)
|
||||||
}
|
* <p/>
|
||||||
|
* Fingerprint is shown using lowercase characters. Studies have shown that humans can
|
||||||
// public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) {
|
* better differentiate between numbers and letters when letters are lowercase.
|
||||||
// PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
*
|
||||||
// if (secretKey == null) {
|
* @param fingerprint
|
||||||
// Log.e(Constants.TAG, "Key could not be found!");
|
* @param split split into 4 character chunks
|
||||||
// return false; // could be a public key, assume it is not empty
|
* @return
|
||||||
// }
|
*/
|
||||||
// return isSecretKeyPrivateEmpty(secretKey);
|
public static String convertFingerprintToHex(byte[] fingerprint, boolean split) {
|
||||||
// }
|
String hexString = Hex.toHexString(fingerprint);
|
||||||
|
if (split) {
|
||||||
public static String convertKeyIdToHex(long keyId) {
|
hexString = hexString.replaceAll("(.{4})(?!$)", "$1 ");
|
||||||
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
|
|
||||||
while (fingerPrint.length() < 8) {
|
|
||||||
fingerPrint = "0" + fingerPrint;
|
|
||||||
}
|
}
|
||||||
return fingerPrint;
|
|
||||||
|
return hexString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: documentation
|
* Convert key id from long to 64 bit hex string
|
||||||
*
|
* <p/>
|
||||||
|
* V4: "The Key ID is the low-order 64 bits of the fingerprint"
|
||||||
|
* <p/>
|
||||||
|
* see http://tools.ietf.org/html/rfc4880#section-12.2
|
||||||
|
*
|
||||||
* @param keyId
|
* @param keyId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String convertKeyToHex(long keyId) {
|
public static String convertKeyIdToHex(long keyId) {
|
||||||
return convertKeyIdToHex(keyId >> 32) + convertKeyIdToHex(keyId);
|
return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long convertHexToKeyId(String data) {
|
private static String convertKeyIdToHex32bit(long keyId) {
|
||||||
int len = data.length();
|
String hexString = Long.toHexString(keyId & 0xffffffffL).toLowerCase(Locale.US);
|
||||||
String s2 = data.substring(len - 8);
|
while (hexString.length() < 8) {
|
||||||
String s1 = data.substring(0, len - 8);
|
hexString = "0" + hexString;
|
||||||
|
}
|
||||||
|
return hexString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in HkpKeyServer to convert hex encoded key ids back to long.
|
||||||
|
*
|
||||||
|
* @param hexString
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static long convertHexToKeyId(String hexString) {
|
||||||
|
int len = hexString.length();
|
||||||
|
String s2 = hexString.substring(len - 8);
|
||||||
|
String s1 = hexString.substring(0, len - 8);
|
||||||
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
|
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits userId string into naming part, email part, and comment part
|
* Splits userId string into naming part, email part, and comment part
|
||||||
*
|
*
|
||||||
* @param userId
|
* @param userId
|
||||||
* @return array with naming (0), email (1), comment (2)
|
* @return array with naming (0), email (1), comment (2)
|
||||||
*/
|
*/
|
||||||
public static String[] splitUserId(String userId) {
|
public static String[] splitUserId(String userId) {
|
||||||
String[] result = new String[] { null, null, null };
|
String[] result = new String[]{null, null, null};
|
||||||
|
|
||||||
if (userId == null || userId.equals("")) {
|
if (userId == null || userId.equals("")) {
|
||||||
return result;
|
return result;
|
||||||
@@ -547,7 +539,6 @@ public class PgpKeyHelper {
|
|||||||
result[0] = matcher.group(1);
|
result[0] = matcher.group(1);
|
||||||
result[1] = matcher.group(3);
|
result[1] = matcher.group(3);
|
||||||
result[2] = matcher.group(2);
|
result[2] = matcher.group(2);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -341,10 +341,10 @@ public class ProviderHelper {
|
|||||||
long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
|
long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
boolean has_private = true;
|
boolean hasPrivate = true;
|
||||||
if (key.isMasterKey()) {
|
if (key.isMasterKey()) {
|
||||||
if (PgpKeyHelper.isSecretKeyPrivateEmpty(key)) {
|
if (key.isPrivateKeyEmpty()) {
|
||||||
has_private = false;
|
hasPrivate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,8 +352,8 @@ public class ProviderHelper {
|
|||||||
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
||||||
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
|
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
|
||||||
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
|
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
|
||||||
values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && has_private));
|
values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && hasPrivate));
|
||||||
values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && has_private));
|
values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && hasPrivate));
|
||||||
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
||||||
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
|
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
|
||||||
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
|
|||||||
} else if (extras.containsKey(EXTRA_KEY_ID)) {
|
} else if (extras.containsKey(EXTRA_KEY_ID)) {
|
||||||
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
|
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
|
||||||
if (keyId != 0) {
|
if (keyId != 0) {
|
||||||
query = "0x" + PgpKeyHelper.convertKeyToHex(keyId);
|
query = PgpKeyHelper.convertKeyIdToHex(keyId);
|
||||||
}
|
}
|
||||||
} else if (extras.containsKey(EXTRA_FINGERPRINT)) {
|
} else if (extras.containsKey(EXTRA_FINGERPRINT)) {
|
||||||
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
|
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
// get key id from MASTER_KEY_ID
|
// get key id from MASTER_KEY_ID
|
||||||
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
|
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
|
||||||
|
|
||||||
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
|
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
|
||||||
mKeyId.setText(keyIdStr);
|
mKeyId.setText(keyIdStr);
|
||||||
|
|
||||||
// get creation date from CREATION
|
// get creation date from CREATION
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
|
|||||||
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
|
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
|
||||||
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
|
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
|
||||||
.getFingerprint(), true);
|
.getFingerprint(), true);
|
||||||
this.hexKeyId = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
|
this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
|
||||||
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
|
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
|
||||||
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
|
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
|
||||||
if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL
|
if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
|
|||||||
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
|
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
|
||||||
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
|
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
|
||||||
|
|
||||||
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
|
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
|
||||||
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm),
|
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm),
|
||||||
cursor.getInt(mIndexKeySize));
|
cursor.getInt(mIndexKeySize));
|
||||||
|
|
||||||
|
|||||||
@@ -174,9 +174,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
|
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
|
||||||
String keyId1Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
|
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
|
||||||
String keyId2Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID() >> 32);
|
mKeyId.setText(keyIdStr);
|
||||||
mKeyId.setText(keyId1Str + " " + keyId2Str);
|
|
||||||
|
|
||||||
Vector<Choice> choices = new Vector<Choice>();
|
Vector<Choice> choices = new Vector<Choice>();
|
||||||
boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT);
|
boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT);
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
HttpClient client = new DefaultHttpClient();
|
HttpClient client = new DefaultHttpClient();
|
||||||
try {
|
try {
|
||||||
HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
|
HttpGet get = new HttpGet("http://" + mHost + ":" + mPort
|
||||||
+ "/pks/lookup?op=get&search=0x" + PgpKeyHelper.convertKeyToHex(keyId));
|
+ "/pks/lookup?op=get&search=0x" + PgpKeyHelper.convertKeyIdToHex(keyId));
|
||||||
|
|
||||||
HttpResponse response = client.execute(get);
|
HttpResponse response = client.execute(get);
|
||||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:stretchColumns="1">
|
android:shrinkColumns="1">
|
||||||
|
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user