Exemple #1
0
        private unsafe void CounterSign(CmsSigner signer)
        {
            // Sanity check.
            Debug.Assert(signer != null);

            //


            CspParameters parameters = new CspParameters();

            if (X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters) == false)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            KeyContainerPermission            kp    = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
            KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign);

            kp.AccessEntries.Add(entry);
            kp.Demand();

            // Get the signer's index.
            uint index = (uint)PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0);

            // Create CMSG_SIGNER_ENCODE_INFO structure.
            SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer);

            try {
                // Marshal to unmanaged memory.
                Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false);

                // Counter sign.
                if (!CAPI.CryptMsgCountersign(m_signedCms.GetCryptMsgHandle(),
                                              index,
                                              1,
                                              pSignerEncodeInfo.DangerousGetHandle()))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                // CAPI requires that the messge be re-encoded if any unauthenticated
                // attribute has been added. So, let's re-open it to decode to work
                // around this limitation.
                m_signedCms.ReopenToDecode();
            }
            finally {
                Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                pSignerEncodeInfo.Dispose();

                // and don't forget to dispose of resources allocated for the structure.
                signerEncodeInfo.Dispose();
            }

            // Finally, add certs to bag of certs.
            PkcsUtils.AddCertsToMessage(m_signedCms.GetCryptMsgHandle(), m_signedCms.Certificates, PkcsUtils.CreateBagOfCertificates(signer));

            return;
        }
Exemple #2
0
        private void CoSign(CmsSigner signer, bool silent)
        {
            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent);

            try {
                SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

                try {
                    // Marshal to unmanaged memory.
                    Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false);

                    // Add the signature.
                    if (!CAPI.CryptMsgControl(m_safeCryptMsgHandle,
                                              0,
                                              CAPI.CMSG_CTRL_ADD_SIGNER,
                                              pSignerEncodeInfo.DangerousGetHandle()))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
                finally {
                    Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                    pSignerEncodeInfo.Dispose();
                }
            }
            finally {
                // and don't forget to dispose of resources allocated for the structure.
                signerEncodeInfo.Dispose();
            }

            // Finally, add certs to bag of certs.
            PkcsUtils.AddCertsToMessage(m_safeCryptMsgHandle, Certificates, PkcsUtils.CreateBagOfCertificates(signer));
        }
Exemple #3
0
        internal AlgorithmIdentifier(CAPI.CERT_PUBLIC_KEY_INFO keyInfo)
        {
            SafeLocalAllocHandle pKeyInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO))));

            Marshal.StructureToPtr(keyInfo, pKeyInfo.DangerousGetHandle(), false);
            int keyLength = (int)CAPI.CAPISafe.CertGetPublicKeyLength(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pKeyInfo.DangerousGetHandle());

            byte[] parameters = new byte[keyInfo.Algorithm.Parameters.cbData];
            if (parameters.Length > 0)
            {
                Marshal.Copy(keyInfo.Algorithm.Parameters.pbData, parameters, 0, parameters.Length);
            }
            Marshal.DestroyStructure(pKeyInfo.DangerousGetHandle(), typeof(CAPI.CERT_PUBLIC_KEY_INFO));
            pKeyInfo.Dispose();
            Reset(Oid.FromOidValue(keyInfo.Algorithm.pszObjId, OidGroup.PublicKeyAlgorithm), keyLength, parameters);
        }
Exemple #4
0
        internal unsafe SignerInfo(SignedCms signedCms, SignerInfo parentSignerInfo, byte[] encodedSignerInfo)
        {
            // Sanity check.
            Debug.Assert(signedCms != null && encodedSignerInfo != null && encodedSignerInfo.Length > 0);

            uint cbCmsgSignerInfo = 0;
            SafeLocalAllocHandle pbCmsgSignerInfo = SafeLocalAllocHandle.InvalidHandle;

            fixed(byte *pEncodedSignerInfo = &encodedSignerInfo[0])
            {
                if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS7_SIGNER_INFO),
                                       new IntPtr(pEncodedSignerInfo),
                                       (uint)encodedSignerInfo.Length,
                                       out pbCmsgSignerInfo,
                                       out cbCmsgSignerInfo))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }

            m_signedCms         = signedCms;
            m_parentSignerInfo  = parentSignerInfo;
            m_encodedSignerInfo = (byte[])encodedSignerInfo.Clone();
            m_pbCmsgSignerInfo  = pbCmsgSignerInfo;
            m_cmsgSignerInfo    = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO));
        }
Exemple #5
0
        // Private callback invoked when icmpsendecho APIs succeed.
        private static void PingCallback(object state, bool signaled)
        {
            Ping ping = (Ping)state;
            PingCompletedEventArgs eventArgs           = null;
            bool               cancelled               = false;
            AsyncOperation     asyncOp                 = null;
            SendOrPostCallback onPingCompletedDelegate = null;

            try
            {
                lock (ping._lockObject)
                {
                    cancelled = ping._cancelled;
                    asyncOp   = ping._asyncOp;
                    onPingCompletedDelegate = ping._onPingCompletedDelegate;

                    if (!cancelled)
                    {
                        // Parse reply buffer.
                        SafeLocalAllocHandle buffer = ping._replyBuffer;

                        // Marshals and constructs new reply.
                        PingReply reply;

                        if (ping._ipv6)
                        {
                            Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure <Interop.IpHlpApi.Icmp6EchoReply>(buffer.DangerousGetHandle());
                            reply = new PingReply(icmp6Reply, buffer.DangerousGetHandle(), ping._sendSize);
                        }
                        else
                        {
                            Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure <Interop.IpHlpApi.IcmpEchoReply>(buffer.DangerousGetHandle());
                            reply = new PingReply(icmpReply);
                        }

                        eventArgs = new PingCompletedEventArgs(reply, null, false, asyncOp.UserSuppliedState);
                    }
                    else
                    {
                        // Canceled.
                        eventArgs = new PingCompletedEventArgs(null, null, true, asyncOp.UserSuppliedState);
                    }
                }
            }
            catch (Exception e)
            {
                // In case of failure, create a failed event arg.
                PingException pe = new PingException(SR.net_ping, e);
                eventArgs = new PingCompletedEventArgs(null, pe, false, asyncOp.UserSuppliedState);
            }
            finally
            {
                ping.FreeUnmanagedStructures();
                ping.UnregisterWaitHandle();
                ping.Finish(true);
            }

            asyncOp.PostOperationCompleted(onPingCompletedDelegate, eventArgs);
        }
Exemple #6
0
        // Private callback invoked when icmpsendecho APIs succeed.
        private void PingCallback()
        {
            TaskCompletionSource <PingReply> tcs = _taskCompletionSource;

            _taskCompletionSource = null;

            PingReply reply    = null;
            Exception error    = null;
            bool      canceled = false;

            try
            {
                lock (_lockObject)
                {
                    canceled = _canceled;

                    // Parse reply buffer.
                    SafeLocalAllocHandle buffer = _replyBuffer;

                    // Marshals and constructs new reply.
                    if (_ipv6)
                    {
                        Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure <Interop.IpHlpApi.Icmp6EchoReply>(buffer.DangerousGetHandle());
                        reply = CreatePingReplyFromIcmp6EchoReply(icmp6Reply, buffer.DangerousGetHandle(), _sendSize);
                    }
                    else
                    {
                        Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure <Interop.IpHlpApi.IcmpEchoReply>(buffer.DangerousGetHandle());
                        reply = CreatePingReplyFromIcmpEchoReply(icmpReply);
                    }
                }
            }
            catch (Exception e)
            {
                // In case of failure, create a failed event arg.
                error = new PingException(SR.net_ping, e);
            }
            finally
            {
                FreeUnmanagedStructures();
                UnregisterWaitHandle();
                Finish();
            }

            // Once we've called Finish, complete the task
            if (canceled)
            {
                tcs.SetCanceled();
            }
            else if (reply != null)
            {
                tcs.SetResult(reply);
            }
            else
            {
                Debug.Assert(error != null);
                tcs.SetException(error);
            }
        }
Exemple #7
0
        private static byte[] Encode(DateTime signingTime)
        {
            long ft = signingTime.ToFileTimeUtc();
            SafeLocalAllocHandle pbSigningTime = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(Int64))));

            Marshal.WriteInt64(pbSigningTime.DangerousGetHandle(), ft);

            byte[] encodedSigningTime = new byte[0];
            if (!CAPI.EncodeObject(CAPI.szOID_RSA_signingTime, pbSigningTime.DangerousGetHandle(), out encodedSigningTime))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            pbSigningTime.Dispose();

            return(encodedSigningTime);
        }
Exemple #8
0
 internal SignerInfo(SignedCms signedCms, SafeLocalAllocHandle pbCmsgSignerInfo)
 {
     this.m_signedCms = signedCms;
     this.m_parentSignerInfo = (SignerInfo)null;
     this.m_encodedSignerInfo = (byte[])null;
     this.m_pbCmsgSignerInfo = pbCmsgSignerInfo;
     this.m_cmsgSignerInfo = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO));
 }
Exemple #9
0
        internal static NetworkInterface[] GetNetworkInterfaces()
        {
            Contract.Ensures(Contract.Result <NetworkInterface[]>() != null);
            AddressFamily        family     = AddressFamily.Unspecified;
            uint                 bufferSize = 0;
            SafeLocalAllocHandle buffer     = null;

            // TODO: #2485: This will probably require changes in the PAL for HostInformation.
            Interop.IpHlpApi.FIXED_INFO   fixedInfo     = HostInformationPal.GetFixedInfo();
            List <SystemNetworkInterface> interfaceList = new List <SystemNetworkInterface>();

            Interop.IpHlpApi.GetAdaptersAddressesFlags flags =
                Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeGateways
                | Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeWins;

            // Figure out the right buffer size for the adapter information.
            uint result = Interop.IpHlpApi.GetAdaptersAddresses(
                family, (uint)flags, IntPtr.Zero, SafeLocalAllocHandle.Zero, ref bufferSize);

            while (result == Interop.IpHlpApi.ERROR_BUFFER_OVERFLOW)
            {
                // Allocate the buffer and get the adapter info.
                using (buffer = SafeLocalAllocHandle.LocalAlloc((int)bufferSize))
                {
                    result = Interop.IpHlpApi.GetAdaptersAddresses(
                        family, (uint)flags, IntPtr.Zero, buffer, ref bufferSize);

                    // If succeeded, we're going to add each new interface.
                    if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                    {
                        // Linked list of interfaces.
                        IntPtr ptr = buffer.DangerousGetHandle();
                        while (ptr != IntPtr.Zero)
                        {
                            // Traverse the list, marshal in the native structures, and create new NetworkInterfaces.
                            Interop.IpHlpApi.IpAdapterAddresses adapterAddresses = Marshal.PtrToStructure <Interop.IpHlpApi.IpAdapterAddresses>(ptr);
                            interfaceList.Add(new SystemNetworkInterface(fixedInfo, adapterAddresses));

                            ptr = adapterAddresses.next;
                        }
                    }
                }
            }

            // If we don't have any interfaces detected, return empty.
            if (result == Interop.IpHlpApi.ERROR_NO_DATA || result == Interop.IpHlpApi.ERROR_INVALID_PARAMETER)
            {
                return(new SystemNetworkInterface[0]);
            }

            // Otherwise we throw on an error.
            if (result != Interop.IpHlpApi.ERROR_SUCCESS)
            {
                throw new NetworkInformationException((int)result);
            }

            return(interfaceList.ToArray());
        }
Exemple #10
0
        // Copies _requestBuffer into unmanaged memory for async icmpsendecho APIs.
        private unsafe void SetUnmanagedStructures(byte[] buffer)
        {
            _requestBuffer = SafeLocalAllocHandle.LocalAlloc(buffer.Length);
            byte *dst = (byte *)_requestBuffer.DangerousGetHandle();

            for (int i = 0; i < buffer.Length; ++i)
            {
                dst[i] = buffer[i];
            }
        }
Exemple #11
0
        internal SignerInfo(SignedCms signedCms, SafeLocalAllocHandle pbCmsgSignerInfo)
        {
            // Sanity check.
            Debug.Assert(signedCms != null && pbCmsgSignerInfo != null && !pbCmsgSignerInfo.IsInvalid);

            m_signedCms         = signedCms;
            m_parentSignerInfo  = null;
            m_encodedSignerInfo = null;
            m_pbCmsgSignerInfo  = pbCmsgSignerInfo;
            m_cmsgSignerInfo    = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO));
        }
Exemple #12
0
        [System.Security.SecurityCritical]  // auto-generated
        internal UNICODE_INTPTR_STRING(int stringBytes, SafeLocalAllocHandle buffer)
        {
            Debug.Assert(buffer == null || (stringBytes >= 0 && (ulong)stringBytes <= buffer.ByteLength),
                         "buffer == null || (stringBytes >= 0 && stringBytes <= buffer.ByteLength)");

            this.Length    = (ushort)stringBytes;
            this.MaxLength = (ushort)buffer.ByteLength;

            // Marshaling with a SafePointer does not work correctly, so unfortunately we need to extract
            // the raw handle here.
            this.Buffer = buffer.DangerousGetHandle();
        }
Exemple #13
0
        private PingReply CreatePingReply()
        {
            SafeLocalAllocHandle buffer = _replyBuffer;

            // Marshals and constructs new reply.
            if (_ipv6)
            {
                Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure <Interop.IpHlpApi.Icmp6EchoReply>(buffer.DangerousGetHandle());
                return(CreatePingReplyFromIcmp6EchoReply(icmp6Reply, buffer.DangerousGetHandle(), _sendSize));
            }

            Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure <Interop.IpHlpApi.IcmpEchoReply>(buffer.DangerousGetHandle());
            return(CreatePingReplyFromIcmpEchoReply(icmpReply));
        }
Exemple #14
0
        /// <summary>
        /// Convert each Oid's value to an ASCII string, then create an unmanaged array of "numOids" LPSTR pointers, one for each Oid.
        /// "numOids" is the number of LPSTR pointers. This is normally the same as oids.Count, except in the case where a malicious caller
        /// appends to the OidCollection while this method is in progress. In such a case, this method guarantees only that this won't create
        /// an unmanaged buffer overflow condition.
        /// </summary>
        public static SafeHandle ToLpstrArray(this OidCollection?oids, out int numOids)
        {
            if (oids == null || oids.Count == 0)
            {
                numOids = 0;
                return(SafeLocalAllocHandle.InvalidHandle);
            }

            // Copy the oid strings to a local array to prevent a security race condition where
            // the OidCollection or individual oids can be modified by another thread and
            // potentially cause a buffer overflow
            var oidStrings = new string[oids.Count];

            for (int i = 0; i < oidStrings.Length; i++)
            {
                oidStrings[i] = oids[i].Value !;
            }

            unsafe
            {
                int allocationSize = checked (oidStrings.Length * sizeof(void *));
                foreach (string oidString in oidStrings)
                {
                    checked
                    {
                        allocationSize += oidString.Length + 1; // Encoding.ASCII doesn't have a fallback, so it's fine to use String.Length
                    }
                }

                SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.Create(allocationSize);
                byte **pOidPointers = (byte **)(safeLocalAllocHandle.DangerousGetHandle());
                byte * pOidContents = (byte *)(pOidPointers + oidStrings.Length);

                for (int i = 0; i < oidStrings.Length; i++)
                {
                    string oidString = oidStrings[i];

                    pOidPointers[i] = pOidContents;

                    int bytesWritten = Encoding.ASCII.GetBytes(oidString, new Span <byte>(pOidContents, oidString.Length));
                    Debug.Assert(bytesWritten == oidString.Length);

                    pOidContents[oidString.Length] = 0;
                    pOidContents += oidString.Length + 1;
                }

                numOids = oidStrings.Length;
                return(safeLocalAllocHandle);
            }
        }
Exemple #15
0
        private void Decode()
        {
            uint cbDecoded = 0;
            SafeLocalAllocHandle pbDecoded = null;

            if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_UTC_TIME),
                                   RawData,
                                   out pbDecoded,
                                   out cbDecoded))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            long signingTime = Marshal.ReadInt64(pbDecoded.DangerousGetHandle());

            pbDecoded.Dispose();

            m_signingTime = DateTime.FromFileTimeUtc(signingTime);
            m_decoded     = true;
        }
Exemple #16
0
        internal unsafe SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber)
        {
            // If serial number is 0, then it is the special SKI encoding or NoSignature
            bool  isSKIorHashOnly = true;
            byte *pb = (byte *)serialNumber.pbData;

            for (uint i = 0; i < serialNumber.cbData; i++)
            {
                if (*pb++ != (byte)0)
                {
                    isSKIorHashOnly = false;
                    break;
                }
            }

            if (isSKIorHashOnly)
            {
                byte[] issuerBytes = new byte[issuer.cbData];
                Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length);
                X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes);
                if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    Reset(SubjectIdentifierType.NoSignature, null);
                    return;
                }
            }

            if (isSKIorHashOnly)
            {
                // Decode disguised SKI in issuer field (See WinCrypt.h for more info).  Note that some certificates may contain
                // an all-zero serial number but not be encoded with an szOID_KEYID_RDN.  In order to allow use of signatures created
                // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just
                // decoding the incoming issuer and serial number.
                m_type  = SubjectIdentifierType.SubjectKeyIdentifier;
                m_value = String.Empty;

                uint cbCertNameInfo = 0;
                SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle;

                if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME),
                                      issuer.pbData,
                                      issuer.cbData,
                                      out pbCertNameInfo,
                                      out cbCertNameInfo))
                {
                    using (pbCertNameInfo) {
                        checked {
                            CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO));
                            for (uint i = 0; i < certNameInfo.cRDN; i++)
                            {
                                CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)(i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN));

                                for (uint j = 0; j < certRdn.cRDNAttr; j++)
                                {
                                    CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR));

                                    if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING)
                                        {
                                            byte[] ski = new byte[certRdnAttr.Value.cbData];
                                            Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length);
                                            Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski));
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial;
            IssuerAndSerial.Issuer       = issuer;
            IssuerAndSerial.SerialNumber = serialNumber;
            X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial);

            Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial);
        }
Exemple #17
0
        /// <summary>
        /// Creates a Windows SID Claim and adds to collection of claims.
        /// </summary>
        private void AddPrimarySidClaim(List <Claim> instanceClaims)
        {
            // special case the anonymous identity.
            if (_safeTokenHandle.IsInvalid)
            {
                return;
            }

            SafeLocalAllocHandle safeAllocHandle = SafeLocalAllocHandle.InvalidHandle;

            try
            {
                safeAllocHandle = GetTokenInformation(_safeTokenHandle, TokenInformationClass.TokenUser);
                Interop.SID_AND_ATTRIBUTES user = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure <Interop.SID_AND_ATTRIBUTES>(safeAllocHandle.DangerousGetHandle());
                uint mask = Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY;

                SecurityIdentifier sid = new SecurityIdentifier(user.Sid, true);
                Claim claim;
                if (user.Attributes == 0)
                {
                    claim = new Claim(ClaimTypes.PrimarySid, sid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                    claim.Properties.Add(ClaimTypes.WindowsSubAuthority, sid.IdentifierAuthority.ToString());
                    instanceClaims.Add(claim);
                }
                else if ((user.Attributes & mask) == Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY)
                {
                    claim = new Claim(ClaimTypes.DenyOnlyPrimarySid, sid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                    claim.Properties.Add(ClaimTypes.WindowsSubAuthority, sid.IdentifierAuthority.ToString());
                    instanceClaims.Add(claim);
                }
            }
            finally
            {
                safeAllocHandle.Dispose();
            }
        }
Exemple #18
0
        /// <summary>
        /// Initializes a new instance of the WindowsIdentity class for the user represented by the specified User Principal Name (UPN).
        /// </summary>
        /// <remarks>
        /// Unlike the desktop version, we connect to Lsa only as an untrusted caller. We do not attempt to exploit Tcb privilege or adjust the current
        /// thread privilege to include Tcb.
        /// </remarks>
        public WindowsIdentity(string sUserPrincipalName)
            : base(null, null, null, ClaimTypes.Name, ClaimTypes.GroupSid)
        {
            // Desktop compat: See comments below for why we don't validate sUserPrincipalName.

            using (SafeLsaHandle lsaHandle = ConnectToLsa())
            {
                int packageId = LookupAuthenticationPackage(lsaHandle, Interop.SspiCli.AuthenticationPackageNames.MICROSOFT_KERBEROS_NAME_A);

                // 8 byte or less name that indicates the source of the access token. This choice of name is visible to callers through the native GetTokenInformation() api
                // so we'll use the same name the CLR used even though we're not actually the "CLR."
                byte[] sourceName = { (byte)'C', (byte)'L', (byte)'R', (byte)0 };

                TOKEN_SOURCE sourceContext;
                if (!Interop.Advapi32.AllocateLocallyUniqueId(out sourceContext.SourceIdentifier))
                {
                    throw new SecurityException(new Win32Exception().Message);
                }
                sourceContext.SourceName = new byte[TOKEN_SOURCE.TOKEN_SOURCE_LENGTH];
                Buffer.BlockCopy(sourceName, 0, sourceContext.SourceName, 0, sourceName.Length);

                // Desktop compat: Desktop never null-checks sUserPrincipalName. Actual behavior is that the null makes it down to Encoding.Unicode.GetBytes() which then throws
                // the ArgumentNullException (provided that the prior LSA calls didn't fail first.) To make this compat decision explicit, we'll null check ourselves
                // and simulate the exception from Encoding.Unicode.GetBytes().
                if (sUserPrincipalName == null)
                {
                    throw new ArgumentNullException("s");
                }

                byte[] upnBytes = Encoding.Unicode.GetBytes(sUserPrincipalName);
                if (upnBytes.Length > ushort.MaxValue)
                {
                    // Desktop compat: LSA only allocates 16 bits to hold the UPN size. We should throw an exception here but unfortunately, the desktop did an unchecked cast to ushort,
                    // effectively truncating upnBytes to the first (N % 64K) bytes. We'll simulate the same behavior here (albeit in a way that makes it look less accidental.)
                    Array.Resize(ref upnBytes, upnBytes.Length & ushort.MaxValue);
                }
                unsafe
                {
                    //
                    // Build the KERB_S4U_LOGON structure.  Note that the LSA expects this entire
                    // structure to be contained within the same block of memory, so we need to allocate
                    // enough room for both the structure itself and the UPN string in a single buffer
                    // and do the marshalling into this buffer by hand.
                    //
                    int authenticationInfoLength = checked (sizeof(KERB_S4U_LOGON) + upnBytes.Length);
                    using (SafeLocalAllocHandle authenticationInfo = Interop.Kernel32.LocalAlloc(0, new UIntPtr(checked ((uint)authenticationInfoLength))))
                    {
                        if (authenticationInfo.IsInvalid)
                        {
                            throw new OutOfMemoryException();
                        }

                        KERB_S4U_LOGON *pKerbS4uLogin = (KERB_S4U_LOGON *)(authenticationInfo.DangerousGetHandle());
                        pKerbS4uLogin->MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon;
                        pKerbS4uLogin->Flags       = KerbS4uLogonFlags.None;

                        pKerbS4uLogin->ClientUpn.Length = pKerbS4uLogin->ClientUpn.MaximumLength = checked ((ushort)upnBytes.Length);

                        IntPtr pUpnOffset = (IntPtr)(pKerbS4uLogin + 1);
                        pKerbS4uLogin->ClientUpn.Buffer = pUpnOffset;
                        Marshal.Copy(upnBytes, 0, pKerbS4uLogin->ClientUpn.Buffer, upnBytes.Length);

                        pKerbS4uLogin->ClientRealm.Length = pKerbS4uLogin->ClientRealm.MaximumLength = 0;
                        pKerbS4uLogin->ClientRealm.Buffer = IntPtr.Zero;

                        ushort sourceNameLength = checked ((ushort)(sourceName.Length));
                        using (SafeLocalAllocHandle sourceNameBuffer = Interop.Kernel32.LocalAlloc(0, new UIntPtr(sourceNameLength)))
                        {
                            if (sourceNameBuffer.IsInvalid)
                            {
                                throw new OutOfMemoryException();
                            }

                            Marshal.Copy(sourceName, 0, sourceNameBuffer.DangerousGetHandle(), sourceName.Length);
                            LSA_STRING lsaOriginName = new LSA_STRING(sourceNameBuffer.DangerousGetHandle(), sourceNameLength);

                            SafeLsaReturnBufferHandle profileBuffer;
                            int  profileBufferLength;
                            LUID logonId;
                            SafeAccessTokenHandle accessTokenHandle;
                            QUOTA_LIMITS          quota;
                            int subStatus;
                            int ntStatus = Interop.SspiCli.LsaLogonUser(
                                lsaHandle,
                                ref lsaOriginName,
                                SECURITY_LOGON_TYPE.Network,
                                packageId,
                                authenticationInfo.DangerousGetHandle(),
                                authenticationInfoLength,
                                IntPtr.Zero,
                                ref sourceContext,
                                out profileBuffer,
                                out profileBufferLength,
                                out logonId,
                                out accessTokenHandle,
                                out quota,
                                out subStatus);

                            if (ntStatus == unchecked ((int)Interop.StatusOptions.STATUS_ACCOUNT_RESTRICTION) && subStatus < 0)
                            {
                                ntStatus = subStatus;
                            }
                            if (ntStatus < 0) // non-negative numbers indicate success
                            {
                                throw GetExceptionFromNtStatus(ntStatus);
                            }
                            if (subStatus < 0) // non-negative numbers indicate success
                            {
                                throw GetExceptionFromNtStatus(subStatus);
                            }

                            if (profileBuffer != null)
                            {
                                profileBuffer.Dispose();
                            }

                            _safeTokenHandle = accessTokenHandle;
                        }
                    }
                }
            }
        }
 internal UNICODE_INTPTR_STRING(int stringBytes, SafeLocalAllocHandle buffer)
 {
     Length = (ushort)stringBytes;
     MaxLength = (ushort)buffer.ByteLength;
     Buffer = buffer.DangerousGetHandle();
 }
Exemple #20
0
        /// <summary>
        /// Creates a collection of SID claims that represent the users groups.
        /// </summary>
        private void AddGroupSidClaims(List <Claim> instanceClaims)
        {
            // special case the anonymous identity.
            if (_safeTokenHandle.IsInvalid)
            {
                return;
            }

            SafeLocalAllocHandle safeAllocHandle             = SafeLocalAllocHandle.InvalidHandle;
            SafeLocalAllocHandle safeAllocHandlePrimaryGroup = SafeLocalAllocHandle.InvalidHandle;

            try
            {
                // Retrieve the primary group sid
                safeAllocHandlePrimaryGroup = GetTokenInformation(_safeTokenHandle, TokenInformationClass.TokenPrimaryGroup);
                Interop.TOKEN_PRIMARY_GROUP primaryGroup    = (Interop.TOKEN_PRIMARY_GROUP)Marshal.PtrToStructure <Interop.TOKEN_PRIMARY_GROUP>(safeAllocHandlePrimaryGroup.DangerousGetHandle());
                SecurityIdentifier          primaryGroupSid = new SecurityIdentifier(primaryGroup.PrimaryGroup, true);

                // only add one primary group sid
                bool foundPrimaryGroupSid = false;

                // Retrieve all group sids, primary group sid is one of them
                safeAllocHandle = GetTokenInformation(_safeTokenHandle, TokenInformationClass.TokenGroups);
                int    count             = Marshal.ReadInt32(safeAllocHandle.DangerousGetHandle());
                IntPtr pSidAndAttributes = new IntPtr((long)safeAllocHandle.DangerousGetHandle() + (long)Marshal.OffsetOf <Interop.TOKEN_GROUPS>("Groups"));
                Claim  claim;
                for (int i = 0; i < count; ++i)
                {
                    Interop.SID_AND_ATTRIBUTES group = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure <Interop.SID_AND_ATTRIBUTES>(pSidAndAttributes);
                    uint mask = Interop.SecurityGroups.SE_GROUP_ENABLED | Interop.SecurityGroups.SE_GROUP_LOGON_ID | Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY;
                    SecurityIdentifier groupSid = new SecurityIdentifier(group.Sid, true);

                    if ((group.Attributes & mask) == Interop.SecurityGroups.SE_GROUP_ENABLED)
                    {
                        if (!foundPrimaryGroupSid && StringComparer.Ordinal.Equals(groupSid.Value, primaryGroupSid.Value))
                        {
                            claim = new Claim(ClaimTypes.PrimaryGroupSid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                            claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                            instanceClaims.Add(claim);
                            foundPrimaryGroupSid = true;
                        }
                        //Primary group sid generates both regular groupsid claim and primary groupsid claim
                        claim = new Claim(ClaimTypes.GroupSid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                        claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                        instanceClaims.Add(claim);
                    }
                    else if ((group.Attributes & mask) == Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY)
                    {
                        if (!foundPrimaryGroupSid && StringComparer.Ordinal.Equals(groupSid.Value, primaryGroupSid.Value))
                        {
                            claim = new Claim(ClaimTypes.DenyOnlyPrimaryGroupSid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                            claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                            instanceClaims.Add(claim);
                            foundPrimaryGroupSid = true;
                        }
                        //Primary group sid generates both regular groupsid claim and primary groupsid claim
                        claim = new Claim(ClaimTypes.DenyOnlySid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                        claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                        instanceClaims.Add(claim);
                    }
                    pSidAndAttributes = new IntPtr((long)pSidAndAttributes + Marshal.SizeOf <Interop.SID_AND_ATTRIBUTES>());
                }
            }
            finally
            {
                safeAllocHandle.Dispose();
                safeAllocHandlePrimaryGroup.Dispose();
            }
        }
Exemple #21
0
        private unsafe void RemoveCounterSignature(int parentIndex, int childIndex)
        {
            // Just make sure this is non-negative.
            if (parentIndex < 0)
            {
                throw new ArgumentOutOfRangeException("parentIndex");
            }
            if (childIndex < 0)
            {
                throw new ArgumentOutOfRangeException("childIndex");
            }

            uint cbCmsgCmsSignerInfo = 0;
            SafeLocalAllocHandle pbCmsgCmsSignerInfo = SafeLocalAllocHandle.InvalidHandle;

            uint cbCmsgSignerInfo = 0;
            SafeLocalAllocHandle pbCmsgSignerInfo = SafeLocalAllocHandle.InvalidHandle;

            uint               index = 0;
            uint               cAttr = 0;
            IntPtr             pAttr = IntPtr.Zero;
            SafeCryptMsgHandle hMsg  = m_signedCms.GetCryptMsgHandle();

            if (PkcsUtils.CmsSupported())
            {
                PkcsUtils.GetParam(hMsg,
                                   CAPI.CMSG_CMS_SIGNER_INFO_PARAM,
                                   (uint)parentIndex,
                                   out pbCmsgCmsSignerInfo,
                                   out cbCmsgCmsSignerInfo);

                CAPI.CMSG_CMS_SIGNER_INFO cmsgCmsSignerInfo = (CAPI.CMSG_CMS_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgCmsSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_CMS_SIGNER_INFO));
                cAttr = cmsgCmsSignerInfo.UnauthAttrs.cAttr;
                pAttr = new IntPtr((long)cmsgCmsSignerInfo.UnauthAttrs.rgAttr);
            }
            else
            {
                PkcsUtils.GetParam(hMsg,
                                   CAPI.CMSG_SIGNER_INFO_PARAM,
                                   (uint)parentIndex,
                                   out pbCmsgSignerInfo,
                                   out cbCmsgSignerInfo);

                CAPI.CMSG_SIGNER_INFO cmsgSignerInfo = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO));
                cAttr = cmsgSignerInfo.UnauthAttrs.cAttr;
                pAttr = new IntPtr((long)cmsgSignerInfo.UnauthAttrs.rgAttr);
            }

            // Find index for counter signature attribute.
            // Note: It is not guaranteed that CAPI will keep all counter signatures
            // in one single unauthenticated attribute. So we need to find the correct
            // unauthenticated attribute containing this counter signer which is
            // identified by index.
            for (index = 0; index < cAttr; index++)
            {
                checked {
                    CAPI.CRYPT_ATTRIBUTE attr = (CAPI.CRYPT_ATTRIBUTE)Marshal.PtrToStructure(pAttr, typeof(CAPI.CRYPT_ATTRIBUTE));
                    if (String.Compare(attr.pszObjId, CAPI.szOID_RSA_counterSign, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        if (attr.cValue > 0)
                        {
                            // Is it in this attribute?
                            if (childIndex < (int)attr.cValue)
                            {
                                // Found the desired counter signature attribute. So, first remove the
                                // entire attribute, then remove just the counter signature from the
                                // retrieved attribute, and finally add back the modified attribute,
                                // if necessary.
                                CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA delPara = new CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA)));
                                delPara.dwSignerIndex     = (uint)parentIndex;
                                delPara.dwUnauthAttrIndex = index;

                                if (!CAPI.CryptMsgControl(hMsg,
                                                          0,
                                                          CAPI.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR,
                                                          new IntPtr(&delPara)))
                                {
                                    throw new CryptographicException(Marshal.GetLastWin32Error());
                                }

                                // No need to add back if only one counter signature in this attribute.
                                if (attr.cValue > 1)
                                {
                                    try {
                                        // There were more than one counter signatures in this attribute, so
                                        // need to add back a new counter signature attribute which includes
                                        // the remaining counter signatures.
                                        uint cbCounterSignatureValue = (uint)((attr.cValue - 1) * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)));
                                        SafeLocalAllocHandle pbCounterSignatureValue = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbCounterSignatureValue));

                                        // Copy everything except the one being removed.
                                        CAPI.CRYPTOAPI_BLOB *pOldValue = (CAPI.CRYPTOAPI_BLOB *)attr.rgValue;
                                        CAPI.CRYPTOAPI_BLOB *pNewValue = (CAPI.CRYPTOAPI_BLOB *)pbCounterSignatureValue.DangerousGetHandle();

                                        for (int i = 0; i < (int)attr.cValue; i++, pOldValue++, pNewValue++)
                                        {
                                            if (i != childIndex)
                                            {
                                                *pNewValue = *pOldValue;
                                            }
                                        }

                                        // Encode the new counter signature attribute.
                                        byte[] encodedNewAttribute;
                                        CAPI.CRYPT_ATTRIBUTE newAttr = new CAPI.CRYPT_ATTRIBUTE();
                                        newAttr.pszObjId = attr.pszObjId;
                                        newAttr.cValue   = attr.cValue - 1;
                                        newAttr.rgValue  = pbCounterSignatureValue.DangerousGetHandle();

                                        SafeLocalAllocHandle pNewAttr = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ATTRIBUTE))));
                                        Marshal.StructureToPtr(newAttr, pNewAttr.DangerousGetHandle(), false);

                                        try {
                                            if (!CAPI.EncodeObject(new IntPtr(CAPI.PKCS_ATTRIBUTE),
                                                                   pNewAttr.DangerousGetHandle(),
                                                                   out encodedNewAttribute))
                                            {
                                                throw new CryptographicException(Marshal.GetLastWin32Error());
                                            }
                                        }
                                        finally {
                                            Marshal.DestroyStructure(pNewAttr.DangerousGetHandle(), typeof(CAPI.CRYPT_ATTRIBUTE));
                                            pNewAttr.Dispose();
                                        }

                                        // Finally, add it back.
                                        fixed(byte *pbData = &encodedNewAttribute[0])
                                        {
                                            CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA addPara = new CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA)));
                                            addPara.dwSignerIndex = (uint)parentIndex;
                                            addPara.blob.cbData   = (uint)encodedNewAttribute.Length;
                                            addPara.blob.pbData   = new IntPtr(pbData);

                                            if (!CAPI.CryptMsgControl(hMsg,
                                                                      0,
                                                                      CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR,
                                                                      new IntPtr(&addPara)))
                                            {
                                                throw new CryptographicException(Marshal.GetLastWin32Error());
                                            }
                                        }

                                        // Keep alive.
                                        pbCounterSignatureValue.Dispose();
                                    }
                                    catch (CryptographicException) {
                                        // Roll back.
                                        byte[] encodedAttribute;
                                        if (CAPI.EncodeObject(new IntPtr(CAPI.PKCS_ATTRIBUTE),
                                                              pAttr,
                                                              out encodedAttribute))
                                        {
                                            fixed(byte *pbData = &encodedAttribute[0])
                                            {
                                                CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA addPara = new CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA)));
                                                addPara.dwSignerIndex = (uint)parentIndex;
                                                addPara.blob.cbData   = (uint)encodedAttribute.Length;
                                                addPara.blob.pbData   = new IntPtr(pbData);
                                                CAPI.CryptMsgControl(hMsg, 0, CAPI.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR, new IntPtr(&addPara));
                                            }
                                        }
                                        throw;
                                    }
                                }

                                return;
                            }

                            childIndex -= (int)attr.cValue;
                        }
                    }

                    pAttr = new IntPtr((long)pAttr + (long)Marshal.SizeOf(typeof(CAPI.CRYPT_ATTRIBUTE)));
                }
            }

            // Keep alive.
            if (pbCmsgCmsSignerInfo != null && !pbCmsgCmsSignerInfo.IsInvalid)
            {
                pbCmsgCmsSignerInfo.Dispose();
            }
            if (pbCmsgSignerInfo != null && !pbCmsgSignerInfo.IsInvalid)
            {
                pbCmsgSignerInfo.Dispose();
            }

            throw new CryptographicException(CAPI.CRYPT_E_NO_SIGNER);
        }
Exemple #22
0
        private void GetPerAdapterInfo(uint index)
        {
            if (index != 0)
            {
                uint size = 0;
                SafeLocalAllocHandle buffer = null;

                uint result = Interop.IpHlpApi.GetPerAdapterInfo(index, SafeLocalAllocHandle.Zero, ref size);
                while (result == Interop.IpHlpApi.ERROR_BUFFER_OVERFLOW)
                {
                    // Now we allocate the buffer and read the network parameters.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetPerAdapterInfo(index, buffer, ref size);
                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            Interop.IpHlpApi.IpPerAdapterInfo ipPerAdapterInfo =
                                Marshal.PtrToStructure <Interop.IpHlpApi.IpPerAdapterInfo>(buffer.DangerousGetHandle());

                            _autoConfigEnabled = ipPerAdapterInfo.autoconfigEnabled;
                            _autoConfigActive  = ipPerAdapterInfo.autoconfigActive;
                        }
                    }
                }

                if (result != Interop.IpHlpApi.ERROR_SUCCESS)
                {
                    throw new NetworkInformationException((int)result);
                }
            }
        }
Exemple #23
0
        private PingReply InternalSend(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool async)
        {
            _ipv6     = (address.AddressFamily == AddressFamily.InterNetworkV6) ? true : false;
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;

            try
            {
                if (async)
                {
                    if (pingEvent == null)
                    {
                        pingEvent = new ManualResetEvent(false);
                    }
                    else
                    {
                        pingEvent.Reset();
                    }

                    _registeredWait = ThreadPool.RegisterWaitForSingleObject(pingEvent, new WaitOrTimerCallback(PingCallback), this, -1, true);
                }

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (async && error == Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Expected async return value.
                    return(null);
                }

                // Cleanup.
                FreeUnmanagedStructures();
                UnregisterWaitHandle();

                if (async || // No IPStatus async errors.
                    error < (int)IPStatus.DestinationNetworkUnreachable || // Min
                    error > (int)IPStatus.DestinationScopeMismatch)    // Max or Out of IPStatus range.
                {
                    throw new Win32Exception(error);
                }

                return(new PingReply((IPStatus)error)); // Synchronous IPStatus errors.
            }

            if (async)
            {
                return(null);
            }

            FreeUnmanagedStructures();

            PingReply reply;

            if (_ipv6)
            {
                Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure <Interop.IpHlpApi.Icmp6EchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmp6Reply, _replyBuffer.DangerousGetHandle(), _sendSize);
            }
            else
            {
                Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure <Interop.IpHlpApi.IcmpEchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmpReply);
            }

            // IcmpEchoReply still has an unsafe IntPtr reference into replybuffer
            // and replybuffer was being freed prematurely by the GC, causing AccessViolationExceptions.
            GC.KeepAlive(_replyBuffer);

            return(reply);
        }
        private void WriteCore(byte[] buffer, int offset, int size)
        {
            Interop.HttpApi.HTTP_FLAGS flags = ComputeLeftToWrite();
            if (size == 0 && _leftToWrite != 0)
            {
                return;
            }
            if (_leftToWrite >= 0 && size > _leftToWrite)
            {
                throw new ProtocolViolationException(SR.net_entitytoobig);
            }

            uint statusCode;
            uint dataToWrite = (uint)size;
            SafeLocalAllocHandle bufferAsIntPtr = null;
            IntPtr pBufferAsIntPtr = IntPtr.Zero;
            bool   sentHeaders     = _httpContext.Response.SentHeaders;

            try
            {
                if (size == 0)
                {
                    statusCode = _httpContext.Response.SendHeaders(null, null, flags, false);
                }
                else
                {
                    fixed(byte *pDataBuffer = buffer)
                    {
                        byte *pBuffer = pDataBuffer;

                        if (_httpContext.Response.BoundaryType == BoundaryType.Chunked)
                        {
                            string chunkHeader = size.ToString("x", CultureInfo.InvariantCulture);
                            dataToWrite     = dataToWrite + (uint)(chunkHeader.Length + 4);
                            bufferAsIntPtr  = SafeLocalAllocHandle.LocalAlloc((int)dataToWrite);
                            pBufferAsIntPtr = bufferAsIntPtr.DangerousGetHandle();
                            for (int i = 0; i < chunkHeader.Length; i++)
                            {
                                Marshal.WriteByte(pBufferAsIntPtr, i, (byte)chunkHeader[i]);
                            }
                            Marshal.WriteInt16(pBufferAsIntPtr, chunkHeader.Length, 0x0A0D);
                            Marshal.Copy(buffer, offset, pBufferAsIntPtr + chunkHeader.Length + 2, size);
                            Marshal.WriteInt16(pBufferAsIntPtr, (int)(dataToWrite - 2), 0x0A0D);
                            pBuffer = (byte *)pBufferAsIntPtr;
                            offset  = 0;
                        }
                        Interop.HttpApi.HTTP_DATA_CHUNK dataChunk = default;
                        dataChunk.DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                        dataChunk.pBuffer       = (byte *)(pBuffer + offset);
                        dataChunk.BufferLength  = dataToWrite;

                        flags |= _leftToWrite == size ? Interop.HttpApi.HTTP_FLAGS.NONE : Interop.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
                        if (!sentHeaders)
                        {
                            statusCode = _httpContext.Response.SendHeaders(&dataChunk, null, flags, false);
                        }
                        else
                        {
                            if (NetEventSource.Log.IsEnabled())
                            {
                                NetEventSource.Info(this, "Calling Interop.HttpApi.HttpSendResponseEntityBody");
                            }

                            statusCode =
                                Interop.HttpApi.HttpSendResponseEntityBody(
                                    _httpContext.RequestQueueHandle,
                                    _httpContext.RequestId,
                                    (uint)flags,
                                    1,
                                    &dataChunk,
                                    null,
                                    SafeLocalAllocHandle.Zero,
                                    0,
                                    null,
                                    null);

                            if (NetEventSource.Log.IsEnabled())
                            {
                                NetEventSource.Info(this, "Call to Interop.HttpApi.HttpSendResponseEntityBody returned:" + statusCode);
                            }
                            if (_httpContext.Listener.IgnoreWriteExceptions)
                            {
                                if (NetEventSource.Log.IsEnabled())
                                {
                                    NetEventSource.Info(this, "Write() suppressing error");
                                }
                                statusCode = Interop.HttpApi.ERROR_SUCCESS;
                            }
                        }
                    }
                }
            }
            finally
            {
                // free unmanaged buffer
                bufferAsIntPtr?.Close();
            }

            if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_HANDLE_EOF)
            {
                Exception exception = new HttpListenerException((int)statusCode);
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Error(this, exception.ToString());
                }
                _closed = true;
                _httpContext.Abort();
                throw exception;
            }
            UpdateAfterWrite(dataToWrite);
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.DumpBuffer(this, buffer, offset, (int)dataToWrite);
            }
        }
Exemple #25
0
        internal AlgorithmIdentifier(CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier)
        {
            int  keyLength    = 0;
            uint cbParameters = 0;
            SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle;

            byte[] parameters = new byte[0];

            uint algId = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId);

            if (algId == CAPI.CALG_RC2)
            {
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_RC2_CBC_PARAMETERS),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    CAPI.CRYPT_RC2_CBC_PARAMETERS rc2Parameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS));
                    switch (rc2Parameters.dwVersion)
                    {
                    case CAPI.CRYPT_RC2_40BIT_VERSION:
                        keyLength = 40;
                        break;

                    case CAPI.CRYPT_RC2_56BIT_VERSION:
                        keyLength = 56;
                        break;

                    case CAPI.CRYPT_RC2_128BIT_VERSION:
                        keyLength = 128;
                        break;
                    }
                    // Retrieve IV if available.
                    if (rc2Parameters.fIV)
                    {
                        parameters = (byte[])rc2Parameters.rgbIV.Clone();
                    }
                }
            }
            else if (algId == CAPI.CALG_RC4 || algId == CAPI.CALG_DES || algId == CAPI.CALG_3DES)
            {
                // Retrieve the IV if available. For non RC2, the parameter contains the IV
                // (for RC4 the IV is really the salt). There are (128 - KeyLength) / 8
                // bytes of RC4 salt.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_OCTET_STRING),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    if (cbParameters > Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)))
                    {
                        CAPI.CRYPTOAPI_BLOB blob = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB));

                        if (algId == CAPI.CALG_RC4)
                        {
                            if (blob.cbData > 0)
                            {
                                parameters = new byte[blob.cbData];
                                Marshal.Copy(blob.pbData, parameters, 0, parameters.Length);
                            }
                        }
                        else
                        {
                            // This should be the same as the RC4 code, but for compatibility
                            // * Allocate an array as big as the CRYPTOAPI_BLOB
                            // * Copy in the cbData value
                            // * Copy in the (pbData) value
                            //
                            // But don't copy in the pbData pointer value (or, rather, clear it out),
                            // among other things it makes decoding the same contents into two
                            // different EnvelopedCms objects say the parameters were different.
                            parameters = new byte[cbParameters];
                            Marshal.Copy(pbParameters.DangerousGetHandle(), parameters, 0, parameters.Length);
                            Array.Clear(parameters, sizeof(uint), (int)(parameters.Length - blob.cbData - sizeof(uint)));
                        }
                    }
                }

                // Determine key length.
                if (algId == CAPI.CALG_RC4)
                {
                    // For RC4, keyLength = 128 - (salt length * 8).
                    keyLength = 128 - ((int)parameters.Length * 8);
                }
                else if (algId == CAPI.CALG_DES)
                {
                    // DES key length is fixed at 64 (or 56 without the parity bits).
                    keyLength = 64;
                }
                else
                {
                    // 3DES key length is fixed at 192 (or 168 without the parity bits).
                    keyLength = 192;
                }
            }
            else
            {
                // Everything else, don't decode it as CAPI may not expose or know how.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    parameters = new byte[algorithmIdentifier.Parameters.cbData];
                    Marshal.Copy(algorithmIdentifier.Parameters.pbData, parameters, 0, parameters.Length);
                }
            }

            Reset(Oid.FromOidValue(algorithmIdentifier.pszObjId, OidGroup.All), keyLength, parameters);
            pbParameters.Dispose();
        }
        internal AlgorithmIdentifier(CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier)
        {
            int  keyLength    = 0;
            uint cbParameters = 0;
            SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle;

            byte[] parameters = new byte[0];

            uint algId = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId);

            if (algId == CAPI.CALG_RC2)
            {
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_RC2_CBC_PARAMETERS),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    CAPI.CRYPT_RC2_CBC_PARAMETERS rc2Parameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS));
                    switch (rc2Parameters.dwVersion)
                    {
                    case CAPI.CRYPT_RC2_40BIT_VERSION:
                        keyLength = 40;
                        break;

                    case CAPI.CRYPT_RC2_56BIT_VERSION:
                        keyLength = 56;
                        break;

                    case CAPI.CRYPT_RC2_128BIT_VERSION:
                        keyLength = 128;
                        break;
                    }
                    // Retrieve IV if available.
                    if (rc2Parameters.fIV)
                    {
                        parameters = (byte[])rc2Parameters.rgbIV.Clone();
                    }
                }
            }
            else if (algId == CAPI.CALG_RC4 || algId == CAPI.CALG_DES || algId == CAPI.CALG_3DES)
            {
                // Retrieve the IV if available. For non RC2, the parameter contains the IV
                // (for RC4 the IV is really the salt). There are (128 - KeyLength) / 8
                // bytes of RC4 salt.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_OCTET_STRING),
                                           algorithmIdentifier.Parameters.pbData,
                                           algorithmIdentifier.Parameters.cbData,
                                           out pbParameters,
                                           out cbParameters))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    if (cbParameters > 0)
                    {
                        if (algId == CAPI.CALG_RC4)
                        {
                            CAPI.CRYPTOAPI_BLOB saltBlob = (CAPI.CRYPTOAPI_BLOB)Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB));
                            if (saltBlob.cbData > 0)
                            {
                                parameters = new byte[saltBlob.cbData];
                                Marshal.Copy(saltBlob.pbData, parameters, 0, parameters.Length);
                            }
                        }
                        else
                        {
                            parameters = new byte[cbParameters];
                            Marshal.Copy(pbParameters.DangerousGetHandle(), parameters, 0, parameters.Length);
                        }
                    }
                }

                // Determine key length.
                if (algId == CAPI.CALG_RC4)
                {
                    // For RC4, keyLength = 128 - (salt length * 8).
                    keyLength = 128 - ((int)parameters.Length * 8);
                }
                else if (algId == CAPI.CALG_DES)
                {
                    // DES key length is fixed at 64 (or 56 without the parity bits).
                    keyLength = 64;
                }
                else
                {
                    // 3DES key length is fixed at 192 (or 168 without the parity bits).
                    keyLength = 192;
                }
            }
            else
            {
                // Everything else, don't decode it as CAPI may not expose or know how.
                if (algorithmIdentifier.Parameters.cbData > 0)
                {
                    parameters = new byte[algorithmIdentifier.Parameters.cbData];
                    Marshal.Copy(algorithmIdentifier.Parameters.pbData, parameters, 0, parameters.Length);
                }
            }

            Reset(Oid.FromOidValue(algorithmIdentifier.pszObjId, OidGroup.All), keyLength, parameters);
            pbParameters.Dispose();
        }
Exemple #27
0
        private unsafe void Verify(X509Certificate2Collection extraStore, X509Certificate2 certificate, bool verifySignatureOnly)
        {
            checked {
                // We need to find out if DSS parameters inheritance is necessary. If so, we need to
                // first build the chain to cause CAPI to inherit and set the parameters in the
                // CERT_PUBKEY_ALG_PARA_PROP_ID extended property. Once we have the parameters in
                // the property, we then need to retrieve a copy and point to it in the CERT_INFO
                // structure.
                SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle;
                CAPI.CERT_CONTEXT    pCertContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));

                // Point to SubjectPublicKeyInfo field inside the CERT_INFO structure.
                IntPtr pSubjectPublicKeyInfo = new IntPtr((long)pCertContext.pCertInfo + (long)Marshal.OffsetOf(typeof(CAPI.CERT_INFO), "SubjectPublicKeyInfo"));

                // Point to Algorithm field inside the SubjectPublicKeyInfo field.
                IntPtr pAlgorithm = new IntPtr((long)pSubjectPublicKeyInfo + (long)Marshal.OffsetOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO), "Algorithm"));

                // Point to Parameters field inside the Algorithm field.
                IntPtr pParameters = new IntPtr((long)pAlgorithm + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));

                // Retrieve the pszObjId pointer.
                IntPtr pObjId = Marshal.ReadIntPtr(pAlgorithm);

                // Translate the OID to AlgId value.
                CAPI.CRYPT_OID_INFO pOIDInfo = CAPI.CryptFindOIDInfo(CAPI.CRYPT_OID_INFO_OID_KEY, pObjId, CAPI.CRYPT_PUBKEY_ALG_OID_GROUP_ID);

                // Is this DSS?
                if (pOIDInfo.Algid == CAPI.CALG_DSS_SIGN)
                {
                    bool inheritParameters = false;

                    // This is DSS, so inherit the parameters if necessary.
                    IntPtr pcbData = new IntPtr((long)pParameters + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                    IntPtr ppbData = new IntPtr((long)pParameters + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                    if (Marshal.ReadInt32(pcbData) == 0)
                    {
                        inheritParameters = true;
                    }
                    else
                    {
                        // Need to inherit if NULL pbData or *pbData is 0x05 (NULL ASN tag).
                        if (Marshal.ReadIntPtr(ppbData) == IntPtr.Zero)
                        {
                            inheritParameters = true;
                        }
                        else
                        {
                            IntPtr pbData = Marshal.ReadIntPtr(ppbData);
                            if ((uint)Marshal.ReadInt32(pbData) == CAPI.ASN_TAG_NULL)
                            {
                                inheritParameters = true;
                            }
                        }
                    }

                    // Do we need to copy inherited DSS parameters?
                    if (inheritParameters)
                    {
                        // Build the chain to force CAPI to propagate the parameters to
                        // CERT_PUBKEY_ALG_PARA_PROP_ID extended property.
                        SafeCertChainHandle pChainContext = SafeCertChainHandle.InvalidHandle;
                        X509Utils.BuildChain(new IntPtr(CAPI.HCCE_CURRENT_USER),
                                             X509Utils.GetCertContext(certificate),
                                             null,
                                             null,
                                             null,
                                             X509RevocationMode.NoCheck,
                                             X509RevocationFlag.ExcludeRoot,
                                             DateTime.Now,
                                             new TimeSpan(0, 0, 0), // default
                                             ref pChainContext);
                        pChainContext.Dispose();

                        // The parameter is inherited in the extended property, but not copied
                        // to CERT_INFO, so we need to do it ourselves.
                        uint cbParameters = 0;

                        if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                             CAPI.CERT_PUBKEY_ALG_PARA_PROP_ID,
                                                                             pbParameters,
                                                                             ref cbParameters))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }

                        if (cbParameters > 0)
                        {
                            pbParameters = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbParameters));
                            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                                 CAPI.CERT_PUBKEY_ALG_PARA_PROP_ID,
                                                                                 pbParameters,
                                                                                 ref cbParameters))
                            {
                                throw new CryptographicException(Marshal.GetLastWin32Error());
                            }

                            Marshal.WriteInt32(pcbData, (int)cbParameters);
                            Marshal.WriteIntPtr(ppbData, pbParameters.DangerousGetHandle());
                        }
                    }
                }

                // Is this counter signer?
                if (m_parentSignerInfo == null)
                {
                    // Just plain signer.
                    if (!CAPI.CryptMsgControl(m_signedCms.GetCryptMsgHandle(),
                                              0,
                                              CAPI.CMSG_CTRL_VERIFY_SIGNATURE,
                                              pCertContext.pCertInfo))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    // Counter signer, so need to first find parent signer's index.
                    int index          = -1;
                    int lastWin32Error = 0;

                    // Since we allow the same signer to sign more than once,
                    // we must than try all signatures of the same signer.
                    while (true)
                    {
                        try {
                            // Find index of parent signer.
                            index = PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), m_parentSignerInfo, index + 1);
                        }
                        catch (CryptographicException) {
                            // Did we ever find a signature of the same signer?
                            if (lastWin32Error == 0)
                            {
                                // No. So we just re-throw, which is most likely CAPI.CRYPT_E_SIGNER_NOT_FOUND.
                                throw;
                            }
                            else
                            {
                                // Yes. Throw previous error, which is most likely CAPI.NTE_BAD_SIGNATURE.
                                throw new CryptographicException(lastWin32Error);
                            }
                        }

                        // Now get the parent encoded singer info.
                        uint cbParentEncodedSignerInfo = 0;
                        SafeLocalAllocHandle pbParentEncodedSignerInfo = SafeLocalAllocHandle.InvalidHandle;

                        PkcsUtils.GetParam(m_signedCms.GetCryptMsgHandle(),
                                           CAPI.CMSG_ENCODED_SIGNER,
                                           (uint)index,
                                           out pbParentEncodedSignerInfo,
                                           out cbParentEncodedSignerInfo);

                        // Try next signer if we can't get parent of this signer.
                        if (cbParentEncodedSignerInfo == 0)
                        {
                            lastWin32Error = CAPI.CRYPT_E_NO_SIGNER;
                            continue;
                        }

                        fixed(byte *pbEncodedSignerInfo = m_encodedSignerInfo)
                        {
                            if (!CAPI.CAPISafe.CryptMsgVerifyCountersignatureEncoded(IntPtr.Zero,
                                                                                     CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                                     pbParentEncodedSignerInfo.DangerousGetHandle(),
                                                                                     cbParentEncodedSignerInfo,
                                                                                     new IntPtr(pbEncodedSignerInfo),
                                                                                     (uint)m_encodedSignerInfo.Length,
                                                                                     pCertContext.pCertInfo))
                            {
                                // Cache the error, and try next signer.
                                lastWin32Error = Marshal.GetLastWin32Error();
                                continue;
                            }
                        }

                        // Keep alive.
                        pbParentEncodedSignerInfo.Dispose();

                        // The signature is successfully verified.
                        break;
                    }
                }

                // Verfiy the cert if requested.
                if (!verifySignatureOnly)
                {
                    int hr = VerifyCertificate(certificate, extraStore);
                    if (hr != CAPI.S_OK)
                    {
                        throw new CryptographicException(hr);
                    }
                }

                // Keep alive.
                pbParameters.Dispose();
            }
        }
Exemple #28
0
        public static Interop.IpHlpApi.FIXED_INFO GetFixedInfo()
        {
            uint size = 0;
            SafeLocalAllocHandle buffer = null;

            Interop.IpHlpApi.FIXED_INFO fixedInfo = new Interop.IpHlpApi.FIXED_INFO();

            // First we need to get the size of the buffer
            uint result = Interop.IpHlpApi.GetNetworkParams(SafeLocalAllocHandle.InvalidHandle, ref size);

            while (result == Interop.IpHlpApi.ERROR_BUFFER_OVERFLOW)
            {
                // Now we allocate the buffer and read the network parameters.
                using (buffer = Interop.mincore_obsolete.LocalAlloc(0, (UIntPtr)size))
                {
                    if (buffer.IsInvalid)
                    {
                        throw new OutOfMemoryException();
                    }

                    result = Interop.IpHlpApi.GetNetworkParams(buffer, ref size);
                    if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                    {
                        fixedInfo = Marshal.PtrToStructure <Interop.IpHlpApi.FIXED_INFO>(buffer.DangerousGetHandle());
                    }
                }
            }

            // If the result include there being no information, we'll still throw
            if (result != Interop.IpHlpApi.ERROR_SUCCESS)
            {
                throw new Win32Exception((int)result);
            }

            return(fixedInfo);
        }
Exemple #29
0
        ///
        /// Gets the active TCP connections. Uses the native GetTcpTable API.
        private List <SystemTcpConnectionInformation> GetAllTcpConnections()
        {
            uint size   = 0;
            uint result = 0;
            SafeLocalAllocHandle buffer = null;
            List <SystemTcpConnectionInformation> tcpConnections = new List <SystemTcpConnectionInformation>();

            // Check if it supports IPv4 for IPv6 only modes.
            if (Socket.OSSupportsIPv4)
            {
                // Get the buffer size needed.
                result = Interop.IpHlpApi.GetTcpTable(SafeLocalAllocHandle.Zero, ref size, true);

                while (result == Interop.IpHlpApi.ERROR_INSUFFICIENT_BUFFER)
                {
                    // Allocate the buffer and get the TCP table.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetTcpTable(buffer, ref size, true);

                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();
                            Interop.IpHlpApi.MibTcpTable tcpTableInfo = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcpTable>(newPtr);

                            if (tcpTableInfo.numberOfEntries > 0)
                            {
                                // Skip over the tableinfo to get the inline rows.
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpTableInfo.numberOfEntries));

                                for (int i = 0; i < tcpTableInfo.numberOfEntries; i++)
                                {
                                    Interop.IpHlpApi.MibTcpRow tcpRow = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcpRow>(newPtr);
                                    tcpConnections.Add(new SystemTcpConnectionInformation(tcpRow));

                                    // Increment the pointer to the next row.
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpRow));
                                }
                            }
                        }
                    }
                }

                // If we don't have any ipv4 interfaces detected, just continue.
                if (result != Interop.IpHlpApi.ERROR_SUCCESS && result != Interop.IpHlpApi.ERROR_NO_DATA)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            if (Socket.OSSupportsIPv6)
            {
                // Get the buffer size needed.
                size   = 0;
                result = Interop.IpHlpApi.GetExtendedTcpTable(SafeLocalAllocHandle.Zero, ref size, true,
                                                              (uint)AddressFamily.InterNetworkV6,
                                                              Interop.IpHlpApi.TcpTableClass.TcpTableOwnerPidAll, 0);

                while (result == Interop.IpHlpApi.ERROR_INSUFFICIENT_BUFFER)
                {
                    // Allocate the buffer and get the TCP table.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetExtendedTcpTable(buffer, ref size, true,
                                                                      (uint)AddressFamily.InterNetworkV6,
                                                                      Interop.IpHlpApi.TcpTableClass.TcpTableOwnerPidAll, 0);
                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();

                            Interop.IpHlpApi.MibTcp6TableOwnerPid tcpTable6OwnerPid = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcp6TableOwnerPid>(newPtr);

                            if (tcpTable6OwnerPid.numberOfEntries > 0)
                            {
                                // Skip over the tableinfo to get the inline rows.
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpTable6OwnerPid.numberOfEntries));

                                for (int i = 0; i < tcpTable6OwnerPid.numberOfEntries; i++)
                                {
                                    Interop.IpHlpApi.MibTcp6RowOwnerPid tcp6RowOwnerPid = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcp6RowOwnerPid>(newPtr);
                                    tcpConnections.Add(new SystemTcpConnectionInformation(tcp6RowOwnerPid));

                                    // We increment the pointer to the next row.
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcp6RowOwnerPid));
                                }
                            }
                        }
                    }
                }

                // If we don't have any ipv6 interfaces detected, just continue.
                if (result != Interop.IpHlpApi.ERROR_SUCCESS && result != Interop.IpHlpApi.ERROR_NO_DATA)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            return(tcpConnections);
        }
Exemple #30
0
        private unsafe void Sign(CmsSigner signer, bool silent)
        {
            SafeCryptMsgHandle safeCryptMsgHandle = null;

            CAPI.CMSG_SIGNED_ENCODE_INFO signedEncodeInfo = new CAPI.CMSG_SIGNED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNED_ENCODE_INFO)));
            SafeCryptProvHandle          safeCryptProvHandle;

            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent, out safeCryptProvHandle);

            byte[] encodedMessage = null;
            try {
                SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

                try {
                    Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false);
                    X509Certificate2Collection bagOfCerts         = PkcsUtils.CreateBagOfCertificates(signer);
                    SafeLocalAllocHandle       pEncodedBagOfCerts = PkcsUtils.CreateEncodedCertBlob(bagOfCerts);

                    signedEncodeInfo.cSigners     = 1;
                    signedEncodeInfo.rgSigners    = pSignerEncodeInfo.DangerousGetHandle();
                    signedEncodeInfo.cCertEncoded = (uint)bagOfCerts.Count;
                    if (bagOfCerts.Count > 0)
                    {
                        signedEncodeInfo.rgCertEncoded = pEncodedBagOfCerts.DangerousGetHandle();
                    }

                    // Because of the way CAPI treats inner content OID, we should pass NULL
                    // for data type, otherwise detached will not work.
                    if (String.Compare(this.ContentInfo.ContentType.Value, CAPI.szOID_RSA_data, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       Detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                                                                       CAPI.CMSG_SIGNED,
                                                                       new IntPtr(&signedEncodeInfo),
                                                                       IntPtr.Zero,
                                                                       IntPtr.Zero);
                    }
                    else
                    {
                        safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       Detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                                                                       CAPI.CMSG_SIGNED,
                                                                       new IntPtr(&signedEncodeInfo),
                                                                       this.ContentInfo.ContentType.Value,
                                                                       IntPtr.Zero);
                    }

                    if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }


                    if (this.ContentInfo.Content.Length > 0)
                    {
                        if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, this.ContentInfo.pContent, (uint)this.ContentInfo.Content.Length, true))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                    }

                    // Retrieve encoded message.
                    encodedMessage = PkcsUtils.GetContent(safeCryptMsgHandle);
                    safeCryptMsgHandle.Dispose();

                    pEncodedBagOfCerts.Dispose();
                }
                finally {
                    Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                    pSignerEncodeInfo.Dispose();
                }
            }
            finally {
                // Don't forget to free all the resource still held inside signerEncodeInfo.
                signerEncodeInfo.Dispose();
                safeCryptProvHandle.Dispose();
            }

            // Re-open to decode.
            safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
            if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid)
            {
                m_safeCryptMsgHandle.Dispose();
            }
            m_safeCryptMsgHandle = safeCryptMsgHandle;
            GC.KeepAlive(signer);
        }
Exemple #31
0
        /// Gets the active UDP listeners. Uses the native GetUdpTable API.
        public override IPEndPoint[] GetActiveUdpListeners()
        {
            uint size   = 0;
            uint result = 0;
            SafeLocalAllocHandle buffer       = null;
            List <IPEndPoint>    udpListeners = new List <IPEndPoint>();

            // Check if it support IPv4 for IPv6 only modes.
            if (Socket.OSSupportsIPv4)
            {
                // Get the buffer size needed.
                result = Interop.IpHlpApi.GetUdpTable(SafeLocalAllocHandle.Zero, ref size, true);
                while (result == Interop.IpHlpApi.ERROR_INSUFFICIENT_BUFFER)
                {
                    // Allocate the buffer and get the UDP table.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetUdpTable(buffer, ref size, true);

                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();
                            Interop.IpHlpApi.MibUdpTable udpTableInfo = Marshal.PtrToStructure <Interop.IpHlpApi.MibUdpTable>(newPtr);

                            if (udpTableInfo.numberOfEntries > 0)
                            {
                                // Skip over the tableinfo to get the inline rows.
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udpTableInfo.numberOfEntries));
                                for (int i = 0; i < udpTableInfo.numberOfEntries; i++)
                                {
                                    Interop.IpHlpApi.MibUdpRow udpRow = Marshal.PtrToStructure <Interop.IpHlpApi.MibUdpRow>(newPtr);
                                    int localPort = udpRow.localPort1 << 8 | udpRow.localPort2;

                                    udpListeners.Add(new IPEndPoint(udpRow.localAddr, (int)localPort));

                                    // We increment the pointer to the next row.
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udpRow));
                                }
                            }
                        }
                    }
                }

                // If we don't have any ipv4 interfaces detected, just continue.
                if (result != Interop.IpHlpApi.ERROR_SUCCESS && result != Interop.IpHlpApi.ERROR_NO_DATA)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            if (Socket.OSSupportsIPv6)
            {
                // Get the buffer size needed.
                size   = 0;
                result = Interop.IpHlpApi.GetExtendedUdpTable(SafeLocalAllocHandle.Zero, ref size, true,
                                                              (uint)AddressFamily.InterNetworkV6,
                                                              Interop.IpHlpApi.UdpTableClass.UdpTableOwnerPid, 0);
                while (result == Interop.IpHlpApi.ERROR_INSUFFICIENT_BUFFER)
                {
                    // Allocate the buffer and get the UDP table.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetExtendedUdpTable(buffer, ref size, true,
                                                                      (uint)AddressFamily.InterNetworkV6,
                                                                      Interop.IpHlpApi.UdpTableClass.UdpTableOwnerPid, 0);

                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();
                            Interop.IpHlpApi.MibUdp6TableOwnerPid udp6TableOwnerPid = Marshal.PtrToStructure <Interop.IpHlpApi.MibUdp6TableOwnerPid>(newPtr);

                            if (udp6TableOwnerPid.numberOfEntries > 0)
                            {
                                // Skip over the tableinfo to get the inline rows.
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udp6TableOwnerPid.numberOfEntries));
                                for (int i = 0; i < udp6TableOwnerPid.numberOfEntries; i++)
                                {
                                    Interop.IpHlpApi.MibUdp6RowOwnerPid udp6RowOwnerPid = Marshal.PtrToStructure <Interop.IpHlpApi.MibUdp6RowOwnerPid>(newPtr);
                                    int localPort = udp6RowOwnerPid.localPort1 << 8 | udp6RowOwnerPid.localPort2;

                                    udpListeners.Add(new IPEndPoint(new IPAddress(udp6RowOwnerPid.localAddr,
                                                                                  udp6RowOwnerPid.localScopeId), localPort));

                                    // We increment the pointer to the next row.
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udp6RowOwnerPid));
                                }
                            }
                        }
                    }
                }
                // If we don't have any ipv6 interfaces detected, just continue.
                if (result != Interop.IpHlpApi.ERROR_SUCCESS && result != Interop.IpHlpApi.ERROR_NO_DATA)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            return(udpListeners.ToArray());
        }