Skip to content

Commit

Permalink
v1.0 (build 216)
Browse files Browse the repository at this point in the history
  • Loading branch information
finiasz committed Oct 16, 2023
1 parent 39df8c4 commit 3a37281
Show file tree
Hide file tree
Showing 219 changed files with 14,454 additions and 3,055 deletions.
45 changes: 44 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,47 @@
# Build 207 (0.15.0)
# Build 216 (1.0)
2023-10-10

- Fixes for compatibility with iOS and Windows versions

# ~~Build 215 (1.0)~~
2023-10-07

- Final adjustments to the transfer protocol

# ~~Build 214 (1.0)~~
2023-09-30

- Several improvements to the transfer protocol
- Notifications when a new device is added or the current device is set to be deactivated

# ~~Build 213 (1.0)~~
2023-09-27

- Fix keycloak issue in the transfer protocol

# ~~Build 211 (1.0)~~
2023-09-26

- Android 14 compatibility
- Transfer protocol: copy a profile to a new device without using a backup/restore

# Build 210 (0.15.0.3)
2023-09-05

- Fix for a bug in engine backup manager
- Update SQLite JDBC to 3.42.0.1

# Build 209 (0.15.0.2)
2023-08-11

- Hotfix for a crash on weird Markdown input

# Build 208 (0.15.0.1)
2023-08-03

- Hotfix for a billing library crash

# Build 207 (0.15.0)
2023-07-31

- Minor fixes for group types
Expand Down
11 changes: 6 additions & 5 deletions obv_engine/engine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ repositories {
}

dependencies {
// do not update further: jackson >2.13 does not work on older Android APIs
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'
implementation files('libs/sqlite-jdbc-3.41.2.1.jar')
implementation files('libs/sqlite-jdbc-3.42.0.1.jar')

implementation 'org.slf4j:slf4j-api:2.0.7'
implementation 'org.slf4j:slf4j-simple:2.0.7'
implementation 'org.slf4j:slf4j-api:2.0.9'
implementation 'org.slf4j:slf4j-simple:2.0.9'

implementation 'org.bitbucket.b_c:jose4j:0.9.3'

implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
implementation 'net.iharder:base64:2.3.9'

testImplementation 'junit:junit:4.13.2'
testImplementation 'org.xerial:sqlite-jdbc:3.41.2.1' // only here to check if a new version is available
testImplementation 'org.xerial:sqlite-jdbc:3.42.0.1' // only here to check if a new version is available
}
Binary file removed obv_engine/engine/libs/sqlite-jdbc-3.41.2.1.jar
Binary file not shown.
Binary file added obv_engine/engine/libs/sqlite-jdbc-3.42.0.1.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,7 @@ public int verifyBackupKey(String seedString) {
BackupSeed backupSeed = new BackupSeed(seedString);
BackupSeed.DerivedKeys derivedKeys = backupSeed.deriveKeys();

if (derivedKeys.backupKeyUid.equals(backupKey.getUid()) &&
derivedKeys.macKey.equals(backupKey.getMacKey()) &&
if (derivedKeys.macKey.equals(backupKey.getMacKey()) &&
derivedKeys.encryptionKeyPair.getPublicKey().equals(backupKey.getEncryptionPublicKey())) {
// we have the same keys, everything is fine
backupKey.addSuccessfulVerification();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import io.olvid.engine.Logger;
import io.olvid.engine.backup.datatypes.BackupManagerSession;
import io.olvid.engine.crypto.Suite;
import io.olvid.engine.datatypes.ObvDatabase;
import io.olvid.engine.datatypes.Session;
import io.olvid.engine.datatypes.UID;
Expand Down Expand Up @@ -175,13 +176,59 @@ public static void createTable(Session session) throws SQLException {
UPLOADED_BACKUP_VERSION + " INTEGER, " +
EXPORTED_BACKUP_VERSION + " INTEGER, " +
LATEST_BACKUP_VERSION + " INTEGER, " +
"FOREIGN KEY (" + UID_ + "," + UPLOADED_BACKUP_VERSION + ") REFERENCES " + Backup.TABLE_NAME + " (" + Backup.BACKUP_KEY_UID + "," + Backup.VERSION + ") ON DELETE SET NULL, " +
"FOREIGN KEY (" + UID_ + "," + EXPORTED_BACKUP_VERSION + ") REFERENCES " + Backup.TABLE_NAME + " (" + Backup.BACKUP_KEY_UID + "," + Backup.VERSION + ") ON DELETE SET NULL, " +
"FOREIGN KEY (" + UID_ + "," + LATEST_BACKUP_VERSION + ") REFERENCES " + Backup.TABLE_NAME + " (" + Backup.BACKUP_KEY_UID + "," + Backup.VERSION + ") ON DELETE SET NULL);");
"FOREIGN KEY (" + UID_ + "," + UPLOADED_BACKUP_VERSION + ") REFERENCES " + Backup.TABLE_NAME + " (" + Backup.BACKUP_KEY_UID + "," + Backup.VERSION + "), " +
"FOREIGN KEY (" + UID_ + "," + EXPORTED_BACKUP_VERSION + ") REFERENCES " + Backup.TABLE_NAME + " (" + Backup.BACKUP_KEY_UID + "," + Backup.VERSION + "), " +
"FOREIGN KEY (" + UID_ + "," + LATEST_BACKUP_VERSION + ") REFERENCES " + Backup.TABLE_NAME + " (" + Backup.BACKUP_KEY_UID + "," + Backup.VERSION + "));");
}
}

public static void upgradeTable(Session session, int oldVersion, int newVersion) throws SQLException {
if (oldVersion < 36 && newVersion >= 36) {
Logger.d("MIGRATING `backup_key` DATABASE FROM VERSION " + oldVersion + " TO 36");
try (Statement statement = session.createStatement()) {
statement.execute("CREATE TABLE backup_key_new (" +
" uid BLOB PRIMARY KEY, " +
" encryption_public_key BLOB NOT NULL, " +
" mac_key BLOB NOT NULL, " +
" key_generation_timestamp INTEGER NOT NULL, " +
" last_successful_key_verification_timestamp INTEGER NOT NULL, " +
" last_key_verification_prompt_timestamp INTEGER NOT NULL, " +
" successful_verification_count INTEGER NOT NULL, " +
" uploaded_backup_version INTEGER, " +
" exported_backup_version INTEGER, " +
" latest_backup_version INTEGER, " +
"FOREIGN KEY (uid, uploaded_backup_version) REFERENCES backup (backup_key_uid, version), " +
"FOREIGN KEY (uid, exported_backup_version) REFERENCES backup (backup_key_uid, version), " +
"FOREIGN KEY (uid, latest_backup_version) REFERENCES backup (backup_key_uid, version));");

ResultSet res = statement.executeQuery("SELECT * FROM backup_key WHERE uid IS NULL");
if (res.next()) {
// we have a null primary key --> copy it partially to new table
try (PreparedStatement ps = session.prepareStatement("INSERT INTO backup_key_new VALUES (?,?,?,?,?, ?,?,?,?,?)")) {
ps.setBytes(1, new UID(Suite.getDefaultPRNGService(Suite.LATEST_VERSION)).getBytes());
ps.setBytes(2, res.getBytes("encryption_public_key"));
ps.setBytes(3, res.getBytes("mac_key"));
ps.setLong(4, res.getLong("key_generation_timestamp"));
ps.setLong(5, res.getLong("last_successful_key_verification_timestamp"));
ps.setLong(6, res.getLong("last_key_verification_prompt_timestamp"));
ps.setInt(7, res.getInt("successful_verification_count"));
ps.setNull(8, Types.INTEGER);
ps.setNull(9, Types.INTEGER);
ps.setNull(10, Types.INTEGER);
ps.executeUpdate();
}
// delete all existing backups (the backup_key_uid no longer exists)
statement.execute("DELETE FROM backup");
} else {
// no null primary key, simply copy the content of the old table to the new one
statement.execute("INSERT into backup_key_new (uid, encryption_public_key, mac_key, key_generation_timestamp, last_successful_key_verification_timestamp, last_key_verification_prompt_timestamp, successful_verification_count, uploaded_backup_version, exported_backup_version, latest_backup_version) SELECT uid, encryption_public_key, mac_key, key_generation_timestamp, last_successful_key_verification_timestamp, last_key_verification_prompt_timestamp, successful_verification_count, uploaded_backup_version, exported_backup_version, latest_backup_version FROM backup_key");
}
statement.execute("DROP TABLE backup_key");
statement.execute("ALTER TABLE backup_key_new RENAME TO backup_key");

}
oldVersion = 36;
}
}

// delete all BackupKey and all Backup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@


import java.sql.SQLException;
import java.util.Objects;

import io.olvid.engine.Logger;
import io.olvid.engine.crypto.PRNGService;
import io.olvid.engine.datatypes.Constants;
import io.olvid.engine.datatypes.Identity;
import io.olvid.engine.datatypes.UID;
import io.olvid.engine.datatypes.containers.ChannelDialogResponseMessageToSend;
Expand Down Expand Up @@ -85,7 +87,8 @@ private static LocalChannel[] acceptableChannelsForPosting(ChannelManagerSession
switch (message.getSendChannelInfo().getChannelType()) {
case SendChannelInfo.LOCAL_TYPE:
// Check that the toIdentity is an OwnedIdentity
if (channelManagerSession.identityDelegate.isOwnedIdentity(channelManagerSession.session, message.getSendChannelInfo().getToIdentity())) {
if (channelManagerSession.identityDelegate.isOwnedIdentity(channelManagerSession.session, message.getSendChannelInfo().getToIdentity())
|| Objects.equals(message.getSendChannelInfo().getToIdentity().getServer(), Constants.EPHEMERAL_IDENTITY_SERVER)) {
return new LocalChannel[]{
new LocalChannel(message.getSendChannelInfo().getToIdentity())
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
package io.olvid.engine.channel.datatypes;

import java.sql.SQLException;
import java.util.Objects;

import io.olvid.engine.Logger;
import io.olvid.engine.crypto.PRNGService;
import io.olvid.engine.datatypes.Constants;
import io.olvid.engine.datatypes.UID;
import io.olvid.engine.datatypes.containers.ChannelMessageToSend;
import io.olvid.engine.datatypes.containers.ChannelServerQueryMessageToSend;
Expand Down Expand Up @@ -65,7 +67,8 @@ private static ServerQueryChannel[] acceptableChannelsForPosting(ChannelManagerS
switch (message.getSendChannelInfo().getChannelType()) {
case SendChannelInfo.SERVER_QUERY_TYPE:
// Check that the toIdentity is an OwnedIdentity
if (channelManagerSession.identityDelegate.isOwnedIdentity(channelManagerSession.session, message.getSendChannelInfo().getToIdentity())) {
if (channelManagerSession.identityDelegate.isOwnedIdentity(channelManagerSession.session, message.getSendChannelInfo().getToIdentity())
|| Objects.equals(message.getSendChannelInfo().getToIdentity().getServer(), Constants.EPHEMERAL_IDENTITY_SERVER)) {
return new ServerQueryChannel[]{
new ServerQueryChannel()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Objects;

import io.olvid.engine.Logger;
import io.olvid.engine.crypto.PRNGService;
import io.olvid.engine.datatypes.Constants;
import io.olvid.engine.datatypes.UID;
import io.olvid.engine.datatypes.containers.ChannelDialogMessageToSend;
import io.olvid.engine.datatypes.containers.ChannelMessageToSend;
Expand Down Expand Up @@ -65,7 +67,8 @@ private static UserInterfaceChannel[] acceptableChannelsForPosting(ChannelManage
switch (message.getSendChannelInfo().getChannelType()) {
case SendChannelInfo.USER_INTERFACE_TYPE:
// Check that the toIdentity is an OwnedIdentity
if (channelManagerSession.identityDelegate.isOwnedIdentity(channelManagerSession.session, message.getSendChannelInfo().getToIdentity())) {
if (channelManagerSession.identityDelegate.isOwnedIdentity(channelManagerSession.session, message.getSendChannelInfo().getToIdentity())
|| Objects.equals(message.getSendChannelInfo().getToIdentity().getServer(), Constants.EPHEMERAL_IDENTITY_SERVER)) {
return new UserInterfaceChannel[]{
new UserInterfaceChannel()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public DerivedKeys deriveKeys() {
}

public static class DerivedKeys {
public final UID backupKeyUid;
public final UID backupKeyUid; // should never be used during backup: a bug fixed in Sept. 2023 may have changed the original value of this in DB
public final EncryptionEciesCurve25519KeyPair encryptionKeyPair;
public final MACKey macKey;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.nio.charset.StandardCharsets;

public abstract class Constants {
public static final int CURRENT_ENGINE_DB_SCHEMA_VERSION = 35;
public static final int CURRENT_ENGINE_DB_SCHEMA_VERSION = 37;
public static final int SERVER_API_VERSION = 15;
public static final int CURRENT_BACKUP_JSON_VERSION = 0;

Expand Down Expand Up @@ -69,6 +69,10 @@ public abstract class Constants {
public static final long GET_USER_DATA_LOCAL_FILE_LIFESPAN = 86_400_000L * 7; // 7 days
public static final long WELL_KNOWN_REFRESH_INTERVAL = 3_600_000L * 6; // 6 hours

// download message
public static final long RELIST_NEW_MESSAGE_COUNT_THRESHOLD = 20; // number of new messages in a single list operation that trigger a re-list
public static final long RELIST_DELAY = 30_000; // 30 seconds

// backups
public static final long AUTOBACKUP_MAX_INTERVAL = 86_400_000L; // 1 day
public static final long AUTOBACKUP_START_DELAY = 60_000L * 2; // 2 minutes
Expand All @@ -91,6 +95,9 @@ public abstract class Constants {
public static final byte[] ANDROID_STORE_ID = new byte[]{0x01};

public static final int DEFAULT_NUMBER_OF_DIGITS_FOR_SAS = 4;
public static final String EPHEMERAL_IDENTITY_SERVER = "ephemeral_fake_server";
public static final String TRANSFER_WS_SERVER_URL = "wss://transfer.olvid.io";
public static final int TRANSFER_MAX_PAYLOAD_SIZE = 10000;


public static final long BASE_RESCHEDULING_TIME = 250L;
Expand All @@ -104,7 +111,6 @@ public abstract class Constants {
// prefixes for various types of signature

public static final int SIGNATURE_PADDING_LENGTH = 16;

public enum SignatureContext {
SERVER_AUTHENTICATION,
MUTUAL_SCAN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Identity(String server, ServerAuthenticationPublicKey serverAuthenticatio
this.identityBytes = null;
}

public Identity(String server, ServerAuthenticationPublicKey serverAuthenticationPublicKey, EncryptionPublicKey encryptionPublicKey, byte[] identityBytes) {
private Identity(String server, ServerAuthenticationPublicKey serverAuthenticationPublicKey, EncryptionPublicKey encryptionPublicKey, byte[] identityBytes) {
this.server = server;
this.serverAuthenticationPublicKey = serverAuthenticationPublicKey;
this.encryptionPublicKey = encryptionPublicKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
public class ChannelServerResponseMessageToSend implements ChannelMessageToSend {

private final SendChannelInfo sendChannelInfo;
private final Encoded encodedElements;
private final Encoded encodedServerResponse;
private final Encoded encodedElements;

public ChannelServerResponseMessageToSend(Identity toIdentity, Encoded encodedServerResponse, Encoded encodedElements) {
this.sendChannelInfo = SendChannelInfo.createLocalChannelInfo(toIdentity);
this.encodedElements = encodedElements;
this.encodedServerResponse = encodedServerResponse;
this.encodedElements = encodedElements;
}

@Override
Expand Down
Loading

0 comments on commit 3a37281

Please sign in to comment.