@Override public Collection<AbstractKey> findKey(KeyInfo keyInfo) { ArrayList results = new ArrayList(); if (info().matchType(keyInfo)) results.add(AbstractKey.this); return results; } };
/** * See {@link #matchType(KeyInfo)} for details. * @param otherKey * @return true if itherKey type matches this one's. */ public boolean matchType(AbstractKey otherKey) { return matchType(otherKey.info()); }
public void setTag(byte[] tag) { info().setTag(tag); }
public byte[] packedInfo() { return info().pack(); }
/** * The smart keys search. First keys with matching tags and type, then all others with matching * type. * * @param keyInfo desired key information * @return Collection of matching keys, possibly empty. */ @Override @NonNull public Collection<AbstractKey> findKey(KeyInfo keyInfo) { final ArrayList<AbstractKey> result = new ArrayList<>(); for( AbstractKey k: keys) { final KeyInfo ki = k.info(); if( ki.matchType(keyInfo) ) { if( ki.matchTag(keyInfo) ) result.add(0, k); else result.add(k); } } return result; }
/** * Each supported key has a mask that represents its type. The key that has no known mask can't be processed bt the * address. * * @param k * key to calculate mask of. * * @return */ protected static int mask(AbstractKey k) { KeyInfo i = k.info(); switch (i.getAlgorythm()) { case RSAPublic: case RSAPrivate: if (((PublicKey) k).getPublicExponent() == 0x10001) { int l = i.getKeyLength(); if (l == 2048 / 8) return 0x01; if (l == 4096 / 8) return 0x02; } break; } throw new IllegalArgumentException("key can't be masked for address: " + i); }
@Override public KeyInfo info() { if (keyInfo == null) { KeyInfo i = getPublicKey().info(); keyInfo = new KeyInfo(KeyInfo.Algorythm.RSAPrivate, i.getTag(), privateKey .getBitStrength() / 8); } return super.info(); }
@Test public void matchTypeAndTag() throws Exception { // 2 different private keys AbstractKey k1 = TestKeys.privateKey(0); AbstractKey k2 = TestKeys.privateKey(1); assertTrue(k1.info().matchType(k2.info())); assertFalse(k1.info().matchTag(k2.info())); // public matches private, not vice versa AbstractKey k3 = k1.getPublicKey(); assertTrue(k1.info().matchType(k3.info())); assertFalse(k3.info().matchType(k1.info())); assertTrue(k1.info().matchTag(k3.info())); // public keys do not match each other! assertFalse(k3.info().matchType(k3.info())); assertFalse(k3.info().matchType(k2.getPublicKey().info())); // Check AES match algorythm and tag AbstractKey k4 = new SymmetricKey(); assertFalse(k2.matchType(k4)); assertFalse(k3.matchType(k4)); assertFalse(k4.matchType(k2)); assertFalse(k4.matchType(k3)); assertFalse(k4.matchTag(k2)); assertFalse(k4.matchTag(k3)); AbstractKey k5 = new SymmetricKey(); assertTrue(k4.matchType(k5)); assertTrue(k5.matchType(k4)); assertFalse(k4.matchTag(k5)); k4.setTag("Hello"); k5.setTag("Hello"); }
@Test public void privateKeyMustHaveInfo() throws Exception { AbstractKey prk = TestKeys.privateKey(3); AbstractKey puk = prk.getPublicKey(); KeyInfo h = prk.info(); assertEquals(KeyInfo.Algorythm.RSAPrivate, h.getAlgorythm()); assertEquals(KeyInfo.PRF.None, h.getPRF()); assertEquals(5, h.getTag().length); assertArrayEquals(puk.info().getTag(), h.getTag()); // Bytes.dump(h.pack()); }
@Test public void publicKeyMustHaveInfo() throws Exception { AbstractKey k = TestKeys.privateKey(3).getPublicKey(); KeyInfo h = k.info(); assertEquals(KeyInfo.Algorythm.RSAPublic, h.getAlgorythm()); assertEquals(KeyInfo.PRF.None, h.getPRF()); assertEquals(5, h.getTag().length); // Bytes.dump(h.pack()); }
@Test public void findKey() throws Exception { KeyInfo i1 = new KeyInfo(KeyInfo.PRF.HMAC_SHA256, 1024, null, null); AbstractKey pk1 = i1.derivePassword("helluva"); KeyInfo i2 = new KeyInfo(KeyInfo.PRF.HMAC_SHA256, 1025, null, "the tag".getBytes()); AbstractKey pk2 = i2.derivePassword("helluva"); assertEquals(i2.getTag(), pk2.info().getTag()); KeyRing kr = new KeyRing(); SymmetricKey sk1 = new SymmetricKey(); SymmetricKey sk2 = new SymmetricKey(); AbstractKey privateKey = TestKeys.privateKey(0); AbstractKey publicKey1 =TestKeys.privateKey(1).getPublicKey(); AbstractKey publicKey2 = privateKey.getPublicKey(); kr.addKeys( sk1, sk2, privateKey, publicKey1, publicKey2, pk1, pk2 ); kr.addKeys(pk1, pk2); Binder b = kr.toBinder(); KeyRing kr2 = KeyRing.fromBinder(b); assertTrue(kr.keySet().contains(pk1)); assertTrue(kr.keySet().contains(pk2)); assertEquals(pk2, kr.findKey(i2).toArray()[0]); assertEquals(pk2, kr2.findKey(i2).toArray()[0]); final Collection<AbstractKey> keys = kr.findKey(i1); assertTrue(keys.contains(pk1)); assertTrue(keys.contains(pk1)); assertTrue(keys.contains(sk1)); assertTrue(keys.contains(sk2)); assertEquals(4, kr2.findKey(i1).size()); }