Browse Source

Refs #21 Load / store GPG key in Uber key store

isundil 7 years ago
parent
commit
b131a4c2b6

+ 1 - 1
app/src/main/java/info/knacki/pass/io/pgp/GPGStorageEngine.java

@@ -16,7 +16,7 @@ public class GPGStorageEngine {
     public static IGPGStorage GetDefaultEngine(Context ctx) {
         if (fDefaultEngine == null) {
             synchronized (GPGStorageEngine.class) {
-                return fDefaultEngine = new SharedPreferenceGPGStorage(ctx);
+                return fDefaultEngine = new UberGPGStorage(ctx);
             }
         }
         return fDefaultEngine;

+ 26 - 52
app/src/main/java/info/knacki/pass/io/pgp/UberGPGStorage.java

@@ -24,12 +24,8 @@ import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.UnrecoverableEntryException;
 import java.security.cert.CertificateException;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -43,31 +39,26 @@ public class UberGPGStorage implements GPGStorageEngine.IGPGStorage {
     private static final Logger log = Logger.getLogger(UberGPGStorage.class.getName());
     private final Context fContext;
 
+    private final static String KEY_NAME = "sbcKey";
     private final static String KEY_PASS = UberGPGStorage.class.getName()+"___PASSWORD";
 
     UberGPGStorage(Context ctx) {
         fContext = ctx;
     }
 
-    private Map<String, KeyStore.SecretKeyEntry> FindSecretKey(@NonNull byte[] in) throws IOException {
-        final PGPSecretKeyRingCollection pgpSec;
-        final HashMap<String, KeyStore.SecretKeyEntry> keyring = new HashMap<>();
-
+    private PGPSecretKeyRingCollection FindKeyring(@NonNull byte[] in) throws IOException {
         try {
-            pgpSec = new PGPSecretKeyRingCollection(in, new JcaKeyFingerprintCalculator());
+            return new PGPSecretKeyRingCollection(in, new JcaKeyFingerprintCalculator());
         } catch (PGPException e) {
             throw new GPGUtil.MalformedKeyException(e);
         }
-        Iterator<PGPSecretKeyRing> rIt = pgpSec.getKeyRings();
-        while (rIt.hasNext()) {
-            for (Iterator<PGPSecretKey> it = rIt.next().getSecretKeys(); it.hasNext(); ) {
-                PGPSecretKey key = it.next();
-                keyring.put(String.format("%X", key.getKeyID()), new KeyStore.SecretKeyEntry(new SecretKeySpec(key.getEncoded(), "AES")));
-            }
-        }
-        if (keyring.isEmpty())
-            throw new NoSuchElementException("GPG key not found");
-        return keyring;
+    }
+
+    private KeyStore.SecretKeyEntry FindSecretKey(@NonNull byte[] in) throws IOException {
+        Iterator<PGPSecretKeyRing> kr = FindKeyring(in).iterator();
+        if (kr.hasNext())
+            return new KeyStore.SecretKeyEntry(new SecretKeySpec(kr.next().getEncoded(), "AES"));
+        return null;
     }
 
     private KeyStore GetKeystore(boolean read) {
@@ -106,7 +97,7 @@ public class UberGPGStorage implements GPGStorageEngine.IGPGStorage {
     public boolean HasGPGKey() {
         try {
             KeyStore ks = GetKeystore(true);
-            return ks != null && ks.aliases().hasMoreElements();
+            return ks != null && ks.containsAlias(KEY_NAME);
         } catch (KeyStoreException e) {
             log.log(Level.SEVERE, "KeyStore Exception: " +e.getMessage(), e);
             return false;
@@ -119,9 +110,8 @@ public class UberGPGStorage implements GPGStorageEngine.IGPGStorage {
         if (ks == null)
             return false;
         try {
-            Map<String, KeyStore.SecretKeyEntry> keyring = FindSecretKey(FileUtils.ReadAllStream(content));
-            for (Map.Entry<String, KeyStore.SecretKeyEntry> i: keyring.entrySet())
-                ks.setEntry(i.getKey(), i.getValue(), new KeyStore.PasswordProtection(null));
+            KeyStore.SecretKeyEntry keyring = FindSecretKey(FileUtils.ReadAllStream(content));
+            ks.setEntry(KEY_NAME, keyring, new KeyStore.PasswordProtection(null));
             SaveKeystore(ks);
         } catch (KeyStoreException | IOException e) {
             log.log(Level.SEVERE, "Cannot set GPG key content", e);
@@ -130,20 +120,14 @@ public class UberGPGStorage implements GPGStorageEngine.IGPGStorage {
         return true;
     }
 
-    private @NonNull Map<String, KeyStore.SecretKeyEntry> GetGPGKeyContent() throws FileNotFoundException {
+    private @NonNull KeyStore.SecretKeyEntry GetGPGKeyContent() throws FileNotFoundException {
         if (!HasGPGKey())
             throw new FileNotFoundException("GPG key");
         KeyStore ks = GetKeystore(true);
         if (ks == null)
             throw new FileNotFoundException("GPG key store");
-        HashMap<String, KeyStore.SecretKeyEntry> keys = new HashMap<>();
         try {
-            Enumeration<String> aliases = ks.aliases();
-            while (aliases.hasMoreElements()) {
-                String keyId = aliases.nextElement();
-                keys.put(keyId, (KeyStore.SecretKeyEntry) ks.getEntry(keyId, null));
-            }
-            return keys;
+            return (KeyStore.SecretKeyEntry) ks.getEntry(KEY_NAME, null);
         } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableEntryException e) {
             log.log(Level.SEVERE, "KeyStore Exception: " +e.getMessage(), e);
             throw new FileNotFoundException("GPG key store");
@@ -161,42 +145,32 @@ public class UberGPGStorage implements GPGStorageEngine.IGPGStorage {
 
     @Override
     public @NonNull PGPSecretKeyRing GetGPGKeyRing() throws IOException {
-        final PGPSecretKeyRingCollection pgpSec;
+        KeyStore.SecretKeyEntry secretKey = GetGPGKeyContent();
 
         try {
-            Map<String, KeyStore.SecretKeyEntry> secretKeys = GetGPGKeyContent();
-            ArrayList<PGPSecretKey> keys = new ArrayList<>();
-            for (Map.Entry<String, KeyStore.SecretKeyEntry> keyData: secretKeys.entrySet()) {
-                PGPSecretKeyRingCollection key = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(new ByteArrayInputStream(keyData.getValue().getSecretKey().getEncoded())), new JcaKeyFingerprintCalculator());
-                for (Iterator<PGPSecretKeyRing> it = key.getKeyRings(); it.hasNext(); ) {
-                    for (Iterator<PGPSecretKey> it1 = it.next().getSecretKeys(); it1.hasNext(); ) {
-                        PGPSecretKey pgpSecKey = it1.next();
-                        log.severe(String.format("Found key in load: %X", pgpSecKey.getKeyID()));
-                        keys.add(pgpSecKey);
-                    }
-                }
-            }
-            pgpSec = new PGPSecretKeyRingCollection(Collections.singleton(new PGPSecretKeyRing(keys)));
+            Iterator<PGPSecretKeyRing> keyrings = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(new ByteArrayInputStream(secretKey.getSecretKey().getEncoded())), new JcaKeyFingerprintCalculator()).iterator();
+            if (keyrings.hasNext())
+                return keyrings.next();
         } catch (PGPException e) {
+            log.log(Level.WARNING, "Cannot load key: " + e.getMessage(), e);
             throw new GPGUtil.MalformedKeyException(e);
         }
-        Iterator<PGPSecretKeyRing> rIt = pgpSec.getKeyRings();
-        if (rIt.hasNext())
-            return rIt.next();
         throw new NoSuchElementException("GPG key not found");
     }
 
     @Override
     public @NonNull PGPSecretKey GetGPGSecretKey() throws IOException {
-        return GetGPGKeyRing().getSecretKey();
+        PGPSecretKey key = GetGPGKeyRing().getSecretKey();
+        if (key == null)
+            throw new FileNotFoundException("Key");
+        return key;
     }
 
     @Override
     public @NonNull PGPSecretKey GetGPGSecretKey(long keyId) throws IOException {
-        PGPSecretKeyRing kr = GetGPGKeyRing();
-        PGPSecretKey key = kr.getSecretKey(keyId);
+        PGPSecretKey key = GetGPGKeyRing().getSecretKey(keyId);
         if (key == null)
-            throw new IOException(String.format("Key %X", keyId));
+            throw new FileNotFoundException(String.format("Key %X", keyId));
         return key;
     }