Advertisement
Guest User

Untitled

a guest
Oct 10th, 2015
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.23 KB | None | 0 0
  1. /**
  2. * Converter for OTR keys between libotr (Pidgin, Psi+) and Xabber.
  3. *
  4. * Key files:
  5. * Psi+: ~/.local/share/psi+/profiles/default/otr.keys
  6. * Xabber: /data/data/com.xabber.androiddev/databases/xabber.db
  7. *
  8. * Compile:
  9. * javac OtrKeyConverter.java
  10. *
  11. *
  12. * Usage:
  13. *
  14. * Xabber -> libotr (key writtten to stdout)
  15. * java -classpath ".:sqlite-jdbc-3.8.11.2.jar" OtrKeyConverter user@example.com
  16. * xabber.db
  17. *
  18. * libotr -> Xabber (key written to database)
  19. * java -classpath ".:sqlite-jdbc-3.8.11.2.jar" OtrKeyConverter user@example.com
  20. * xabber.db otr.keys
  21. *
  22. *
  23. *
  24. *
  25. */
  26.  
  27. import java.security.KeyFactory;
  28. import java.security.KeyPair;
  29. import java.io.FileInputStream;
  30. import java.io.FileOutputStream;
  31. import java.io.InputStream;
  32. import java.io.OutputStream;
  33. import java.io.FileNotFoundException;
  34. import java.io.IOException;
  35. import java.security.spec.PKCS8EncodedKeySpec;
  36. import java.security.spec.X509EncodedKeySpec;
  37. import java.security.KeyPair;
  38. import java.security.PrivateKey;
  39. import java.security.PublicKey;
  40. import java.security.interfaces.DSAPublicKey;
  41. import java.security.interfaces.DSAPrivateKey;
  42. import java.math.BigInteger;
  43. import java.security.spec.DSAPrivateKeySpec;
  44. import java.security.spec.DSAPublicKeySpec;
  45. import java.sql.*;
  46. import java.security.NoSuchAlgorithmException;
  47. import java.security.spec.InvalidKeySpecException;
  48.  
  49.  
  50. class OtrKey
  51. {
  52. BigInteger p;
  53. BigInteger q;
  54. BigInteger g;
  55. BigInteger y;
  56. BigInteger x;
  57. String account;
  58. String protocol;
  59.  
  60.  
  61. public String toLibotr()
  62. {
  63. return
  64. "(privkeys\n" +
  65. " (account\n" +
  66. "(name \"" + account + "\")\n" +
  67. "(protocol " + protocol + ")\n" +
  68. "(private-key\n" +
  69. " (dsa\n" +
  70. " (p #" + p.toString(16) + "#)\n" +
  71. " (q #" + q.toString(16) + "#)\n" +
  72. " (g #" + g.toString(16) + "#)\n" +
  73. " (y #" + y.toString(16) + "#)\n" +
  74. " (x #" + x.toString(16) + "#)\n" +
  75. " )\n" +
  76. " )\n" +
  77. " )\n" +
  78. ")\n";
  79. }
  80.  
  81.  
  82. public byte[] toXabberPrivate()
  83. throws NoSuchAlgorithmException, InvalidKeySpecException
  84. {
  85. DSAPrivateKeySpec privSpec = new DSAPrivateKeySpec(x, p, q, g);
  86. KeyFactory keyFactory = KeyFactory.getInstance("DSA");
  87. DSAPrivateKey privKey = (DSAPrivateKey) keyFactory.generatePrivate(privSpec);
  88. PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(
  89. privKey.getEncoded());
  90. return encodedKeySpec.getEncoded();
  91. }
  92.  
  93.  
  94. public byte[] toXabberPublic()
  95. throws NoSuchAlgorithmException, InvalidKeySpecException
  96. {
  97. DSAPublicKeySpec pubSpec = new DSAPublicKeySpec(y, p, q, g);
  98. KeyFactory keyFactory = KeyFactory.getInstance("DSA");
  99. DSAPublicKey pubKey = (DSAPublicKey) keyFactory.generatePublic(pubSpec);
  100. X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(pubKey.getEncoded());
  101. return encodedKeySpec.getEncoded();
  102. }
  103. }
  104.  
  105.  
  106.  
  107.  
  108. class OtrKeyConverter
  109. {
  110. private static OtrKey readXabberKey(byte[] privBytes, byte[] pubBytes)
  111. throws NoSuchAlgorithmException, InvalidKeySpecException
  112. {
  113. PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privBytes);
  114. X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubBytes);
  115. KeyFactory keyFactory;
  116. keyFactory = KeyFactory.getInstance("DSA");
  117. DSAPublicKey pubKey = (DSAPublicKey) keyFactory.generatePublic(pubKeySpec);
  118. DSAPrivateKey privKey = (DSAPrivateKey) keyFactory.generatePrivate(privKeySpec);
  119. OtrKey target = new OtrKey();
  120. target.p = pubKey.getParams().getP();
  121. target.q = pubKey.getParams().getQ();
  122. target.g = pubKey.getParams().getG();
  123. target.y = pubKey.getY();
  124. target.x = privKey.getX();
  125. target.account = "foobar";
  126. target.protocol = "prpl-jabber";
  127. return target;
  128. }
  129.  
  130.  
  131. private static OtrKey readLibotrKey(String keyFile)
  132. throws FileNotFoundException, IOException
  133. {
  134. OtrKey otrKey = new OtrKey();
  135. InputStream keyStream = new FileInputStream(keyFile);
  136. byte[] keyBytes = new byte[10000];
  137. keyStream.read(keyBytes);
  138. String keyString = new String(keyBytes);
  139. String[] tokens = keyString.split("\\(");
  140. for (String t: tokens)
  141. {
  142. t = t.trim();
  143. if (t.startsWith("p "))
  144. {
  145. otrKey.p = readNumber(t);
  146. }
  147. if (t.startsWith("q "))
  148. {
  149. otrKey.q = readNumber(t);
  150. }
  151. if (t.startsWith("g "))
  152. {
  153. otrKey.g = readNumber(t);
  154. }
  155. if (t.startsWith("y "))
  156. {
  157. otrKey.y = readNumber(t);
  158. }
  159. if (t.startsWith("x "))
  160. {
  161. otrKey.x = readNumber(t);
  162. }
  163. }
  164. otrKey.account = "foobar";
  165. otrKey.protocol = "prpl-jabber";
  166. return otrKey;
  167. }
  168.  
  169.  
  170. public static BigInteger readNumber(String s)
  171. {
  172. BigInteger bi = new BigInteger(s.substring(s.indexOf('#') + 1,
  173. s.lastIndexOf('#')), 16);
  174. return bi;
  175. }
  176.  
  177.  
  178. public static void main(String[] args)
  179. {
  180. if (args.length != 2 && args.length != 3)
  181. {
  182. System.out.println("Xabber -> libotr:\n" +
  183. "OtrKeyConverter user@example.com xabber.db\n" +
  184. "\n" +
  185. "libotr -> Xabber\n" +
  186. "OtrKeyConverter user@example.com xabber.db otr.keys");
  187. System.exit(2);
  188. }
  189. String[] jid = args[0].split("@");
  190. if (jid.length != 2)
  191. {
  192. System.out.println("invalid jid");
  193. System.exit(2);
  194. }
  195. String jidUser = jid[0].trim();
  196. String jidServer = jid[1].trim();
  197. String dbFile = args[1];
  198. try
  199. {
  200. Class.forName("org.sqlite.JDBC");
  201. Connection c = DriverManager.getConnection("jdbc:sqlite:" + dbFile);
  202.  
  203. if (args.length == 2)
  204. {
  205. // xabber to libotr
  206. System.out.println("Reading key for " + jidUser + "@" + jidServer +
  207. " from " + dbFile);
  208. Statement stmt = c.createStatement();
  209. ResultSet rs = stmt.executeQuery("SELECT public_key,private_key " +
  210. "FROM accounts " +
  211. "WHERE server_name='" + jidServer +
  212. "' and user_name='" + jidUser + "';");
  213. if (rs.next())
  214. {
  215. OtrKey otrKey = readXabberKey(rs.getBytes("private_key"),
  216. rs.getBytes("public_key"));
  217. if (otrKey != null)
  218. {
  219. System.out.println(otrKey.toLibotr());
  220. }
  221. else
  222. {
  223. System.out.println("something went wrong");
  224. }
  225. }
  226. else
  227. {
  228. System.out.println("user not found in database");
  229. }
  230. }
  231. else if (args.length == 3)
  232. {
  233. // libotr to xabber
  234. System.out.println("Writing key for " + jidUser + "@" + jidServer +
  235. " to " + dbFile);
  236. OtrKey otrKey = readLibotrKey(args[2]);
  237. PreparedStatement stmt = c.prepareStatement(
  238. "UPDATE accounts " +
  239. "SET public_key = ?, private_key = ? " +
  240. "WHERE server_name='" + jidServer +
  241. "' and user_name='" + jidUser + "';");
  242. stmt.setBytes(1, otrKey.toXabberPublic());
  243. stmt.setBytes(2, otrKey.toXabberPrivate());
  244. int result = stmt.executeUpdate();
  245. System.out.println(result + " rows updated");
  246. }
  247. }
  248. catch (Exception e)
  249. {
  250. System.err.println( e.getClass().getName() + ": " + e.getMessage() );
  251. System.exit(1);
  252. }
  253. }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement