Ejemplo n.º 1
0
        private SecurityHeader GetBasicUnsignedHeader()
        {
            // The header should have a mustUnderstand attribute value of 1
            var mustUnderstandAttribute =
                Util.CreateXmlAttribute("mustUnderstand", SOAP_ENVELOPE_NS, "1");

            DateTime createdTime = DateTime.Now;
            DateTime expiresTime = createdTime + RequestTimestampValidPeriod;

            string timestampId = CreateElementId(TIMESTAMP_ID_PREFIX);

            SecurityHeader ssoHeader = new SecurityHeader
            {
                Timestamp = new Timestamp
                {
                    Id      = timestampId,
                    Created =
                        new AttributedDateTime
                    {
                        Value = createdTime
                    },
                    Expires =
                        new AttributedDateTime
                    {
                        Value = expiresTime
                    }
                },
                AnyAttr = new[] { mustUnderstandAttribute }
            };

            return(ssoHeader);
        }
        private static void AssertSignedReferences(Receipt receiptMessage, SecurityHeader securityHeader)
        {
            IEnumerable <Reference> receiptRefs =
                receiptMessage.NonRepudiationInformation.MessagePartNRIReferences;

            Assert.All(
                securityHeader.GetReferences(),
                cryptoRef => Assert.Contains(receiptRefs, r => r.URI.Equals(cryptoRef.Uri)));
        }
Ejemplo n.º 3
0
        private void AppendUserNameToken(SecurityHeader wsSecurityHeader, string userName, SecureString password)
        {
            // Reusing the WCF UserNameSecurityToken as there is a built-in serializer for this type.

            UserNameSecurityToken userNameToken = null;

            string tokenId = CreateElementId(SECURITY_TOKEN_ID_PREFIX);

            userNameToken = new UserNameSecurityToken(userName, Util.ConvertSecureStringToString(password), tokenId);

            wsSecurityHeader.UsernameToken = SerializeToken(userNameToken);
        }
Ejemplo n.º 4
0
        private static XmlDocument ToXmlDocument(SecurityHeader value)

        {
            using (XmlDocumentWriterHelper documentWriterHelper = new XmlDocumentWriterHelper())

            {
                SecurityHeaderSerializer.Serialize(documentWriterHelper.CreateDocumentWriter(), value);



                return(documentWriterHelper.ReadDocument());
            }
        }
        /// <summary>
        /// Asynchronously deserializes the given <paramref name="input"/> stream to an <see cref="AS4Message"/> model.
        /// </summary>
        /// <param name="input">The source stream from where the message should be read.</param>
        /// <param name="contentType">The content type required to correctly deserialize the message into different MIME parts.</param>
        /// <param name="cancellation">The token to control the cancellation of the deserialization.</param>
        public async Task <AS4Message> DeserializeAsync(
            Stream input,
            string contentType,
            CancellationToken cancellation = default(CancellationToken))
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (contentType == null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }

            var envelopeDocument = new XmlDocument {
                PreserveWhitespace = true
            };

            envelopeDocument.Load(input);

            // Sometimes throws 'The 'http://www.w3.org/XML/1998/namespace:lang' attribute is not declared.'
            // ValidateEnvelopeDocument(envelopeDocument);

            XmlNamespaceManager nsMgr = GetNamespaceManagerForDocument(envelopeDocument);

            SecurityHeader securityHeader  = DeserializeSecurityHeader(envelopeDocument, nsMgr);
            Messaging      messagingHeader = DeserializeMessagingHeader(envelopeDocument, nsMgr);
            Body1          body            = DeserializeBody(envelopeDocument, nsMgr);

            if (messagingHeader == null)
            {
                throw new InvalidMessageException("The envelopeStream does not contain a Messaging element");
            }

            AS4Message as4Message =
                await AS4Message.CreateAsync(
                    envelopeDocument,
                    contentType,
                    securityHeader,
                    messagingHeader,
                    body);

            StreamUtilities.MovePositionToStreamStart(input);

            return(as4Message);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Appends client certificate information as a BinarySecurityToken XML element
        /// under the root Security element.
        /// </summary>
        /// <returns>
        /// A SecurityTokenReference element which references to the appended client certificate.
        /// </returns>
        private XmlElement AppendBinarySecurityToken(SecurityHeader wsSecurityHeader, X509Certificate2 clientCertificate)
        {
            XmlElement result = null;

            // Reusing the WCF X509SecurityToken as there is a built-in serializer for this type.

            string tokenId = CreateElementId(SECURITY_TOKEN_ID_PREFIX);

            using (var certificateToken = new X509SecurityToken(clientCertificate, tokenId))
            {
                var binarySecurityToken = SerializeToken(certificateToken);
                wsSecurityHeader.BinarySecurityToken = binarySecurityToken;

                result = GetKeyIdentifierClause(certificateToken);
            }

            return(result);
        }
        public async Task Creates_Receipt_With_Same_Signed_References_Tags_From_UserMessage()
        {
            // Arrange
            MessagingContext messagingContext = CreateSignedUserMessageWrappedInContext();

            messagingContext.ReceivingPMode.ReplyHandling.ReceiptHandling.UseNRRFormat = true;
            messagingContext.ReceivingPMode.ReplyHandling.ResponseSigning.IsEnabled    = true;

            // Act
            AS4Message result = await ExerciseCreateReceiptAsync(messagingContext);

            // Assert
            var            receiptMessage = result.FirstSignalMessage as Receipt;
            SecurityHeader securityHeader = messagingContext.AS4Message.SecurityHeader;

            Assert.NotNull(receiptMessage);
            Assert.NotNull(securityHeader);
            AssertSignedReferences(receiptMessage, securityHeader);
        }
Ejemplo n.º 8
0
        // V3 exploit
        // Magic
        //
        internal async static Task LumiaV3CustomFlash(PhoneNotifierViewModel Notifier, List <FlashPart> FlashParts, bool CheckSectorAlignment = true, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null)
        {
            if (SetWorkingStatus == null)
            {
                SetWorkingStatus = (m, s, v, a, st) => { }
            }
            ;
            if (UpdateWorkingStatus == null)
            {
                UpdateWorkingStatus = (m, s, v, st) => { }
            }
            ;
            if (ExitSuccess == null)
            {
                ExitSuccess = (m, s) => { }
            }
            ;
            if (ExitFailure == null)
            {
                ExitFailure = (m, s) => { }
            }
            ;

            uint chunkSize  = 131072u;
            int  chunkSizes = 131072;

            if (FlashParts != null)
            {
                foreach (FlashPart Part in FlashParts)
                {
                    if (Part.Stream == null)
                    {
                        throw new ArgumentException("Stream is null");
                    }
                    if (!Part.Stream.CanSeek)
                    {
                        throw new ArgumentException("Streams must be seekable");
                    }
                    if (((Part.StartSector * 0x200) % chunkSize) != 0)
                    {
                        throw new ArgumentException("Invalid StartSector alignment");
                    }
                    if (CheckSectorAlignment)
                    {
                        if ((Part.Stream.Length % chunkSize) != 0)
                        {
                            throw new ArgumentException("Invalid Data length");
                        }
                    }
                }
            }

            try
            {
                NokiaFlashModel Model = (NokiaFlashModel)Notifier.CurrentModel;
                PhoneInfo       Info  = Model.ReadPhoneInfo();

                if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV2)) == 0) // Exploit needs protocol v2 -> This check is not conclusive, because old phones also report support for this protocol, although it is really not supported.
                {
                    throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that it does not support the Protocol Sync V2.");
                }
                if (Info.FlashAppProtocolVersionMajor < 2) // Old phones do not support the hack. These phones have Flash protocol 1.x.
                {
                    throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that Flash App communication protocol is lower than 2. Reported version by the phone: " + Info.FlashAppProtocolVersionMajor + ".");
                }

                if (Info.UefiSecureBootEnabled)
                {
                    throw new WPinternalsException("Flash failed!", "UEFI Secureboot must be disabled for the Flash V3 exploit to work.");
                }

                // The payloads must be ordered by the number of locations
                //
                // FlashApp processes payloads like this:
                // - First payloads which are with one location, those can be sent in bulk
                // - Then payloads with more than one location, those should not be sent in bulk
                //
                // If you do not order payloads like this, you will get an error, most likely hash mismatch
                //
                LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = new LumiaV2UnlockBootViewModel.FlashingPayload[0];
                if (FlashParts != null)
                {
                    payloads = LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, (uint)(Info.WriteBufferSize / chunkSize), SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Count()).ToArray();
                }

                MemoryStream Headerstream1 = new MemoryStream();

                // ==============================
                // Header 1 start

                ImageHeader image   = new ImageHeader();
                FullFlash   ffimage = new FullFlash();
                Store       simage  = new Store();

                // Todo make this read the image itself
                ffimage.OSVersion         = "10.0.11111.0";
                ffimage.DevicePlatformId0 = Info.PlatformID;
                ffimage.AntiTheftVersion  = "1.1";

                simage.SectorSize     = 512;
                simage.MinSectorCount = Info.EmmcSizeInSectors;

                //Logging.Log("Generating image manifest...");
                string manifest = ManifestIni.BuildUpManifest(ffimage, simage);//, partitions);

                byte[] TextBytes = System.Text.Encoding.ASCII.GetBytes(manifest);

                image.ManifestLength = (UInt32)TextBytes.Length;

                byte[] ImageHeaderBuffer = new byte[0x18];

                ByteOperations.WriteUInt32(ImageHeaderBuffer, 0, image.Size);
                ByteOperations.WriteAsciiString(ImageHeaderBuffer, 0x04, image.Signature);
                ByteOperations.WriteUInt32(ImageHeaderBuffer, 0x10, image.ManifestLength);
                ByteOperations.WriteUInt32(ImageHeaderBuffer, 0x14, image.ChunkSize);

                Headerstream1.Write(ImageHeaderBuffer, 0, 0x18);
                Headerstream1.Write(TextBytes, 0, TextBytes.Length);

                RoundUpToChunks(Headerstream1, chunkSize);

                // Header 1 stop + round
                // ==============================

                MemoryStream Headerstream2 = new MemoryStream();

                // ==============================
                // Header 2 start

                StoreHeader store = new StoreHeader();

                store.WriteDescriptorCount = (UInt32)payloads.Count();
                store.FinalTableIndex      = (UInt32)payloads.Count() - store.FinalTableCount;
                store.PlatformId           = Info.PlatformID;

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    store.WriteDescriptorLength += payload.GetStoreHeaderSize();
                }

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    /*if (payload.TargetLocations.First() > PlatEnd)
                     *  break;*/
                    store.FlashOnlyTableIndex += 1;
                }

                byte[] StoreHeaderBuffer = new byte[0xF8];
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0, store.UpdateType);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x04, store.MajorVersion);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x06, store.MinorVersion);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x08, store.FullFlashMajorVersion);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x0A, store.FullFlashMinorVersion);
                ByteOperations.WriteAsciiString(StoreHeaderBuffer, 0x0C, store.PlatformId);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xCC, store.BlockSizeInBytes);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD0, store.WriteDescriptorCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD4, store.WriteDescriptorLength);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD8, store.ValidateDescriptorCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xDC, store.ValidateDescriptorLength);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE0, store.InitialTableIndex);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE4, store.InitialTableCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE8, store.FlashOnlyTableIndex);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xEC, store.FlashOnlyTableCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xF0, store.FinalTableIndex);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xF4, store.FinalTableCount);
                Headerstream2.Write(StoreHeaderBuffer, 0, 0xF8);

                byte[] descriptorsBuffer = new byte[store.WriteDescriptorLength];

                UInt32 NewWriteDescriptorOffset = 0;
                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, (UInt32)payload.TargetLocations.Count()); // Location count
                    ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, payload.ChunkCount);                      // Chunk count
                    NewWriteDescriptorOffset += 0x08;

                    foreach (UInt32 location in payload.TargetLocations)
                    {
                        ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, 0x00000000);                          // Disk access method (0 = Begin, 2 = End)
                        ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, location);                            // Chunk index
                        NewWriteDescriptorOffset += 0x08;
                    }
                }

                Headerstream2.Write(descriptorsBuffer, 0, (Int32)store.WriteDescriptorLength);

                RoundUpToChunks(Headerstream2, chunkSize);

                // Header 2 stop + round
                // ==============================

                SecurityHeader security = new SecurityHeader();

                Headerstream1.Seek(0, SeekOrigin.Begin);
                Headerstream2.Seek(0, SeekOrigin.Begin);

                security.HashTableSize = 0x20 * (UInt32)((Headerstream1.Length + Headerstream2.Length) / chunkSize);

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    security.HashTableSize += payload.GetSecurityHeaderSize();
                }

                byte[]       HashTable = new byte[security.HashTableSize];
                BinaryWriter bw        = new BinaryWriter(new MemoryStream(HashTable));

                SHA256 crypto = SHA256.Create();
                for (int i = 0; i < Headerstream1.Length / chunkSize; i++)
                {
                    byte[] buffer = new byte[chunkSize];
                    Headerstream1.Read(buffer, 0, (Int32)chunkSize);
                    byte[] hash = crypto.ComputeHash(buffer);
                    bw.Write(hash, 0, hash.Length);
                }

                for (int i = 0; i < Headerstream2.Length / chunkSize; i++)
                {
                    byte[] buffer = new byte[chunkSize];
                    Headerstream2.Read(buffer, 0, (Int32)chunkSize);
                    byte[] hash = crypto.ComputeHash(buffer);
                    bw.Write(hash, 0, hash.Length);
                }

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    bw.Write(payload.ChunkHashes[0], 0, payload.ChunkHashes[0].Length);
                }

                bw.Close();

                //Logging.Log("Generating image catalog...");
                byte[] catalog = GenerateCatalogFile(HashTable);

                security.CatalogSize = (UInt32)catalog.Length;

                byte[] SecurityHeaderBuffer = new byte[0x20];

                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0, security.Size);
                ByteOperations.WriteAsciiString(SecurityHeaderBuffer, 0x04, security.Signature);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x10, security.ChunkSizeInKb);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x14, security.HashAlgorithm);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x18, security.CatalogSize);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x1C, security.HashTableSize);

                MemoryStream retstream = new MemoryStream();

                retstream.Write(SecurityHeaderBuffer, 0, 0x20);

                retstream.Write(catalog, 0, (Int32)security.CatalogSize);
                retstream.Write(HashTable, 0, (Int32)security.HashTableSize);

                RoundUpToChunks(retstream, chunkSize);

                Headerstream1.Seek(0, SeekOrigin.Begin);
                Headerstream2.Seek(0, SeekOrigin.Begin);

                byte[] buff = new byte[Headerstream1.Length];
                Headerstream1.Read(buff, 0, (Int32)Headerstream1.Length);

                Headerstream1.Close();

                retstream.Write(buff, 0, buff.Length);

                buff = new byte[Headerstream2.Length];
                Headerstream2.Read(buff, 0, (Int32)Headerstream2.Length);

                Headerstream2.Close();

                retstream.Write(buff, 0, buff.Length);

                // --------

                // Go back to the beginning
                retstream.Seek(0, SeekOrigin.Begin);

                byte[] FfuHeader = new byte[retstream.Length];
                await retstream.ReadAsync(FfuHeader, 0, (int)retstream.Length);

                retstream.Close();

                byte Options = 0;
                if (!Info.IsBootloaderSecure)
                {
                    Options = (byte)((FlashOptions)Options | FlashOptions.SkipSignatureCheck);
                }

                LogFile.Log("Flash in progress...", LogType.ConsoleOnly);
                SetWorkingStatus("Flashing...", null, (UInt64?)payloads.Count(), Status: WPinternalsStatus.Flashing);

                Model.SendFfuHeaderV1(FfuHeader, Options);

                UInt64 counter = 0;

                int    numberOfPayloadsToSendAtOnce = (int)Math.Round((double)Info.WriteBufferSize / chunkSize);
                byte[] payloadBuffer;

                for (int i = 0; i < payloads.Count(); i += numberOfPayloadsToSendAtOnce)
                {
                    if (i + numberOfPayloadsToSendAtOnce - 1 >= payloads.Count())
                    {
                        numberOfPayloadsToSendAtOnce = payloads.Count() - i;
                    }

                    payloadBuffer = new byte[numberOfPayloadsToSendAtOnce * chunkSizes];

                    string ProgressText = "Flashing resources";

                    for (int j = 0; j < numberOfPayloadsToSendAtOnce; j++)
                    {
                        LumiaV2UnlockBootViewModel.FlashingPayload payload = payloads[i + j];

                        UInt32    StreamIndex = payload.StreamIndexes.First();
                        FlashPart flashPart   = FlashParts[(int)StreamIndex];

                        if (flashPart.ProgressText != null)
                        {
                            ProgressText = flashPart.ProgressText;
                        }

                        Stream Stream = flashPart.Stream;
                        Stream.Seek(payload.StreamLocations.First(), SeekOrigin.Begin);
                        Stream.Read(payloadBuffer, j * chunkSizes, chunkSizes);
                        counter++;
                    }

                    Model.SendFfuPayloadV2(payloadBuffer, int.Parse((counter * 100 / (ulong)payloads.Count()).ToString()));
                    UpdateWorkingStatus(ProgressText, null, counter, WPinternalsStatus.Flashing);
                }

                Model.ResetPhone();

                await Notifier.WaitForRemoval();

                ExitSuccess("Flash succeeded!", null);
            }
            catch
            {
                throw new WPinternalsException("Custom flash failed");
            }
        }
    }
}
Ejemplo n.º 9
0
        private SecurityHeader GetUnsignedHeader()

        {
            // The header should have a mustUnderstand attribute value of 1

            var mustUnderstandAttribute =

                Util.CreateXmlAttribute("mustUnderstand", SOAP_ENVELOPE_NS, "1");



            DateTime createdTime = DateTime.Now;

            DateTime expiresTime = createdTime + RequestTimestampValidPeriod;



            string timestampId = CreateElementId(TIMESTAMP_ID_PREFIX);



            SecurityHeader ssoHeader = new SecurityHeader

            {
                Timestamp = new Timestamp

                {
                    Id = timestampId,

                    Created =

                        new AttributedDateTime

                    {
                        Value = createdTime
                    },

                    Expires =

                        new AttributedDateTime

                    {
                        Value = expiresTime
                    }
                },

                AnyAttr = new[] { mustUnderstandAttribute }
            };



            if (_userNameToken != null)

            {
                ssoHeader.UsernameToken = ToXmlElement(_userNameToken);
            }



            if (_samlToken != null)

            {
                ssoHeader.SamlToken = _samlToken;
            }

            else

            {
                if (_certificateToken != null)

                {
                    // The X509 token is serialized as a binary security token in the security header.

                    var binarySecurityToken = ToXmlElement(_certificateToken);

                    ssoHeader.BinarySecurityToken = binarySecurityToken;
                }
            }



            return(ssoHeader);
        }
Ejemplo n.º 10
0
        public object BeforeSendRequest(ref Message request, IClientChannel channel)

        {
            // Working with the message in XML form

            XmlDocument soapRequest = GetXmlMessage(request);



            // Setting an ID to the body to be able to reference it in the signature (to be able to sign it)

            string bodyId = CreateElementId(BODY_ID_PREFIX);

            SetIdToBodyElement(soapRequest.DocumentElement, bodyId);



            SecurityHeader wsSecurityHeader = GetUnsignedHeader();



            // Converting the sso header from object to xml to easily assign xml values to properties.

            XmlDocument securityHeaderXml = ToXmlDocument(wsSecurityHeader);



            // Attaching the header without the signature

            var ssoHeaderElement = MergeMessageWithHeader(

                soapRequest.DocumentElement,

                securityHeaderXml.DocumentElement);



            if (_certificateToken != null)

            {
                // Get a key identifier to the key depending on how the key is specified.

                XmlElement keyIdentifier = _samlToken != null

                   ? GetKeyIdentifierClause(_samlToken)

                   : GetKeyIdentifierClause(_certificateToken);



                // Compute the signature on the timestamp and body elements.

                var signature = Util.ComputeSignature(

                    soapRequest,

                    keyIdentifier,

                    _certificateToken.Certificate.PrivateKey,

                    bodyId,

                    wsSecurityHeader.Timestamp.Id);



                // Inserting the signature into the security header (and the message respectively).

                ssoHeaderElement.AppendChild(signature);
            }



            // Convert the SOAP request back to a message that replaces the original message

            request = ToMessage(soapRequest, request.Version, request.Headers.Action, request.Properties);



            // No need to correlate requests with replays for this inspector.

            return(null);
        }
Ejemplo n.º 11
0
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            // Retrieve the security context if specified
            var securityContext = WsSecurityContext.GetProperties(request);

            if (securityContext == null)
            {
                // exit with unmodified message
                return(null);
            }

            ValidateSecurityContext(securityContext);

            // Working with the message in XML form
            XmlDocument soapRequest = GetXmlMessage(request);

            // Setting an ID to the body to be able to reference it in the signature (to be able to sign it)
            string bodyId = CreateElementId(BODY_ID_PREFIX);

            SetIdToBodyElement(soapRequest.DocumentElement, bodyId);

            SecurityHeader wsSecurityHeader = GetBasicUnsignedHeader();

            if (!String.IsNullOrEmpty(securityContext.Credentials.User))
            {
                AppendUserNameToken(
                    wsSecurityHeader,
                    securityContext.Credentials.User,
                    securityContext.Credentials.Password);
            }

            // A SecurityTokenReference XmlElement which contains the reference to signing client certificate.
            XmlElement keyIdentifierClause = null;

            if (securityContext.Credentials.BearerToken != null)
            {
                // No signature is used for Bearer token security context
                wsSecurityHeader.SamlToken = securityContext.Credentials.BearerToken;
            }
            else if (securityContext.Credentials.HolderOfKeyToken != null)
            {
                // For HoK token context, the signing certificate is contained within the HoK SAML token
                XmlElement hokToken = securityContext.Credentials.HolderOfKeyToken;
                wsSecurityHeader.SamlToken = hokToken;
                keyIdentifierClause        = GetKeyIdentifierClause(hokToken);
            }
            else if (securityContext.Credentials.ClientCertificate != null)
            {
                // Append local certificate info as a BinarySecurityToken child
                // element of the WS Security header and save a reference to it.
                keyIdentifierClause = AppendBinarySecurityToken(wsSecurityHeader, securityContext.Credentials.ClientCertificate);
            }

            // Converting the sso header from object to xml to easily assign xml values to properties.
            XmlElement securityHeaderXml = Util.ToXmlElement(wsSecurityHeader);

            // Attaching the header without the signature
            var ssoHeaderElement = MergeMessageWithHeader(
                soapRequest.DocumentElement,
                securityHeaderXml);

            if (keyIdentifierClause != null)
            {
                // This should already be ensured by ValidateSecurityContext() method
                Debug.Assert(securityContext.SigningKey != null);

                // Compute signature for timestamp and body elements and add the signature element to the security header.

                var signature = Util.ComputeSignature(
                    soapRequest,
                    keyIdentifierClause,
                    securityContext.SigningKey,
                    bodyId,
                    wsSecurityHeader.Timestamp.Id);

                ssoHeaderElement.AppendChild(signature);
            }

            // Convert the SOAP request back to a message that replaces the original message
            request = ToMessage(soapRequest, request.Version, request.Headers.Action, request.Properties);


            // No need to correlate requests with replays for this inspector.
            return(null);
        }