@@ -18,8 +18,8 @@ class MacKeychain {
1818 * Associates the specified password with the specified key in the system keychain.
1919 *
2020 * @param serviceName Service name
21- * @param account Unique account identifier
22- * @param password Passphrase to store
21+ * @param account Unique account identifier
22+ * @param password Passphrase to store
2323 * @see <a href="https://developer.apple.com/documentation/security/1398366-seckeychainaddgenericpassword">SecKeychainAddGenericPassword</a>
2424 */
2525 public void storePassword (String serviceName , String account , CharSequence password ) throws KeychainAccessException {
@@ -38,13 +38,18 @@ public void storePassword(String serviceName, String account, CharSequence passw
3838 * Loads the password associated with the specified key from the system keychain.
3939 *
4040 * @param serviceName Service name
41- * @param account Unique account identifier
41+ * @param account Unique account identifier
4242 * @return password or <code>null</code> if no such keychain entry could be loaded from the keychain.
4343 * @see <a href="https://developer.apple.com/documentation/security/1397301-seckeychainfindgenericpassword">SecKeychainFindGenericPassword</a>
4444 */
4545 public char [] loadPassword (String serviceName , String account ) {
4646 byte [] pwBytes = Native .INSTANCE .loadPassword (serviceName .getBytes (UTF_8 ), account .getBytes (UTF_8 ));
4747 if (pwBytes == null ) {
48+ // this if-statement is a workaround for https://github.com/cryptomator/integrations-mac/issues/13:
49+ if ("Cryptomator" .equals (serviceName ) && tryMigratePassword (account )) {
50+ // on success: retry
51+ return loadPassword (serviceName , account );
52+ }
4853 return null ;
4954 } else {
5055 CharBuffer pwBuf = UTF_8 .decode (ByteBuffer .wrap (pwBytes ));
@@ -56,14 +61,36 @@ public char[] loadPassword(String serviceName, String account) {
5661 }
5762 }
5863
64+ /**
65+ * Fix for <a href="https://github.com/cryptomator/integrations-mac/issues/13">Issue 13</a>.
66+ * Attempts to find the account with the old hard-coded service name 'Cryptomator\0'
67+ *
68+ * @param account Unique account identifier
69+ * @return <code>true</code> on success
70+ */
71+ private boolean tryMigratePassword (String account ) {
72+ byte [] oldServiceName = {'C' , 'r' , 'y' , 'p' , 't' , 'o' , 'm' , 'a' , 't' , 'o' , 'r' , '\0' };
73+ byte [] newServiceName = {'C' , 'r' , 'y' , 'p' , 't' , 'o' , 'm' , 'a' , 't' , 'o' , 'r' };
74+ byte [] pwBytes = Native .INSTANCE .loadPassword (oldServiceName , account .getBytes (UTF_8 ));
75+ if (pwBytes == null ) {
76+ return false ;
77+ }
78+ int errorCode = Native .INSTANCE .storePassword (newServiceName , account .getBytes (UTF_8 ), pwBytes );
79+ Arrays .fill (pwBytes , (byte ) 0x00 );
80+ if (errorCode != OSSTATUS_SUCCESS ) {
81+ return false ;
82+ }
83+ Native .INSTANCE .deletePassword (oldServiceName , account .getBytes (UTF_8 ));
84+ return true ;
85+ }
86+
5987 /**
6088 * Deletes the password associated with the specified key from the system keychain.
6189 *
6290 * @param serviceName Service name
63- * @param account Unique account identifier
91+ * @param account Unique account identifier
6492 * @return <code>true</code> if the passwords has been deleted, <code>false</code> if no entry for the given key exists.
6593 * @see <a href="https://developer.apple.com/documentation/security/1395547-secitemdelete">SecKeychainItemDelete</a>
66-
6794 */
6895 public boolean deletePassword (String serviceName , String account ) throws KeychainAccessException {
6996 int errorCode = Native .INSTANCE .deletePassword (serviceName .getBytes (UTF_8 ), account .getBytes (UTF_8 ));
0 commit comments