diff --git a/pom.xml b/pom.xml
index 7dfa890..0f59b56 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,12 +94,17 @@
3.0.8
-
+
+
+
+
+
+
- org.xerial
+ io.github.willena
sqlite-jdbc
- 3.28.0
+ 3.35.4
diff --git a/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java b/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java
index cd4d468..6a50d25 100644
--- a/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java
+++ b/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java
@@ -1,5 +1,8 @@
package minsecurity.identity.persist.sqlite;
+import org.sqlite.mc.SQLiteMCConfig;
+import org.sqlite.mc.SQLiteMCSqlCipherConfig;
+
import java.io.File;
import java.sql.*;
@@ -34,6 +37,10 @@ public class Sqlite {
}
+ private String passwd2HexKey(){
+ return String.format("x'%s'", passwd);
+ }
+
/**
* 获取Sqlite object
* @return Sqlite object
@@ -70,8 +77,8 @@ public class Sqlite {
new File(dbPath).mkdirs();
}
String real_db_file = dbPath + db_file;
- Class.forName("org.sqlite.JDBC");
- c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file);
+ // 兼容sqlcipher
+ c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties());
stmt = c.createStatement();
stmt.executeUpdate(table_create);
stmt.close();
@@ -92,8 +99,8 @@ public class Sqlite {
new File(filePath).mkdirs();
}
String real_db_file = filePath + db_file;
- Class.forName("org.sqlite.JDBC");
- c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file);
+ // 兼容sqlcipher
+ c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties());
stmt = c.createStatement();
stmt.executeUpdate(table_create);
stmt.close();
@@ -111,7 +118,8 @@ public class Sqlite {
try{
String real_db_file = db_path + db_file;
Class.forName("org.sqlite.JDBC");
- c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file);
+ // 兼容sqlcipher
+ c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties());
// TODO 设置数据库最大连接数
return c;
}catch (Exception ex){
diff --git a/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java b/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java
index 0043580..d028be6 100644
--- a/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java
+++ b/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java
@@ -15,11 +15,13 @@ import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
+
public final class Db {
private static Identity getIdentityByNameFromStorage(String name, Connection c) throws Exception {
- Statement stmt = c.createStatement();
- ResultSet rs = stmt.executeQuery(String.format("SELECT * FROM identityinfo WHERE name = %s LIMIT 1", name)); // LIMIT 1代替Queryrow
- stmt.close();
+ PreparedStatement pstmt = c.prepareStatement("SELECT * FROM identityinfo WHERE name = ? LIMIT 1");// LIMIT 1代替Queryrow
+ pstmt.setString(1, name);
+ ResultSet rs = pstmt.executeQuery();
+ pstmt.close();
return getIdentityFromSqlRow(rs);
}
@@ -86,7 +88,7 @@ public final class Db {
}
private static Identity getDefaultIdentityFromStorage(ResultSet rs) throws Exception{
- if (rs == null)
+ if (!rs.isBeforeFirst())
return null;
String pubStr = "", priStr = "", pass = "", certStr = "", name = "", prikeyRawByte = "";
@@ -116,20 +118,18 @@ public final class Db {
}
- private static boolean setDefaultIdentityFromStorage(String name, Connection c) throws Exception{
+ private static void setDefaultIdentityFromStorage(String name, Connection c) throws Exception{
PreparedStatement stmt = c.prepareStatement("update identityinfo set is_default = 1 where name= ?");
stmt.setString(1, name);
stmt.executeUpdate();
stmt.close();
- return true;
}
- private static boolean cancelDefaultIdentityFromStorage(String name, Connection c) throws Exception{
+ private static void cancelDefaultIdentityFromStorage(String name, Connection c) throws Exception{
PreparedStatement stmt = c.prepareStatement("update identityinfo set is_default = 0 where name= ?");
stmt.setString(1, name);
stmt.executeUpdate();
stmt.close();
- return true;
}
public static List getAllIdentityFromStorage(String name) throws Exception {
@@ -148,23 +148,106 @@ public final class Db {
return getIdentityByNameFromStorage(name, c);
}
- private static boolean setDefaultIdentityByNameInStorage(String name) throws Exception {
+ private static void setDefaultIdentityByNameInStorage(String name) throws Exception {
Connection c = Sqlite.getInstance().getConn();
- return false;
+ c.setAutoCommit(false);
+ try{
+ PreparedStatement pstmt = c.prepareStatement("select * from identityinfo where name = ? LIMIT 1");
+ pstmt.setString(1, name);
+ ResultSet rs = pstmt.executeQuery(String.format("select * from identityinfo where name = %s LIMIT 1", name));
+ getDefaultIdentityFromStorage(rs);
+ pstmt.close();
+
+ PreparedStatement pstmt2 = c.prepareStatement("SELECT * from identityinfo where is_default = ?");
+ pstmt2.setInt(1, 1);
+ rs = pstmt2.executeQuery();
+ Identity id = getDefaultIdentityFromStorage(rs);
+ if (id != null){
+ cancelDefaultIdentityFromStorage(id.getName(), c);
+ }
+ setDefaultIdentityFromStorage(name, c);
+ pstmt2.close();
+ c.commit();
+ c.close();
+ }catch (Exception ex){
+ System.out.println(ex.getMessage());
+ c.rollback();
+ c.close();
+ throw ex;
+ }
}
- public static boolean SetDefaultIdentityByNameInStorage(String name) throws Exception {
+
+ public static void SetDefaultIdentityByNameInStorage(String name) throws Exception {
for (int i = 0; i < 4; i++){
- boolean res = false;
try{
- res = setDefaultIdentityByNameInStorage(name);
- return res;
+ setDefaultIdentityByNameInStorage(name);
+ return;
}catch (Exception ex){
+ if (i == 3)
+ return;
if (ex.getMessage().equals("database is locked"))
Thread.sleep(50);
else
- return false;
+ throw ex;
}
}
- return false;
+ }
+
+ public static void deleteIdentityByName(String name) throws Exception{
+ Connection c = Sqlite.getInstance().getConn();
+ PreparedStatement pstmt = c.prepareStatement("elete from identityinfo where name=?");
+ pstmt.setString(1, name);
+ pstmt.executeUpdate();
+ pstmt.close();
+ c.close();
+ }
+
+ public static void persistIdentity(Identity identity) throws Exception{
+ Identity id = getIdentityByNameFromStorage(identity.getName());
+ if (id != null)
+ throw new Exception("The name has existed");
+
+ Connection c = Sqlite.getInstance().getConn();
+ String pubStr = "", priStr = "", certStr, prikeyRawByte = "";
+ int algo, sign;
+
+ if (identity.hasPrivateKey()){
+ byte[] priByte = identity.getPrikey().getBytes();
+ priStr = Base64.getEncoder().encodeToString(priByte);
+ }
+ if (identity.getPubkey() != null){
+ byte[] pubByte = identity.getPubkey().getBytes();
+ pubStr = Base64.getEncoder().encodeToString(pubByte);
+ }
+
+ algo = identity.getKeyParam().PublicKeyAlgorithm;
+ sign = identity.getKeyParam().SignatureAlgorithm;
+
+ certStr = CertUtils.toPem(identity.getCert(), null, Common.SM4ECB);
+
+ if (identity.getPrikeyRawByte() != null)
+ prikeyRawByte = Base64.getEncoder().encodeToString(identity.getPrikeyRawByte());
+
+ PreparedStatement pstmt = c.prepareStatement("INSERT INTO identityinfo(name, pubkey, prikey, pubkey_algo, signature_algo, pass, cert,prikey_raw_byte) values(?,?,?,?,?,?,?,?)");
+ pstmt.setString(1, identity.getName());
+ pstmt.setString(2, priStr);
+ pstmt.setString(3, pubStr);
+ pstmt.setInt(4, algo);
+ pstmt.setInt(5, sign);
+ pstmt.setString(6, identity.getPasswd());
+ pstmt.setString(7, certStr);
+ pstmt.setString(8, prikeyRawByte);
+
+ pstmt.executeUpdate();
+ pstmt.close();
+ c.close();
+ }
+
+ public Identity getDefaultIdentityFromStorage() throws Exception{
+ Connection c = Sqlite.getInstance().getConn();
+ PreparedStatement pstmt = c.prepareStatement("SELECT * from identityinfo where is_default= ? LIMIT 1");
+ pstmt.setInt(1, 1);
+ ResultSet rs = pstmt.executeQuery();
+ return getDefaultIdentityFromStorage(rs);
}
}
diff --git a/src/test/java/minsecurity/identity/sqlite/SqliteTest.java b/src/test/java/minsecurity/identity/sqlite/SqliteTest.java
index 8f2f170..2aca043 100644
--- a/src/test/java/minsecurity/identity/sqlite/SqliteTest.java
+++ b/src/test/java/minsecurity/identity/sqlite/SqliteTest.java
@@ -1,5 +1,6 @@
package minsecurity.identity.sqlite;
+import minsecurity.identity.persist.sqlite.Sqlite;
import minsecurity.identity.persist.sqlite.SqliteUtil;
import org.junit.Test;
@@ -11,4 +12,38 @@ public class SqliteTest {
System.out.println(SqliteUtil.home());
assertFalse(SqliteUtil.pathExists("/aaa/1.txt"));
}
+
+ @Test
+ public void TestSqliteOpen(){
+ try{
+ Sqlite.getInstance().openDefault();
+ boolean res = SqliteUtil.pathExists("/home/zhengqi/min/identity/identity.db");
+ if (!res){
+ throw new Exception("no target db file!!");
+ }
+
+ String homePath = SqliteUtil.home();
+ String filePath = homePath + "/test/";
+ Sqlite.getInstance().open(filePath);
+
+ boolean res1 = SqliteUtil.pathExists("/home/zhengqi/test/identity.db");
+ if (!res1){
+ throw new Exception("no target db file!!");
+ }
+ }catch (Exception ex){
+ System.out.println(ex.getMessage());
+ }
+ }
+
+ @Test
+ public void TestSqliteSetPasswd(){
+ try{
+ String newPasswd = "1DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99";
+ Sqlite.getInstance().setPasswd(newPasswd);
+ Sqlite.getInstance().open("/home/zhengqi/min/identity/");
+ // Sqlite.getInstance().getConn();
+ }catch (Exception ex){
+ System.out.println(ex.getMessage());
+ }
+ }
}
diff --git a/src/test/java/minsecurity/identity/sqlite/db/DBTest.java b/src/test/java/minsecurity/identity/sqlite/db/DBTest.java
new file mode 100644
index 0000000..e9109b5
--- /dev/null
+++ b/src/test/java/minsecurity/identity/sqlite/db/DBTest.java
@@ -0,0 +1,4 @@
+package minsecurity.identity.sqlite.db;
+
+public class DBTest {
+}