Merge pull request #2955 from ludovic-henry/mono_msec_ticks-overflow
[mono.git] / mcs / class / referencesource / System.Web / Util / TlsTokenBindingHandle.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="TlsTokenBindingHandle.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.Web.Util {
8     using System;
9     using System.Diagnostics.CodeAnalysis;
10     using System.Runtime.CompilerServices;
11     using System.Runtime.InteropServices;
12     using System.Web.Hosting;
13
14     internal sealed class TlsTokenBindingHandle : HeapAllocHandle {
15         [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Justification = @"Pointer is valid while this SafeHandle is valid.")]
16         private readonly IntPtr _providedTokenBlob;
17         private readonly uint _providedTokenBlobSize;
18         [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Justification = @"Pointer is valid while this SafeHandle is valid.")]
19         private readonly IntPtr _referredTokenBlob;
20         private readonly uint _referredtokenBlobSize;
21
22         internal TlsTokenBindingHandle(IntPtr mgdContext) {
23             int hr = UnsafeIISMethods.MgdGetTlsTokenBindingIdentifiers(
24                 mgdContext,
25                 ref handle,
26                 out _providedTokenBlob,
27                 out _providedTokenBlobSize,
28                 out _referredTokenBlob,
29                 out _referredtokenBlobSize);
30             Misc.ThrowIfFailedHr(hr);
31         }
32
33         public byte[] GetProvidedToken() {
34             return GetTokenImpl(_providedTokenBlob, _providedTokenBlobSize);
35         }
36
37         public byte[] GetReferredToken() {
38             return GetTokenImpl(_referredTokenBlob, _referredtokenBlobSize);
39         }
40
41         private byte[] GetTokenImpl(IntPtr blob, uint blobSize) {
42             if (blob == IntPtr.Zero || blobSize == 0) {
43                 return null;
44             }
45             else {
46                 byte[] retVal = new byte[blobSize];
47                 int length = retVal.Length; // checks for overflow
48                 bool refAdded = false;
49
50                 RuntimeHelpers.PrepareConstrainedRegions();
51                 try
52                 {
53                     DangerousAddRef(ref refAdded);
54                     Marshal.Copy(blob, retVal, 0, length);
55                 }
56                 finally
57                 {
58                     if (refAdded)
59                     {
60                         DangerousRelease();
61                     }
62                 }
63
64                 return retVal;
65             }
66         }
67     }
68 }