private SafeCredentialReference(SafeFreeCredentials target) { bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { target.DangerousAddRef(ref success); } catch { if (success) { target.DangerousRelease(); success = false; } } finally { if (success) { this._Target = target; base.SetHandle(new IntPtr(0)); } } }
private SafeCredentialReference(SafeFreeCredentials target) { bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { target.DangerousAddRef(ref success); } catch { if (success) { target.DangerousRelease(); success = false; } } finally { if (success) { this._Target = target; base.SetHandle(new IntPtr(0)); } } }
public SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { SafeFreeCredentials retVal = new SafeFreeCredentials(certificate, protocols, policy); if (null != retVal) { // Caller does a ref count decrement bool ignore = false; retVal.DangerousAddRef(ref ignore); // TODO (Issue #3362) retVal is not getting released now, need to be fixed. } return(retVal); }
// // After PINvoke call the method will fix the handleTemplate.handle with the returned value. // The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned. // // Since it has a CER, this method can't have any references to imports from DLLs that may not exist on the system. // private static unsafe int MustRunAcceptSecurityContext_SECURITY( ref SafeFreeCredentials inCredentials, void* inContextPtr, SecurityBufferDescriptor inputBuffer, ContextFlags inFlags, Endianness endianness, SafeDeleteContext outContext, SecurityBufferDescriptor outputBuffer, ref ContextFlags outFlags, SafeFreeContextBuffer handleTemplate) { int errorCode = (int) SecurityStatus.InvalidHandle; bool b1 = false; bool b2 = false; // Run the body of this method as a non-interruptible block. RuntimeHelpers.PrepareConstrainedRegions(); try { inCredentials.DangerousAddRef(ref b1); outContext.DangerousAddRef(ref b2); } catch(Exception e) { if (b1) { inCredentials.DangerousRelease(); b1 = false; } if (b2) { outContext.DangerousRelease(); b2 = false; } if (!(e is ObjectDisposedException)) throw; } finally { SSPIHandle credentialHandle = inCredentials._handle; long timeStamp; if (!b1) { // caller should retry inCredentials = null; } else if (b1 && b2) { errorCode = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.AcceptSecurityContext( ref credentialHandle, inContextPtr, inputBuffer, inFlags, endianness, ref outContext._handle, outputBuffer, ref outFlags, out timeStamp); // // When a credential handle is first associated with the context we keep credential // ref count bumped up to ensure ordered finalization. // If the credential handle has been changed we de-ref the old one and associate the // context with the new cred handle but only if the call was successful. if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0) { // Disassociate the previous credential handle if (outContext._EffectiveCredential != null) outContext._EffectiveCredential.DangerousRelease(); outContext._EffectiveCredential = inCredentials; } else { inCredentials.DangerousRelease(); } outContext.DangerousRelease(); // The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer. if (handleTemplate != null) { handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes if (handleTemplate.IsInvalid) { handleTemplate.SetHandleAsInvalid(); } } } if (inContextPtr == null && (errorCode & 0x80000000) != 0) { // an error on the first call, need to set the out handle to invalid value outContext._handle.SetToInvalid(); } } return errorCode; }
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; RuntimeHelpers.PrepareConstrainedRegions(); 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 } } }
private SecurityStatus HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired) { Debug.Assert(!credential.IsInvalid); bool gotCredReference = false; bool gotContextReference = false; try { credential.DangerousAddRef(ref gotCredReference); if ((null == context) || context.IsInvalid) { long options = GetOptions(credential.Protocols); IntPtr contextPtr = Interop.OpenSsl.AllocateSslContext( options, credential.CertHandle, credential.CertKeyHandle, isServer, remoteCertRequired); context = new SafeDeleteContext(contextPtr, credential); } context.DangerousAddRef(ref gotContextReference); IntPtr inputPtr = IntPtr.Zero, outputPtr = IntPtr.Zero; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(context.DangerousGetHandle(), inputPtr, 0, out outputPtr, out outputSize); } else { unsafe { fixed(byte *tokenPtr = inputBuffer.token) { inputPtr = new IntPtr(tokenPtr + inputBuffer.offset); done = Interop.OpenSsl.DoSslHandshake(context.DangerousGetHandle(), inputPtr, inputBuffer.size, out outputPtr, out outputSize); } } } outputBuffer.size = outputSize; outputBuffer.offset = 0; if (outputSize > 0) { outputBuffer.token = new byte[outputBuffer.size]; Marshal.Copy(outputPtr, outputBuffer.token, 0, outputBuffer.size); } else { outputBuffer.token = null; } if (outputPtr != IntPtr.Zero) { Marshal.FreeHGlobal(outputPtr); outputPtr = IntPtr.Zero; } return(done ? SecurityStatus.OK : SecurityStatus.ContinueNeeded); } catch (Exception ex) { Debug.Fail("Exception Caught. - " + ex); return(SecurityStatus.InternalError); } finally { if (gotContextReference) { context.DangerousRelease(); } if (gotCredReference) { credential.DangerousRelease(); } } }