String pictureBase64 = properties.getProperty(prefix + "picture"); String text = properties.getProperty(prefix + "text"); Contact contact = new Contact(name, destination, pictureBase64, text);
protected Properties saveToProperties() { SortedProperties properties = new SortedProperties(); int index = 0; for (Contact contact: contacts) { String prefix = "contact" + index + "."; properties.setProperty(prefix + "name", contact.getName()); String base64Dest = contact.getDestination().toBase64(); properties.setProperty(prefix + "destination", base64Dest); String pictureBase64 = contact.getPictureBase64(); properties.setProperty(prefix + "picture", (pictureBase64==null ? "" : pictureBase64)); String text = contact.getText(); properties.setProperty(prefix + "text", (text==null ? "" : text)); index++; } return properties; }
private byte[] getDataToSign() { byte[] data = toByteArray(); int sigLen = signature==null ? 2 : signature.length+2; // the sig length and the 2 length bytes data = Arrays.copyOf(data, data.length-sigLen); return data; }
@Override public int compare(Contact contact1, Contact contact2) { int nameComparison = String.CASE_INSENSITIVE_ORDER.compare(contact1.getName(), contact2.getName()); if (nameComparison == 0) { // if the names are the same, compare destination keys String key1 = contact1.getDestination().getKey(); String key2 = contact2.getDestination().getKey(); return key1.compareTo(key2); } else return nameComparison; } }
@Test public void toByteArrayAndBack() throws IOException, GeneralSecurityException { WordListAnchor wordLists = new WordListAnchor(); String[] wordListEN = wordLists.getWordList("en"); String[] wordListDE = wordLists.getWordList("de"); byte[] arrayA = contact.toByteArray(); Contact contact2 = new Contact(arrayA); assertEquals(contact.getName(), contact2.getName()); assertEquals(contact.getDestination().toBase64(), contact2.getDestination().toBase64()); assertEquals(contact.getText(), contact2.getText()); assertEquals(contact.getFingerprint().getWords(wordListDE), contact2.getFingerprint().getWords(wordListDE)); assertEquals(contact.getFingerprint().getWords(wordListEN), contact2.getFingerprint().getWords(wordListEN)); assertFalse(contact.getFingerprint().getWords(wordListEN).equals(contact2.getFingerprint().getWords(wordListDE))); assertEquals(contact.getPictureBase64(), contact2.getPictureBase64()); byte[] arrayB = contact2.toByteArray(); assertArrayEquals("The two arrays differ!", arrayA, arrayB); }
@Test public void testSignatureAndFingerprint() throws GeneralSecurityException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { assertTrue(contact.verify()); // change the name char[] chars = contactName.toCharArray(); chars[0]++; String alteredName = new String(chars); contact.setName(alteredName); assertFalse(contact.verify()); // restore the original name and make the salt invalid contact.setName(contactName); Fingerprint fingerprint = contact.getFingerprint(); Field saltField = Fingerprint.class.getDeclaredField("salt"); saltField.setAccessible(true); byte[] salt = (byte[])saltField.get(fingerprint); salt[2]++; assertFalse(contact.verify()); // restore salt salt[2]--; assertTrue(contact.verify()); } }
contact.setName(name); contact.setPictureBase64(pictureBase64); contact.setText(text); return e.getLocalizedMessage(); contact = new Contact(name, destination, pictureBase64, text); addressBook.add(contact);
return contact.getName() + " <" + contact.getBase64Dest() + "@bote>"; // TODO: Make @bote optional
public Contact lookupInDirectory(String name) throws InterruptedException { Hash key = EmailIdentity.calculateHash(name); if(null == dht){ return null; } DhtResults results = dht.findOne(key, Contact.class); if (!results.isEmpty()) { DhtStorablePacket packet = results.getPackets().iterator().next(); if (packet instanceof Contact) { Contact contact = (Contact)packet; try { if (contact.verify()) return contact; } catch (GeneralSecurityException e) { log.error("Can't verify Contact", e); } } } return null; }
public static String getFingerprint(Contact contact, String localeCode) throws GeneralSecurityException { String[] wordList = I2PBote.getInstance().getWordList(localeCode); Fingerprint fingerprint = contact.getFingerprint(); return fingerprint==null ? null : fingerprint.getWords(wordList); }
return contact.getName();
/** Tests if a packet is stored if it contains an invalid signature */ @Test public void testStoreInvalid() { assertEquals(0, folder.getNumElements()); // try adding an invalid Contact char[] chars = contact12Name.toCharArray(); chars[0]++; String alteredName = new String(chars); contact1.setName(alteredName); assertEquals(0, folder.getNumElements()); }
/** Tests if a new packet replaces an existing one when the names match (it shouldn't) */ @Test public void testStoreExisting() { assertEquals(0, folder.getNumElements()); folder.store(contact1); assertEquals(1, folder.getNumElements()); folder.store(contact2); assertEquals(1, folder.getNumElements()); assertTrue("Contact in the folder was overwritten!", folder.iterator().next().getDestination().toBase64().equals(contact1.getDestination().toBase64())); assertTrue("Contact in the folder was overwritten!", !folder.iterator().next().getDestination().toBase64().equals(contact2.getDestination().toBase64())); folder.store(contact3); assertEquals(2, folder.getNumElements()); }
/** * Returns <code>true</code> if a given Base64-encoded Email Destination * is in the address book. * @param base64dest */ public boolean contains(String base64dest) throws PasswordException { initializeIfNeeded(); if (base64dest == null) return false; for (Contact contact: contacts) if (base64dest.equals(contact.getBase64Dest())) return true; return false; }
/** Finds a salt value such that scrypt(nameHash|destination, salt) ends with 10 zero bits */ public static Fingerprint generate(Contact contact) throws GeneralSecurityException { EmailDestination destination = contact.getDestination(); Hash nameHash = EmailIdentity.calculateHash(contact.getName()); return generate(nameHash, destination); }
return contact.getName() + " <" + contact.getBase64Dest() + ">";
@Override public void store(DhtStorablePacket packetToStore) { File packetFile = findPacketFile(packetToStore.getDhtKey()); if (packetFile != null) log.debug("Not storing directory packet with DHT key " + packetToStore.getDhtKey() + " because file exists."); else { if (!(packetToStore instanceof Contact)) log.error("Expected class Contact, got " + packetToStore.getClass()); else { Contact contact = (Contact)packetToStore; try { if (!contact.verify()) log.debug("Not storing Contact because verification failed."); else super.store(packetToStore); } catch (GeneralSecurityException e) { log.error("Can't verify Contact", e); } } } } }
/** * Looks up an {@link Contact} by its Base64 key. If none is found, * <code>null</code> is returned. * @param destination */ public Contact get(String destination) throws PasswordException { initializeIfNeeded(); if (contacts==null || destination==null || destination.isEmpty()) return null; for (Contact contact: contacts) if (destination.equals(contact.getBase64Dest())) return contact; return null; }
@Before public void setUp() throws Exception { File tempDir = new File(System.getProperty("java.io.tmpdir")); testDir = new File(tempDir, "DirectoryEntryFolderTest-" + System.currentTimeMillis()); folderDir = new File(testDir, "folder"); folder = new DirectoryEntryFolder(folderDir); // contact1 and contact2 contain the same name; name in contact3 is different contact1 = new Contact(Base64.decode("QwSlRwEi0IY-mEz6owJfWVG-dZe2qHIcKFKyD8FvdEvdRwBCAxvGHjFocWgadAsrUqFspuWyRrpoa5Hh~SsFBxFjeTZ6Atx~IqWbtxt3pV5fzHLkvgFHx0jpTgIStssa98sD5NIU3unfuQAAAAAAAEgwRgIhAP2-AGnl0Jlpss4rXsAseDCelq~lwbMOtWKimogddYOvAiEAwdMyV12F0N9hQVnns0Zx3MMgoUlDozvGB1CZmx9ZGkA=")); contact2 = new Contact(Base64.decode("QwSlRwEi0IY-mEz6owJfWVG-dZe2qHIcKFKyD8FvdEvdRwBCAt6JpsgAD~TrlH~bafT0CvUPk5jfQDcISB2IG6hCE1ASA1kh3urYt29bPVvhaRh2gDFk2eyz-MZRoMpZLz7hwpyrl783YwAAAAAAAEYwRAIgRlI6aoQ1tdUp5xAFHdh3Wm9bT6HvyWh8WkMgNwIWMQcCIBBCHzXcOD-xe3-CqRO2cWLvXCDFed5zmE7oEctVpbcQ")); contact3 = new Contact(Base64.decode("QwRwRpWqx-xkTC4mYzMJkJtryurqpo0vee2Qnq8uVXD92wBCA5J75fef~d-1BaJZyrP6Y9uYn3~tki2Vie5Fq7jTT7dbAyYGb-PF~7pxIxJwh0lAYALrIgtIt4uaG67xm739FYkBa1b2gwAAAAAAAEcwRQIgGgf3vd28-1YyUN41VLfszN0Nu9xC--LA2is5EJNq8a8CIQDyCK4GSDh1V2hmORmEzmF8xyazB1P~QbtVJHiognSSNA==")); }
private void migrateAddressBook(List<String> lines, Configuration configuration, PasswordHolder passwordHolder) throws IOException, GeneralSecurityException, PasswordException { AddressBook addressBook = new AddressBook(configuration.getAddressBookFile(), passwordHolder); for (String line: lines) { String[] fields = line.split("\\t", 2); try { EmailDestination destination = new EmailDestination(fields[0]); String name = null; if (fields.length > 1) name = fields[1]; Contact contact = new Contact(name, destination); addressBook.add(contact); } catch (GeneralSecurityException e) { log.error("Not a valid Email Destination: <" + fields[0] + ">", e); } } addressBook.save(); } }