Xamarin Public Jenkins f3e3aab35a Imported Upstream version 4.3.2.467
Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
2016-02-22 11:00:01 -05:00

209 lines
4.8 KiB
C#

//
// SafeHandles.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if MONO_FEATURE_NEW_TLS && SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
using IMonoTlsContext = MonoSecurity::Mono.Security.Interface.IMonoTlsContext;
#else
using IMonoTlsContext = Mono.Security.Interface.IMonoTlsContext;
#endif
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
namespace System.Net.Security
{
class DummySafeHandle : SafeHandle
{
protected DummySafeHandle ()
: base ((IntPtr)(-1), true)
{
}
protected override bool ReleaseHandle ()
{
return true;
}
public override bool IsInvalid {
get { return handle == (IntPtr)(-1); }
}
}
class SafeFreeCertContext : DummySafeHandle
{
}
class SafeFreeCredentials : DummySafeHandle
{
SecureCredential credential;
public X509Certificate2 Certificate {
get {
if (IsInvalid)
throw new ObjectDisposedException ("Certificate");
return credential.certificate;
}
}
public SafeFreeCredentials (SecureCredential credential)
{
this.credential = credential;
bool success = true;
DangerousAddRef (ref success);
}
public override bool IsInvalid {
get {
return credential.certificate == null;
}
}
protected override bool ReleaseHandle ()
{
credential.Clear ();
return base.ReleaseHandle ();
}
}
class SafeDeleteContext : DummySafeHandle
{
IMonoTlsContext context;
public IMonoTlsContext Context {
get {
if (IsInvalid)
throw new ObjectDisposedException ("TlsContext");
return context;
}
}
public SafeDeleteContext (IMonoTlsContext context)
{
this.context = context;
}
public override bool IsInvalid {
get {
return context == null || !context.IsValid;
}
}
protected override bool ReleaseHandle ()
{
context.Dispose ();
context = null;
return base.ReleaseHandle ();
}
}
struct SecureCredential
{
public const int CurrentVersion = 0x4;
[Flags]
public enum Flags
{
Zero = 0,
NoSystemMapper = 0x02,
NoNameCheck = 0x04,
ValidateManual = 0x08,
NoDefaultCred = 0x10,
ValidateAuto = 0x20,
UseStrongCrypto = 0x00400000
}
int version;
internal X509Certificate2 certificate;
SchProtocols protocols;
EncryptionPolicy policy;
public SecureCredential (int version, X509Certificate2 certificate, SecureCredential.Flags flags, SchProtocols protocols, EncryptionPolicy policy)
{
this.version = version;
this.certificate = certificate;
this.protocols = protocols;
this.policy = policy;
}
public void Clear ()
{
certificate = null;
}
}
internal class SafeCredentialReference : DummySafeHandle
{
//
// Static cache will return the target handle if found the reference in the table.
//
internal SafeFreeCredentials _Target;
//
//
internal static SafeCredentialReference CreateReference (SafeFreeCredentials target)
{
SafeCredentialReference result = new SafeCredentialReference (target);
if (result.IsInvalid)
return null;
return result;
}
private SafeCredentialReference (SafeFreeCredentials target)
: base ()
{
// Bumps up the refcount on Target to signify that target handle is statically cached so
// its dispose should be postponed
bool b = false;
try {
target.DangerousAddRef (ref b);
} catch {
if (b) {
target.DangerousRelease ();
b = false;
}
} finally {
if (b) {
_Target = target;
SetHandle (new IntPtr (0)); // make this handle valid
}
}
}
override protected bool ReleaseHandle ()
{
SafeFreeCredentials target = _Target;
if (target != null)
target.DangerousRelease ();
_Target = null;
return true;
}
}
}
#endif