[security] Fix SecKeyChain.QueryAsData (#2485)
- Fixes bug #58720: SecKeychain.QueryAsData returns invalid data type (https://bugzilla.xamarin.com/show_bug.cgi?id=58720) As per Apple's doc: https://developer.apple.com/documentation/security/keychain_services/keychain_items/item_return_result_keys?language=objc when multiple return types are requested (when wantPersistentReference is set to true), the underlying native return type is an NSDictionary not an NSData. As per https://bugzilla.xamarin.com/show_bug.cgi?id=58720#c3 when trying to access the byte property of the NSData object, we'd get an "unrecognized selector sent to instance". This is confirmed by the added test.
This commit is contained in:
Родитель
dbc78103d0
Коммит
a628b5c799
|
@ -110,9 +110,10 @@ namespace XamCore.Security {
|
|||
|
||||
using (var copy = NSMutableDictionary.FromDictionary (query.queryDict)){
|
||||
SetLimit (copy, 1);
|
||||
copy.LowlevelSetObject (CFBoolean.True.Handle, SecItem.ReturnData);
|
||||
if (wantPersistentReference)
|
||||
copy.LowlevelSetObject (CFBoolean.True.Handle, SecItem.ReturnPersistentRef);
|
||||
else
|
||||
copy.LowlevelSetObject (CFBoolean.True.Handle, SecItem.ReturnData);
|
||||
|
||||
IntPtr ptr;
|
||||
status = SecItem.SecItemCopyMatching (copy.Handle, out ptr);
|
||||
|
@ -129,9 +130,10 @@ namespace XamCore.Security {
|
|||
|
||||
using (var copy = NSMutableDictionary.FromDictionary (query.queryDict)){
|
||||
var n = SetLimit (copy, max);
|
||||
copy.LowlevelSetObject (CFBoolean.True.Handle, SecItem.ReturnData);
|
||||
if (wantPersistentReference)
|
||||
copy.LowlevelSetObject (CFBoolean.True.Handle, SecItem.ReturnPersistentRef);
|
||||
else
|
||||
copy.LowlevelSetObject (CFBoolean.True.Handle, SecItem.ReturnData);
|
||||
|
||||
IntPtr ptr;
|
||||
status = SecItem.SecItemCopyMatching (copy.Handle, out ptr);
|
||||
|
|
|
@ -113,6 +113,36 @@ namespace MonoTouchFixtures.Security {
|
|||
return returnGuid;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void QueryAsData ()
|
||||
{
|
||||
SecStatusCode code;
|
||||
SecRecord queryRec = new SecRecord (SecKind.GenericPassword) {
|
||||
Service = "KEYCHAIN_SERVICE",
|
||||
Label = "KEYCHAIN_SERVICE",
|
||||
Account = "KEYCHAIN_ACCOUNT"
|
||||
};
|
||||
var data = SecKeyChain.QueryAsData (queryRec, true, out code);
|
||||
if (code == SecStatusCode.Success && queryRec != null) {
|
||||
Assert.NotNull (data.Bytes);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void QueryAsDataArray ()
|
||||
{
|
||||
SecStatusCode code;
|
||||
SecRecord queryRec = new SecRecord (SecKind.GenericPassword) {
|
||||
Service = "KEYCHAIN_SERVICE",
|
||||
Label = "KEYCHAIN_SERVICE",
|
||||
Account = "KEYCHAIN_ACCOUNT"
|
||||
};
|
||||
var data = SecKeyChain.QueryAsData (queryRec, true, 1, out code);
|
||||
if (code == SecStatusCode.Success && queryRec != null) {
|
||||
Assert.NotNull (data [0].Bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static SecStatusCode SetID (Guid setID)
|
||||
{
|
||||
var queryRec = new SecRecord (SecKind.GenericPassword) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче