[Trust] Subclass NativeObject + numerous other code updates (#13104)

* Subclass NativeObject to reuse object lifetime code.
* Enable nullability and fix code accordingly.
* Use 'is' and 'is not' instead of '==' and '!=' for object identity.
* Use the null-safe NativeObjectExtensions.GetHandle extension method to get
  the handle instead of checking for null (avoids some code duplication).
* Use 'nameof (parameter)' instead of string constants.
* Call 'GetCheckedHandle ()' (which will throw an ObjectDisposedException if
  Handle == IntPtr.Zero) instead of manually checking for IntPtr.Zero and
  throwing ObjectDisposedException.
* Remove the (IntPtr) constructor for XAMCORE_4_0.
This commit is contained in:
Rolf Bjarne Kvinge 2021-10-26 08:21:30 +02:00 коммит произвёл GitHub
Родитель 79fc7433c2
Коммит 94a7e815ce
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 58 добавлений и 114 удалений

Просмотреть файл

@ -46,7 +46,7 @@ namespace Security {
public SecPolicy[] GetPolicies ()
{
IntPtr p = IntPtr.Zero;
SecStatusCode result = SecTrustCopyPolicies (handle, ref p);
SecStatusCode result = SecTrustCopyPolicies (Handle, ref p);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
return NSArray.ArrayFromHandle<SecPolicy> (p);
@ -58,7 +58,7 @@ namespace Security {
// the API accept the handle for a single policy or an array of them
void SetPolicies (IntPtr policy)
{
SecStatusCode result = SecTrustSetPolicies (handle, policy);
SecStatusCode result = SecTrustSetPolicies (Handle, policy);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
}
@ -106,13 +106,13 @@ namespace Security {
public bool NetworkFetchAllowed {
get {
bool value;
SecStatusCode result = SecTrustGetNetworkFetchAllowed (handle, out value);
SecStatusCode result = SecTrustGetNetworkFetchAllowed (Handle, out value);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
return value;
}
set {
SecStatusCode result = SecTrustSetNetworkFetchAllowed (handle, value);
SecStatusCode result = SecTrustSetNetworkFetchAllowed (Handle, value);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
}
@ -130,7 +130,7 @@ namespace Security {
public SecCertificate[] GetCustomAnchorCertificates ()
{
IntPtr p;
SecStatusCode result = SecTrustCopyCustomAnchorCertificates (handle, out p);
SecStatusCode result = SecTrustCopyCustomAnchorCertificates (Handle, out p);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
return NSArray.ArrayFromHandle<SecCertificate> (p);
@ -205,7 +205,7 @@ namespace Security {
BlockLiteral block_handler = new BlockLiteral ();
try {
block_handler.SetupBlockUnsafe (evaluate, handler);
return SecTrustEvaluateAsync (handle, queue.Handle, ref block_handler);
return SecTrustEvaluateAsync (Handle, queue.Handle, ref block_handler);
}
finally {
block_handler.CleanupBlock ();
@ -255,7 +255,7 @@ namespace Security {
BlockLiteral block_handler = new BlockLiteral ();
try {
block_handler.SetupBlockUnsafe (evaluate_error, handler);
return SecTrustEvaluateAsyncWithError (handle, queue.Handle, ref block_handler);
return SecTrustEvaluateAsyncWithError (Handle, queue.Handle, ref block_handler);
}
finally {
block_handler.CleanupBlock ();
@ -274,7 +274,7 @@ namespace Security {
public SecTrustResult GetTrustResult ()
{
SecTrustResult trust_result;
SecStatusCode result = SecTrustGetTrustResult (handle, out trust_result);
SecStatusCode result = SecTrustGetTrustResult (Handle, out trust_result);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
return trust_result;
@ -300,7 +300,7 @@ namespace Security {
#endif
public bool Evaluate (out NSError error)
{
var result = SecTrustEvaluateWithError (handle, out var err);
var result = SecTrustEvaluateWithError (Handle, out var err);
error = err == IntPtr.Zero ? null : new NSError (err);
return result;
}
@ -316,7 +316,7 @@ namespace Security {
#endif
public NSDictionary GetResult ()
{
return new NSDictionary (SecTrustCopyResult (handle), true);
return new NSDictionary (SecTrustCopyResult (Handle), true);
}
#if !NET
@ -331,7 +331,7 @@ namespace Security {
#endif
void SetOCSPResponse (IntPtr ocsp)
{
SecStatusCode result = SecTrustSetOCSPResponse (handle, ocsp);
SecStatusCode result = SecTrustSetOCSPResponse (Handle, ocsp);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
}
@ -396,10 +396,10 @@ namespace Security {
public SecStatusCode SetSignedCertificateTimestamps (IEnumerable<NSData> sct)
{
if (sct == null)
return SecTrustSetSignedCertificateTimestamps (handle, IntPtr.Zero);
return SecTrustSetSignedCertificateTimestamps (Handle, IntPtr.Zero);
using (var array = NSArray.FromNSObjects (sct.ToArray ()))
return SecTrustSetSignedCertificateTimestamps (handle, array.Handle);
return SecTrustSetSignedCertificateTimestamps (Handle, array.Handle);
}
#if !NET
@ -414,7 +414,7 @@ namespace Security {
#endif
public SecStatusCode SetSignedCertificateTimestamps (NSArray<NSData> sct)
{
return SecTrustSetSignedCertificateTimestamps (handle, sct.GetHandle ());
return SecTrustSetSignedCertificateTimestamps (Handle, sct.GetHandle ());
}
}
}

Просмотреть файл

@ -27,6 +27,9 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#nullable enable
using System;
using System.Runtime.InteropServices;
using System.Security;
@ -39,23 +42,18 @@ using System.Runtime.Versioning;
#endif
namespace Security {
public partial class SecTrust : INativeObject, IDisposable {
IntPtr handle;
public partial class SecTrust : NativeObject {
#if !XAMCORE_4_0
public SecTrust (IntPtr handle)
: this (handle, false)
: base (handle, false)
{
}
#endif
[Preserve (Conditional=true)]
internal SecTrust (IntPtr handle, bool owns)
: base (handle, owns)
{
if (handle == IntPtr.Zero)
throw new Exception ("Invalid handle");
this.handle = handle;
if (!owns)
CFObject.CFRetain (handle);
}
#if !COREBUILD
@ -70,30 +68,30 @@ namespace Security {
/* SecTrustRef *__nonull */ out IntPtr sectrustref);
public SecTrust (X509Certificate certificate, SecPolicy policy)
public SecTrust (X509Certificate certificate, SecPolicy? policy)
{
if (certificate == null)
throw new ArgumentNullException ("certificate");
if (certificate is null)
throw new ArgumentNullException (nameof (certificate));
using (SecCertificate cert = new SecCertificate (certificate)) {
Initialize (cert.Handle, policy);
}
}
public SecTrust (X509Certificate2 certificate, SecPolicy policy)
public SecTrust (X509Certificate2 certificate, SecPolicy? policy)
{
if (certificate == null)
throw new ArgumentNullException ("certificate");
if (certificate is null)
throw new ArgumentNullException (nameof (certificate));
using (SecCertificate cert = new SecCertificate (certificate)) {
Initialize (cert.Handle, policy);
}
}
public SecTrust (X509CertificateCollection certificates, SecPolicy policy)
public SecTrust (X509CertificateCollection certificates, SecPolicy? policy)
{
if (certificates == null)
throw new ArgumentNullException ("certificates");
if (certificates is null)
throw new ArgumentNullException (nameof (certificates));
SecCertificate[] array = new SecCertificate [certificates.Count];
int i = 0;
@ -102,10 +100,10 @@ namespace Security {
Initialize (array, policy);
}
public SecTrust (X509Certificate2Collection certificates, SecPolicy policy)
public SecTrust (X509Certificate2Collection certificates, SecPolicy? policy)
{
if (certificates == null)
throw new ArgumentNullException ("certificates");
if (certificates is null)
throw new ArgumentNullException (nameof (certificates));
SecCertificate[] array = new SecCertificate [certificates.Count];
int i = 0;
@ -114,18 +112,19 @@ namespace Security {
Initialize (array, policy);
}
void Initialize (SecCertificate[] array, SecPolicy policy)
void Initialize (SecCertificate[] array, SecPolicy? policy)
{
using (var certs = CFArray.FromNativeObjects (array)) {
Initialize (certs.Handle, policy);
}
}
void Initialize (IntPtr certHandle, SecPolicy policy)
void Initialize (IntPtr certHandle, SecPolicy? policy)
{
SecStatusCode result = SecTrustCreateWithCertificates (certHandle, policy == null ? IntPtr.Zero : policy.Handle, out handle);
SecStatusCode result = SecTrustCreateWithCertificates (certHandle, policy.GetHandle (), out var handle);
if (result != SecStatusCode.Success)
throw new ArgumentException (result.ToString ());
InitializeHandle (handle);
}
#if !NET
@ -167,11 +166,8 @@ namespace Security {
#endif
public SecTrustResult Evaluate ()
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
SecTrustResult trust;
SecStatusCode result = SecTrustEvaluate (handle, out trust);
SecStatusCode result = SecTrustEvaluate (GetCheckedHandle (), out trust);
if (result != SecStatusCode.Success)
throw new InvalidOperationException (result.ToString ());
return trust;
@ -182,9 +178,9 @@ namespace Security {
public int Count {
get {
if (handle == IntPtr.Zero)
if (Handle == IntPtr.Zero)
return 0;
return (int) SecTrustGetCertificateCount (handle);
return (int) SecTrustGetCertificateCount (Handle);
}
}
@ -236,12 +232,10 @@ namespace Security {
#endif
public SecCertificate this [nint index] {
get {
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
if ((index < 0) || (index >= Count))
throw new ArgumentOutOfRangeException ("index");
throw new ArgumentOutOfRangeException (nameof (index));
return new SecCertificate (SecTrustGetCertificateAtIndex (handle, index));
return new SecCertificate (SecTrustGetCertificateAtIndex (GetCheckedHandle (), index));
}
}
@ -265,7 +259,7 @@ namespace Security {
[Watch (8,0), TV (15,0), Mac (12,0), iOS (15,0), MacCatalyst (15,0)]
#endif
public SecCertificate[] GetCertificateChain ()
=> NSArray.ArrayFromHandle<SecCertificate> (SecTrustCopyCertificateChain (handle));
=> NSArray.ArrayFromHandle<SecCertificate> (SecTrustCopyCertificateChain (Handle));
#if !NET
[Deprecated (PlatformName.iOS, 14,0)]
@ -299,10 +293,7 @@ namespace Security {
#endif
public SecKey GetPublicKey ()
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
return new SecKey (SecTrustCopyPublicKey (handle), true);
return new SecKey (SecTrustCopyPublicKey (GetCheckedHandle ()), true);
}
#if !NET
@ -334,10 +325,7 @@ namespace Security {
#endif
public SecKey GetKey ()
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
return new SecKey (SecTrustCopyKey (handle), true);
return new SecKey (SecTrustCopyKey (GetCheckedHandle ()), true);
}
#if !NET
@ -351,10 +339,7 @@ namespace Security {
#endif
public NSData GetExceptions ()
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
return new NSData (SecTrustCopyExceptions (handle), false); // inverted boolean?
return new NSData (SecTrustCopyExceptions (GetCheckedHandle ()), false); // inverted boolean?
}
#if !NET
@ -369,11 +354,7 @@ namespace Security {
#endif
public bool SetExceptions (NSData data)
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
IntPtr p = data == null ? IntPtr.Zero : data.Handle;
return SecTrustSetExceptions (handle, p);
return SecTrustSetExceptions (GetCheckedHandle (), data.GetHandle ());
}
[DllImport (Constants.SecurityLibrary)]
@ -381,10 +362,7 @@ namespace Security {
public double GetVerifyTime ()
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
return SecTrustGetVerifyTime (handle);
return SecTrustGetVerifyTime (GetCheckedHandle ());
}
[DllImport (Constants.SecurityLibrary)]
@ -392,12 +370,9 @@ namespace Security {
public SecStatusCode SetVerifyDate (DateTime date)
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
// CFDateRef amd NSDate are toll-freee bridged
using (NSDate d = (NSDate) date) {
return SecTrustSetVerifyDate (handle, d.Handle);
return SecTrustSetVerifyDate (GetCheckedHandle (), d.Handle);
}
}
@ -406,10 +381,8 @@ namespace Security {
public SecStatusCode SetAnchorCertificates (X509CertificateCollection certificates)
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
if (certificates == null)
return SecTrustSetAnchorCertificates (handle, IntPtr.Zero);
if (certificates is null)
return SecTrustSetAnchorCertificates (GetCheckedHandle (), IntPtr.Zero);
SecCertificate[] array = new SecCertificate [certificates.Count];
int i = 0;
@ -420,10 +393,8 @@ namespace Security {
public SecStatusCode SetAnchorCertificates (X509Certificate2Collection certificates)
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
if (certificates == null)
return SecTrustSetAnchorCertificates (handle, IntPtr.Zero);
if (certificates is null)
return SecTrustSetAnchorCertificates (GetCheckedHandle (), IntPtr.Zero);
SecCertificate[] array = new SecCertificate [certificates.Count];
int i = 0;
@ -434,10 +405,10 @@ namespace Security {
public SecStatusCode SetAnchorCertificates (SecCertificate[] array)
{
if (array == null)
return SecTrustSetAnchorCertificates (handle, IntPtr.Zero);
if (array is null)
return SecTrustSetAnchorCertificates (Handle, IntPtr.Zero);
using (var certs = CFArray.FromNativeObjects (array)) {
return SecTrustSetAnchorCertificates (handle, certs.Handle);
return SecTrustSetAnchorCertificates (Handle, certs.Handle);
}
}
@ -446,35 +417,8 @@ namespace Security {
public SecStatusCode SetAnchorCertificatesOnly (bool anchorCertificatesOnly)
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("SecTrust");
return SecTrustSetAnchorCertificatesOnly (handle, anchorCertificatesOnly);
return SecTrustSetAnchorCertificatesOnly (GetCheckedHandle (), anchorCertificatesOnly);
}
#endif
~SecTrust ()
{
Dispose (false);
}
protected virtual void Dispose (bool disposing)
{
if (handle != IntPtr.Zero) {
CFObject.CFRelease (handle);
handle = IntPtr.Zero;
}
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
public IntPtr Handle {
get { return handle; }
}
}
}