Advertisement
Guest User

Untitled

a guest
Sep 8th, 2017
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.97 KB | None | 0 0
  1. using System;
  2.  
  3. using Security;
  4. using Foundation;
  5.  
  6. namespace Project.iOS
  7. {
  8. /// <summary>
  9. /// Keychain helpers. These work on iOS7 onwards only. For compatibility with previoous iOS versions, the "Synchronizable" property must be removed / ignored.
  10. /// </summary>
  11. public static class KeychainHelpers
  12. {
  13. /// <summary>
  14. /// Deletes a username/password record.
  15. /// </summary>
  16. /// <param name="username">the username to query. Not case sensitive. May not be NULL.</param>
  17. /// <param name="serviceId">the service description to query. Not case sensitive. May not be NULL.</param>
  18. /// <param name="synchronizable">
  19. /// Defines if the record you want to delete is syncable via iCloud keychain or not. Note that using the same username and service ID
  20. /// but different synchronization settings will result in two keychain entries.
  21. /// </param>
  22. /// <returns>Status code</returns>
  23. public static SecStatusCode DeletePasswordForUsername(string username, string serviceId, bool synchronizable)
  24. {
  25. if (username == null)
  26. {
  27. throw new ArgumentNullException("userName");
  28. }
  29.  
  30. if (serviceId == null)
  31. {
  32. throw new ArgumentNullException("serviceId");
  33. }
  34.  
  35. // Querying is case sesitive - we don't want that.
  36. username = username.ToLower();
  37. serviceId = serviceId.ToLower();
  38.  
  39. // Query and remove.
  40. var queryRec = new SecRecord(SecKind.GenericPassword)
  41. {
  42. Service = serviceId,
  43. Label = serviceId,
  44. Account = username,
  45. Synchronizable = synchronizable
  46. };
  47. var code = SecKeyChain.Remove(queryRec);
  48. return code;
  49. }
  50.  
  51. /// <summary>
  52. /// Sets a password for a specific username.
  53. /// </summary>
  54. /// <param name="username">the username to add the password for. Not case sensitive. May not be NULL.</param>
  55. /// <param name="password">the password to associate with the record. May not be NULL.</param>
  56. /// <param name="serviceId">the service description to use. Not case sensitive. May not be NULL.</param>
  57. /// <param name="secAccessible">defines how the keychain record is protected</param>
  58. /// <param name="synchronizable">
  59. /// Defines if keychain record can by synced via iCloud keychain.
  60. /// Note that using the same username and service ID but different synchronization settings will result in two keychain entries.
  61. /// </param>
  62. /// <returns>SecStatusCode.Success if everything went fine, otherwise some other status</returns>
  63. public static SecStatusCode SetPasswordForUsername(string username, string password, string serviceId, SecAccessible secAccessible, bool synchronizable)
  64. {
  65. if (username == null)
  66. {
  67. throw new ArgumentNullException("userName");
  68. }
  69.  
  70. if (serviceId == null)
  71. {
  72. throw new ArgumentNullException("serviceId");
  73. }
  74.  
  75. if (password == null)
  76. {
  77. throw new ArgumentNullException("password");
  78. }
  79.  
  80. // Querying is case sesitive - we don't want that.
  81. username = username.ToLower();
  82. serviceId = serviceId.ToLower();
  83.  
  84. // Don't bother updating. Delete existing record and create a new one.
  85. DeletePasswordForUsername(username, serviceId, synchronizable);
  86.  
  87. // Create a new record.
  88. // Store password UTF8 encoded.
  89. SecStatusCode code = SecKeyChain.Add(new SecRecord(SecKind.GenericPassword)
  90. {
  91. Service = serviceId,
  92. Label = serviceId,
  93. Account = username,
  94. Generic = NSData.FromString(password, NSStringEncoding.UTF8),
  95. Accessible = secAccessible,
  96. Synchronizable = synchronizable
  97. });
  98.  
  99. return code;
  100. }
  101.  
  102. /// <summary>
  103. /// Gets a password for a specific username.
  104. /// </summary>
  105. /// <param name="username">the username to query. Not case sensitive. May not be NULL.</param>
  106. /// <param name="serviceId">the service description to use. Not case sensitive. May not be NULL.</param>
  107. /// <param name="synchronizable">
  108. /// Defines if the record you want to get is syncable via iCloud keychain or not. Note that using the same username and service ID
  109. /// but different synchronization settings will result in two keychain entries.
  110. /// </param>
  111. /// <returns>
  112. /// The password or NULL if no matching record was found.
  113. /// </returns>
  114. public static string GetPasswordForUsername(string username, string serviceId, bool synchronizable)
  115. {
  116. if (username == null)
  117. {
  118. throw new ArgumentNullException("userName");
  119. }
  120.  
  121. if (serviceId == null)
  122. {
  123. throw new ArgumentNullException("serviceId");
  124. }
  125.  
  126. // Querying is case sesitive - we don't want that.
  127. username = username.ToLower();
  128. serviceId = serviceId.ToLower();
  129.  
  130. SecStatusCode code;
  131. // Query the record.
  132. SecRecord queryRec = new SecRecord(SecKind.GenericPassword)
  133. {
  134. Service = serviceId,
  135. Label = serviceId,
  136. Account = username,
  137. Synchronizable = synchronizable
  138. };
  139. queryRec = SecKeyChain.QueryAsRecord(queryRec, out code);
  140.  
  141. // If found, try to get password.
  142. if (code == SecStatusCode.Success && queryRec != null && queryRec.Generic != null)
  143. {
  144. // Decode from UTF8.
  145. return NSString.FromData(queryRec.Generic, NSStringEncoding.UTF8);
  146. }
  147.  
  148. // Something went wrong.
  149. return null;
  150. }
  151. }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement