Exemple #1
0
        private static IntPtr GetSubjectInfoPointer(string path)
        {
            // target file info
            var signerFileInfo = new SIGNER_FILE_INFO
            {
                pwszFileName = Marshal.StringToHGlobalUni(path),
                cbSize       = (uint)Marshal.SizeOf <SIGNER_FILE_INFO>(),
                hFile        = IntPtr.Zero
            };

            // subject info
            var signerSubjectInfo = new SIGNER_SUBJECT_INFO
            {
                cbSize          = (uint)Marshal.SizeOf <SIGNER_SUBJECT_INFO>(),
                pdwIndex        = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint))),
                dwSubjectChoice = Constants.SIGNER_SUBJECT_FILE,
                SubjectChoice   = new SIGNER_SUBJECT_INFO.SubjectChoiceUnion
                {
                    pSignerFileInfo = Marshal.AllocHGlobal(Marshal.SizeOf <SIGNER_FILE_INFO>())
                }
            };

            Marshal.StructureToPtr(Constants.DONT_CARE, signerSubjectInfo.pdwIndex, false);
            Marshal.StructureToPtr(signerFileInfo, signerSubjectInfo.SubjectChoice.pSignerFileInfo, false);

            var subjectHandle = Marshal.AllocHGlobal(Marshal.SizeOf <SIGNER_SUBJECT_INFO>());

            Marshal.StructureToPtr(signerSubjectInfo, subjectHandle, false);
            return(subjectHandle);
        }
        private static IntPtr CreateSignerSubjectInfo(string pathToAssembly)
        {
            SIGNER_SUBJECT_INFO info = new SIGNER_SUBJECT_INFO
            {
                cbSize   = (uint)Marshal.SizeOf(typeof(SIGNER_SUBJECT_INFO)),
                pdwIndex = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint)))
            };
            var index = 0;

            Marshal.StructureToPtr(index, info.pdwIndex, false);

            info.dwSubjectChoice = 0x1;     //SIGNER_SUBJECT_FILE
            IntPtr assemblyFilePtr = Marshal.StringToHGlobalUni(pathToAssembly);

            SIGNER_FILE_INFO fileInfo = new SIGNER_FILE_INFO
            {
                cbSize       = (uint)Marshal.SizeOf(typeof(SIGNER_FILE_INFO)),
                pwszFileName = assemblyFilePtr,
                hFile        = IntPtr.Zero
            };

            info.Union1 = new SIGNER_SUBJECT_INFO.SubjectChoiceUnion
            {
                pSignerFileInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SIGNER_FILE_INFO)))
            };

            Marshal.StructureToPtr(fileInfo, info.Union1.pSignerFileInfo, false);

            IntPtr pSubjectInfo = Marshal.AllocHGlobal(Marshal.SizeOf(info));

            Marshal.StructureToPtr(info, pSubjectInfo, false);

            return(pSubjectInfo);
        }
Exemple #3
0
        /// <summary>Authenticode signs a file.</summary>
        /// <param name="pageHashing">True if the signing process should try to include page hashing, otherwise false.
        /// Use <c>null</c> to use the operating system default. Note that page hashing still may be disabled if the
        /// Subject Interface Package does not support page hashing.</param>
        /// <param name="descriptionUrl">A URL describing the signature or the signer.</param>
        /// <param name="description">The description to apply to the signature.</param>
        /// <param name="path">The path to the file to signed.</param>
        /// <param name="logger">An optional logger to capture signing operations.</param>
        /// <returns>A HRESULT indicating the result of the signing operation. S_OK, or zero, is returned if the signing
        /// operation completed successfully.</returns>
        public unsafe int SignFile(ReadOnlySpan <char> path, ReadOnlySpan <char> description, ReadOnlySpan <char> descriptionUrl, bool?pageHashing, ILogger logger = null)
        {
            void CopyAndNullTerminate(ReadOnlySpan <char> str, Span <char> destination)
            {
                str.CopyTo(destination);
                destination[destination.Length - 1] = '\0';
            }

            var flags = SignerSignEx3Flags.SIGN_CALLBACK_UNDOCUMENTED;

            if (pageHashing == true)
            {
                flags |= SignerSignEx3Flags.SPC_INC_PE_PAGE_HASHES_FLAG;
            }
            else if (pageHashing == false)
            {
                flags |= SignerSignEx3Flags.SPC_EXC_PE_PAGE_HASHES_FLAG;
            }

            SignerSignTimeStampFlags timeStampFlags;
            ReadOnlySpan <byte>      timestampAlgorithmOid;
            string timestampUrl;

            switch (_timeStampConfiguration.Type)
            {
            case TimeStampType.Authenticode:
                timeStampFlags        = SignerSignTimeStampFlags.SIGNER_TIMESTAMP_AUTHENTICODE;
                timestampAlgorithmOid = default;
                timestampUrl          = _timeStampConfiguration.Url;
                break;

            case TimeStampType.RFC3161:
                timeStampFlags        = SignerSignTimeStampFlags.SIGNER_TIMESTAMP_RFC3161;
                timestampAlgorithmOid = AlgorithmTranslator.HashAlgorithmToOidAsciiTerminated(_timeStampConfiguration.DigestAlgorithm);
                timestampUrl          = _timeStampConfiguration.Url;
                break;

            default:
                timeStampFlags        = 0;
                timestampAlgorithmOid = default;
                timestampUrl          = null;
                break;
            }

            Span <char> pathWithNull         = path.Length > 0x100 ? new char[path.Length + 1] : stackalloc char[path.Length + 1];
            Span <char> descriptionBuffer    = description.Length > 0x100 ? new char[description.Length + 1] : stackalloc char[description.Length + 1];
            Span <char> descriptionUrlBuffer = descriptionUrl.Length > 0x100 ? new char[descriptionUrl.Length + 1] : stackalloc char[descriptionUrl.Length + 1];

            Span <char> timestampUrlBuffer = timestampUrl == null ?
                                         default : timestampUrl.Length > 0x100 ?
                                             new char[timestampUrl.Length + 1] : stackalloc char[timestampUrl.Length + 1];

                                             CopyAndNullTerminate(path, pathWithNull);
                                             CopyAndNullTerminate(description, descriptionBuffer);
                                             CopyAndNullTerminate(descriptionUrl, descriptionUrlBuffer);
                                             if (timestampUrl != null)
                                             {
                                                 CopyAndNullTerminate(timestampUrl, timestampUrlBuffer);
                                             }

                                             fixed(byte *pTimestampAlgorithm = timestampAlgorithmOid)
                                             fixed(char *pTimestampUrl   = timestampUrlBuffer)
                                             fixed(char *pPath           = pathWithNull)
                                             fixed(char *pDescription    = descriptionBuffer)
                                             fixed(char *pDescriptionUrl = descriptionUrlBuffer)
                                             {
                                                 var fileInfo               = new SIGNER_FILE_INFO(pPath, default);
                                                 var subjectIndex           = 0u;
                                                 var signerSubjectInfoUnion = new SIGNER_SUBJECT_INFO_UNION(&fileInfo);
                                                 var subjectInfo            = new SIGNER_SUBJECT_INFO(&subjectIndex, SignerSubjectInfoUnionChoice.SIGNER_SUBJECT_FILE, signerSubjectInfoUnion);
                                                 var authCodeStructure      = new SIGNER_ATTR_AUTHCODE(pDescription, pDescriptionUrl);
                                                 var storeInfo              = new SIGNER_CERT_STORE_INFO(
                                                     dwCertPolicy: SignerCertStoreInfoFlags.SIGNER_CERT_POLICY_CHAIN,
                                                     hCertStore: _certificateStore.Handle,
                                                     pSigningCert: _signingCertificate.Handle
                                                     );
                                                 var signerCert = new SIGNER_CERT(
                                                     dwCertChoice: SignerCertChoice.SIGNER_CERT_STORE,
                                                     union: new SIGNER_CERT_UNION(&storeInfo)
                                                     );
                                                 var signatureInfo = new SIGNER_SIGNATURE_INFO(
                                                     algidHash: AlgorithmTranslator.HashAlgorithmToAlgId(_fileDigestAlgorithm),
                                                     psAuthenticated: IntPtr.Zero,
                                                     psUnauthenticated: IntPtr.Zero,
                                                     dwAttrChoice: SignerSignatureInfoAttrChoice.SIGNER_AUTHCODE_ATTR,
                                                     attrAuthUnion: new SIGNER_SIGNATURE_INFO_UNION(&authCodeStructure)
                                                     );
                                                 var callbackPtr      = Marshal.GetFunctionPointerForDelegate(_signCallback);
                                                 var signCallbackInfo = new SIGN_INFO(callbackPtr);

                                                 logger?.LogTrace("Getting SIP Data");
                                                 var    sipKind = SipExtensionFactory.GetSipKind(path);
                                                 void * sipData = (void *)0;
                                                 IntPtr context = IntPtr.Zero;

                                                 switch (sipKind)
                                                 {
                                                 case SipKind.Appx:
                                                     APPX_SIP_CLIENT_DATA   clientData;
                                                     SIGNER_SIGN_EX3_PARAMS parameters;
                                                     clientData.pSignerParams = &parameters;
                                                     sipData = &clientData;
                                                     flags  &= ~SignerSignEx3Flags.SPC_INC_PE_PAGE_HASHES_FLAG;
                                                     flags  |= SignerSignEx3Flags.SPC_EXC_PE_PAGE_HASHES_FLAG;
                                                     FillAppxExtension(ref clientData, flags, timeStampFlags, &subjectInfo, &signerCert, &signatureInfo, &context, pTimestampUrl, pTimestampAlgorithm, &signCallbackInfo);
                                                     break;
                                                 }

                                                 logger?.LogTrace("Calling SignerSignEx3");
                                                 var result = mssign32.SignerSignEx3
                                                              (
                                                     flags,
                                                     &subjectInfo,
                                                     &signerCert,
                                                     &signatureInfo,
                                                     IntPtr.Zero,
                                                     timeStampFlags,
                                                     pTimestampAlgorithm,
                                                     pTimestampUrl,
                                                     IntPtr.Zero,
                                                     sipData,
                                                     &context,
                                                     IntPtr.Zero,
                                                     &signCallbackInfo,
                                                     IntPtr.Zero
                                                              );

                                                 if (result == 0 && context != IntPtr.Zero)
                                                 {
                                                     Debug.Assert(mssign32.SignerFreeSignerContext(context) == 0);
                                                 }
                                                 if (result == 0 && sipKind == SipKind.Appx)
                                                 {
                                                     var state = ((APPX_SIP_CLIENT_DATA *)sipData)->pAppxSipState;
                                                     if (state != IntPtr.Zero)
                                                     {
                                                         Marshal.Release(state);
                                                     }
                                                 }
                                                 return(result);
                                             }
        }
        static IntPtr CreateSignerSubjectInfo(string pathToAssembly)
        {
            var info = new SIGNER_SUBJECT_INFO
            {
                cbSize = (uint) Marshal.SizeOf(typeof (SIGNER_SUBJECT_INFO)),
                pdwIndex = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (uint)))
            };

            const int index = 0;
            Marshal.StructureToPtr(index, info.pdwIndex, false);

            info.dwSubjectChoice = 0x1; //SIGNER_SUBJECT_FILE
            var assemblyFilePtr = Marshal.StringToHGlobalUni(pathToAssembly);

            var fileInfo = new SIGNER_FILE_INFO
            {
                cbSize = (uint) Marshal.SizeOf(typeof (SIGNER_FILE_INFO)),
                pwszFileName = assemblyFilePtr,
                hFile = IntPtr.Zero
            };

            info.Union1 = new SIGNER_SUBJECT_INFO.SubjectChoiceUnion
            {
                pSignerFileInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (SIGNER_FILE_INFO)))
            };

            Marshal.StructureToPtr(fileInfo, info.Union1.pSignerFileInfo, false);

            var pSubjectInfo = Marshal.AllocHGlobal(Marshal.SizeOf(info));
            Marshal.StructureToPtr(info, pSubjectInfo, false);

            return pSubjectInfo;
        }