@@ -26,41 +26,50 @@ JNIEXPORT jint JNICALL Java_org_cryptomator_macos_keychain_MacKeychain_00024Nati
2626 jbyte *pwStr = (*env)->GetByteArrayElements (env, password, NULL );
2727 jsize length = (*env)->GetArrayLength (env, password);
2828
29- // find existing:
30- NSMutableDictionary *query = [@{
31- (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
32- (__bridge id )kSecAttrService : [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding],
33- (__bridge id )kSecAttrAccount : [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding],
34- (__bridge id )kSecReturnAttributes : @YES ,
35- (__bridge id )kSecReturnData : @YES ,
36- (__bridge id )kSecMatchLimit : (__bridge id )kSecMatchLimitOne
37- } mutableCopy];
38- if (requireOsAuthentication) {
39- LAContext *context = getSharedLAContext ();
40- query[(__bridge id )kSecUseAuthenticationContext ] = context;
41- }
42- CFDictionaryRef result = NULL ;
43- OSStatus status = SecItemCopyMatching ((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
44- if (status == errSecSuccess && result != NULL ) {
45- // update existing:
46- NSDictionary *attributesToUpdate = @{
47- (__bridge id )kSecValueData : [NSData dataWithBytes: pwStr length: length]
48- };
49- status = SecItemUpdate ((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate);
50- } else if (status == errSecItemNotFound) {
51- // add new:
52- NSMutableDictionary *attributes = [@{
29+ NSString *serviceString = [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding];
30+ NSString *keyString = [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding];
31+
32+ OSStatus status = errSecParam;
33+
34+ if (serviceString && keyString) { // guard both NSStrings not to be NIL
35+ // find existing:
36+ NSMutableDictionary *query = [@{
5337 (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
54- (__bridge id )kSecAttrService : [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding],
55- (__bridge id )kSecAttrAccount : [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding],
56- (__bridge id )kSecValueData : [NSData dataWithBytes: pwStr length: length]
38+ (__bridge id )kSecAttrService : serviceString,
39+ (__bridge id )kSecAttrAccount : keyString,
40+ (__bridge id )kSecReturnAttributes : @YES ,
41+ (__bridge id )kSecReturnData : @YES ,
42+ (__bridge id )kSecMatchLimit : (__bridge id )kSecMatchLimitOne
5743 } mutableCopy];
5844 if (requireOsAuthentication) {
59- attributes[(__bridge id )kSecAttrAccessControl ] = (__bridge_transfer id )SecAccessControlCreateWithFlags (kCFAllocatorDefault , kSecAttrAccessibleWhenUnlocked , kSecAccessControlUserPresence , NULL );
45+ LAContext *context = getSharedLAContext ();
46+ query[(__bridge id )kSecUseAuthenticationContext ] = context;
47+ }
48+ CFDictionaryRef result = NULL ;
49+ status = SecItemCopyMatching ((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
50+ if (status == errSecSuccess && result != NULL ) {
51+ // update existing:
52+ NSDictionary *attributesToUpdate = @{
53+ (__bridge id )kSecValueData : [NSData dataWithBytes: pwStr length: length]
54+ };
55+ status = SecItemUpdate ((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate);
56+ } else if (status == errSecItemNotFound) {
57+ // add new:
58+ NSMutableDictionary *attributes = [@{
59+ (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
60+ (__bridge id )kSecAttrService : serviceString,
61+ (__bridge id )kSecAttrAccount : keyString,
62+ (__bridge id )kSecValueData : [NSData dataWithBytes: pwStr length: length]
63+ } mutableCopy];
64+ if (requireOsAuthentication) {
65+ attributes[(__bridge id )kSecAttrAccessControl ] = (__bridge_transfer id )SecAccessControlCreateWithFlags (kCFAllocatorDefault , kSecAttrAccessibleWhenUnlocked , kSecAccessControlUserPresence , NULL );
66+ }
67+ status = SecItemAdd ((__bridge CFDictionaryRef)attributes, NULL );
68+ } else {
69+ NSLog (@" Error storing item in keychain. Status code: %d " , (int )status);
6070 }
61- status = SecItemAdd ((__bridge CFDictionaryRef)attributes, NULL );
6271 } else {
63- NSLog (@" Error storing item in keychain. Status code: %d " , ( int )status );
72+ NSLog (@" Invalid UTF-8 input: service or key string conversion failed " );
6473 }
6574
6675 (*env)->ReleaseByteArrayElements (env, service, serviceStr, JNI_ABORT);
@@ -73,28 +82,36 @@ JNIEXPORT jbyteArray JNICALL Java_org_cryptomator_macos_keychain_MacKeychain_000
7382 jbyte *serviceStr = (*env)->GetByteArrayElements (env, service, NULL );
7483 jbyte *keyStr = (*env)->GetByteArrayElements (env, key, NULL );
7584
76- // find existing:
77- LAContext *context = getSharedLAContext ();
78- NSDictionary *query = @{
79- (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
80- (__bridge id )kSecAttrService : [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding],
81- (__bridge id )kSecAttrAccount : [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding],
82- (__bridge id )kSecReturnAttributes : @YES ,
83- (__bridge id )kSecReturnData : @YES ,
84- (__bridge id )kSecMatchLimit : (__bridge id )kSecMatchLimitOne ,
85- (__bridge id )kSecUseAuthenticationContext : context
86- };
87- CFDictionaryRef result = NULL ;
88- OSStatus status = SecItemCopyMatching ((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
85+ NSString *serviceString = [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding];
86+ NSString *keyString = [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding];
87+
8988 jbyteArray password = NULL ;
90- if (status == errSecSuccess && result != NULL ) {
91- // retrieve password:
92- NSDictionary *attributes = (__bridge_transfer NSDictionary *)result;
93- NSData *passwordData = attributes[(__bridge id )kSecValueData ];
94- password = (*env)->NewByteArray (env, (int )passwordData.length );
95- (*env)->SetByteArrayRegion (env, password, 0 , (int )passwordData.length , (jbyte *)passwordData.bytes );
96- } else if (status != errSecItemNotFound) {
97- NSLog (@" Error retrieving item from keychain. Status code: %d " , (int )status);
89+
90+ if (serviceString && keyString) { // guard both NSStrings not to be NIL
91+ // find existing:
92+ LAContext *context = getSharedLAContext ();
93+ NSDictionary *query = @{
94+ (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
95+ (__bridge id )kSecAttrService : serviceString,
96+ (__bridge id )kSecAttrAccount : keyString,
97+ (__bridge id )kSecReturnAttributes : @YES ,
98+ (__bridge id )kSecReturnData : @YES ,
99+ (__bridge id )kSecMatchLimit : (__bridge id )kSecMatchLimitOne ,
100+ (__bridge id )kSecUseAuthenticationContext : context
101+ };
102+ CFDictionaryRef result = NULL ;
103+ OSStatus status = SecItemCopyMatching ((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
104+ if (status == errSecSuccess && result != NULL ) {
105+ // retrieve password:
106+ NSDictionary *attributes = (__bridge_transfer NSDictionary *)result;
107+ NSData *passwordData = attributes[(__bridge id )kSecValueData ];
108+ password = (*env)->NewByteArray (env, (int )passwordData.length );
109+ (*env)->SetByteArrayRegion (env, password, 0 , (int )passwordData.length , (jbyte *)passwordData.bytes );
110+ } else if (status != errSecItemNotFound) {
111+ NSLog (@" Error retrieving item from keychain. Status code: %d " , (int )status);
112+ }
113+ } else {
114+ NSLog (@" Invalid UTF-8 input: service or key string conversion failed" );
98115 }
99116
100117 (*env)->ReleaseByteArrayElements (env, service, serviceStr, JNI_ABORT);
@@ -106,17 +123,26 @@ JNIEXPORT jint JNICALL Java_org_cryptomator_macos_keychain_MacKeychain_00024Nati
106123 jbyte *serviceStr = (*env)->GetByteArrayElements (env, service, NULL );
107124 jbyte *keyStr = (*env)->GetByteArrayElements (env, key, NULL );
108125
109- // find existing:
110- LAContext *context = getSharedLAContext ();
111- NSDictionary *query = @{
112- (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
113- (__bridge id )kSecAttrService : [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding],
114- (__bridge id )kSecAttrAccount : [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding],
115- (__bridge id )kSecUseAuthenticationContext : context
116- };
117- OSStatus status = SecItemDelete ((__bridge CFDictionaryRef)query);
118- if (status != errSecSuccess) {
119- NSLog (@" Error deleting item from keychain. Status code: %d " , (int )status);
126+ NSString *serviceString = [NSString stringWithCString: (char *)serviceStr encoding: NSUTF8StringEncoding];
127+ NSString *keyString = [NSString stringWithCString: (char *)keyStr encoding: NSUTF8StringEncoding];
128+
129+ OSStatus status = errSecParam;
130+
131+ if (serviceString && keyString) { // guard both NSStrings not to be NIL
132+ // find existing:
133+ LAContext *context = getSharedLAContext ();
134+ NSDictionary *query = @{
135+ (__bridge id )kSecClass : (__bridge id )kSecClassGenericPassword ,
136+ (__bridge id )kSecAttrService : serviceString,
137+ (__bridge id )kSecAttrAccount : keyString,
138+ (__bridge id )kSecUseAuthenticationContext : context
139+ };
140+ status = SecItemDelete ((__bridge CFDictionaryRef)query);
141+ if (status != errSecSuccess) {
142+ NSLog (@" Error deleting item from keychain. Status code: %d " , (int )status);
143+ }
144+ } else {
145+ NSLog (@" Invalid UTF-8 input: service or key string conversion failed" );
120146 }
121147
122148 (*env)->ReleaseByteArrayElements (env, service, serviceStr, JNI_ABORT);
0 commit comments