Skip to content

Instantly share code, notes, and snippets.

@Isaac-Kleinman
Created May 5, 2014 22:06
Show Gist options
  • Save Isaac-Kleinman/5a5fa6800cdc3e9e1a69 to your computer and use it in GitHub Desktop.
Save Isaac-Kleinman/5a5fa6800cdc3e9e1a69 to your computer and use it in GitHub Desktop.
using System;
using System.Text;
using System.ServiceModel.Channels;
using System.Xml;
using System.IO;
using System.Security.Cryptography;
using System.Resources;
using System.Security.Cryptography.X509Certificates;
namespace eMedNySOAPClient
{
public class CustomTextMessageEncoder : MessageEncoder
{
private string contentType;
private MessageVersion msgVersion;
public CustomTextMessageEncoder(string contentType, MessageVersion msgVersion)
{
this.contentType = contentType;
this.msgVersion = msgVersion;
}
public override string ContentType
{
get
{
return contentType;
}
}
public override string MediaType
{
get
{
return string.Empty;
}
}
public override MessageVersion MessageVersion
{
get
{
return msgVersion;
}
}
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
byte[] msgContents = new byte[buffer.Count];
Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);
bufferManager.ReturnBuffer(buffer.Array);
MemoryStream stream = new MemoryStream(msgContents);
var doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(stream);
var encryptedKey = doc.GetElementsByTagName( "xenc:EncryptedKey" )[0].InnerText;
var cipherText = doc.GetElementsByTagName( "xenc:CipherValue" )[1].InnerText;
var cipher = Convert.FromBase64String( cipherText );
var clientCert = new X509Certificate2( //PULL IN YOUR CLIENT CERTIFICATE HERE );
var rsa = (RSACryptoServiceProvider)clientCert.PrivateKey;
byte [] key = rsa.Decrypt(Convert.FromBase64String(encryptedKey), false);
SymmetricAlgorithm alg = new TripleDESCryptoServiceProvider();
alg.KeySize = 192;
alg.Mode = CipherMode.CBC;
alg.Padding = PaddingMode.ISO10126;
byte[] IV = new byte[8];
Array.Copy(cipher, IV, 8);
MemoryStream ms = new MemoryStream( cipher , IV.Length, cipher.Length-IV.Length);
CryptoStream csDecrypt = new CryptoStream( ms, alg.CreateDecryptor(key, IV ), CryptoStreamMode.Read);
byte [] fromEnc = new byte[cipher.Length];
csDecrypt.Read(fromEnc, 0, fromEnc.Length);
string messageBody = UTF8Encoding.UTF8.GetString(fromEnc);
XmlDocumentFragment bodyElement = doc.CreateDocumentFragment();
bodyElement.InnerXml = messageBody;
var body = (XmlNode)doc.GetElementsByTagName("soapenv:Body")[0];
body.ReplaceChild( bodyElement, body.FirstChild );
doc.DocumentElement.RemoveChild( doc.GetElementsByTagName( "soapenv:Header" )[0] );
stream = new MemoryStream();
doc.Save(stream);
stream.Position = 0;
return Message.CreateMessage(XmlReader.Create(stream), int.MaxValue, this.MessageVersion);
}
public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
{
XmlReader reader = XmlReader.Create(stream);
var message = Message.CreateMessage(reader, maxSizeOfHeaders, this.MessageVersion);
return message;
}
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
MemoryStream stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream);
message.WriteMessage(writer);
writer.Close();
byte[] messageBytes = stream.GetBuffer();
int messageLength = (int)stream.Position;
int totalLength = messageLength + messageOffset;
byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
return byteArray;
}
public override void WriteMessage(Message message, Stream stream)
{
XmlWriter writer = XmlWriter.Create(stream);
message.WriteMessage(writer);
writer.Close();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment