Identify certificates by fingerprint

pull/168/head
M66B 5 years ago
parent d92777b692
commit a2bb26e086

File diff suppressed because it is too large Load Diff

@ -56,7 +56,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html // https://developer.android.com/topic/libraries/architecture/room.html
@Database( @Database(
version = 117, version = 118,
entities = { entities = {
EntityIdentity.class, EntityIdentity.class,
EntityAccount.class, EntityAccount.class,
@ -1140,6 +1140,21 @@ public abstract class DB extends RoomDatabase {
db.execSQL("CREATE INDEX IF NOT EXISTS `index_certificate_email` ON `certificate` (`email`)"); db.execSQL("CREATE INDEX IF NOT EXISTS `index_certificate_email` ON `certificate` (`email`)");
} }
}) })
.addMigrations(new Migration(117, 118) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("DROP TABLE IF EXISTS `certificate`");
db.execSQL("CREATE TABLE IF NOT EXISTS `certificate`" +
" (`id` INTEGER PRIMARY KEY AUTOINCREMENT" +
", `fingerprint` TEXT NOT NULL" +
", `email` TEXT NOT NULL" +
", `subject` TEXT" +
", `data` TEXT NOT NULL)");
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_certificate_fingerprint_email` ON `certificate` (`fingerprint`, `email`)");
db.execSQL("CREATE INDEX IF NOT EXISTS `index_certificate_email` ON `certificate` (`email`)");
}
})
.build(); .build();
} }

@ -29,12 +29,13 @@ import java.util.List;
@Dao @Dao
public interface DaoCertificate { public interface DaoCertificate {
@Query("SELECT * FROM certificate" + @Query("SELECT * FROM certificate" +
" ORDER BY subject DESC") " ORDER BY email DESC")
LiveData<List<EntityCertificate>> liveCertificates(); LiveData<List<EntityCertificate>> liveCertificates();
@Query("SELECT * FROM certificate" + @Query("SELECT * FROM certificate" +
" WHERE subject = :subject") " WHERE fingerprint = :fingerprint" +
EntityCertificate getCertificateBySubject(String subject); " AND email = :email")
EntityCertificate getCertificate(String fingerprint, String email);
@Query("SELECT * FROM certificate" + @Query("SELECT * FROM certificate" +
" WHERE email = :email") " WHERE email = :email")

@ -31,7 +31,7 @@ import java.util.Objects;
foreignKeys = { foreignKeys = {
}, },
indices = { indices = {
@Index(value = {"subject"}, unique = true), @Index(value = {"fingerprint", "email"}, unique = true),
@Index(value = {"email"}), @Index(value = {"email"}),
} }
) )
@ -41,8 +41,10 @@ public class EntityCertificate {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
public Long id; public Long id;
@NonNull @NonNull
public String subject; public String fingerprint;
@NonNull
public String email; public String email;
public String subject;
@NonNull @NonNull
public String data; public String data;
@ -50,8 +52,9 @@ public class EntityCertificate {
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof EntityCertificate) { if (obj instanceof EntityCertificate) {
EntityCertificate other = (EntityCertificate) obj; EntityCertificate other = (EntityCertificate) obj;
return (this.subject.equals(other.subject) && return (this.fingerprint.equals(other.fingerprint) &&
Objects.equals(this.email, other.email) && Objects.equals(this.email, other.email) &&
Objects.equals(this.subject, other.subject) &&
this.data.equals(other.data)); this.data.equals(other.data));
} else } else
return false; return false;

@ -165,6 +165,7 @@ import javax.mail.FolderClosedException;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import javax.security.auth.x500.X500Principal;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
@ -4388,20 +4389,21 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
.getCertificate(certHolder); .getCertificate(certHolder);
try { try {
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))) { if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))) {
String subject = cert.getSubjectDN().getName(); if (message.from != null && message.from.length == 1) {
if (!TextUtils.isEmpty(subject) && String fingerprint = Helper.sha256(cert.getEncoded());
message.from != null && message.from.length == 1) { String email = ((InternetAddress) message.from[0]).getAddress();
EntityCertificate c = db.certificate().getCertificateBySubject(subject); EntityCertificate record = db.certificate().getCertificate(fingerprint, email);
if (c == null) { if (record == null) {
c = new EntityCertificate(); record = new EntityCertificate();
c.subject = subject; record.fingerprint = fingerprint;
c.email = ((InternetAddress) message.from[0]).getAddress(); record.email = email;
c.data = Base64.encodeToString(cert.getEncoded(), Base64.NO_WRAP); record.subject = cert.getSubjectX500Principal().getName(X500Principal.RFC2253);
c.id = db.certificate().insertCertificate(c); record.data = Base64.encodeToString(cert.getEncoded(), Base64.NO_WRAP);
record.id = db.certificate().insertCertificate(record);
} }
} }
return subject; return cert.getSubjectX500Principal().getName(X500Principal.RFC2253);
} }
} catch (CMSVerifierCertificateNotValidException ex) { } catch (CMSVerifierCertificateNotValidException ex) {
Log.w(ex); Log.w(ex);

Loading…
Cancel
Save