This commit is contained in:
skidoodle 2024-03-13 00:33:46 +01:00
commit e124a47765
19374 changed files with 9806149 additions and 0 deletions

View file

@ -0,0 +1,92 @@
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
namespace Kreta.EESZTInterface.STS
{
partial class CreateSoap
{
public static XmlDocument CreateX509Soap(X509Certificate2 oamCert, X509Certificate2 cert)
{
XmlElement elem;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
string idBody = "Id-" + Guid.NewGuid().ToString().Replace("-", "");
string idTs = "TS-" + Guid.NewGuid().ToString().Replace("-", "");
string idX509 = "X509-" + Guid.NewGuid().ToString().Replace("-", "");
string idOamCert = "OAM-" + Guid.NewGuid().ToString().Replace("-", "");
XmlElement root = xmlDoc.CreateElement("soap", "Envelope", Namespaces.soap12Ns);
root.SetAttribute("xmlns:ns", Namespaces.nsNs);
xmlDoc.AppendChild(root);
XmlElement head = xmlDoc.CreateElement("soap", "Header", Namespaces.soap12Ns);
root.AppendChild(head);
XmlElement sec = xmlDoc.CreateElement("wsse", "Security", Namespaces.wsseNs);
sec.SetAttribute("xmlns:wsu", Namespaces.wsuNs);
head.AppendChild(sec);
XmlElement binary = xmlDoc.CreateElement("wsse", "BinarySecurityToken", Namespaces.wsseNs);
binary.SetAttribute("Id", Namespaces.wsuNs, idOamCert);
binary.SetAttribute("ValueType", STSValues.x509v3Value);
binary.SetAttribute("EncodingType", STSValues.base64BinaryValue);
binary.InnerText = CertificateHelper.CertToBase64String(oamCert);
sec.AppendChild(binary);
binary = xmlDoc.CreateElement("wsse", "BinarySecurityToken", Namespaces.wsseNs);
binary.SetAttribute("Id", Namespaces.wsuNs, idX509);
binary.SetAttribute("ValueType", STSValues.x509v3Value);
binary.SetAttribute("EncodingType", STSValues.base64BinaryValue);
binary.InnerText = CertificateHelper.CertToBase64String(cert);
sec.AppendChild(binary);
XmlElement timestamp = xmlDoc.CreateElement("wsu", "Timestamp", Namespaces.wsuNs);
timestamp.SetAttribute("Id", Namespaces.wsuNs, idTs);
sec.AppendChild(timestamp);
elem = xmlDoc.CreateElement("wsu", "Created", Namespaces.wsuNs);
elem.InnerText = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ");
timestamp.AppendChild(elem);
elem = xmlDoc.CreateElement("wsu", "Expires", Namespaces.wsuNs);
elem.InnerText = DateTime.Now.AddHours(2).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ");
timestamp.AppendChild(elem);
XmlElement body = xmlDoc.CreateElement("soap", "Body", Namespaces.soap12Ns);
body.SetAttribute("xmlns:wsu", Namespaces.wsuNs);
body.SetAttribute("Id", Namespaces.wsuNs, idBody);
xmlDoc.DocumentElement.AppendChild(body);
XmlElement secToken = xmlDoc.CreateElement("ns", "RequestSecurityToken", Namespaces.nsNs);
body.AppendChild(secToken);
elem = xmlDoc.CreateElement("ns", "RequestType", Namespaces.nsNs);
elem.InnerText = STSValues.issueValue;
secToken.AppendChild(elem);
elem = xmlDoc.CreateElement("ns", "TokenType", Namespaces.nsNs);
elem.InnerText = STSValues.samlv2Value;
secToken.AppendChild(elem);
var mem = new MemoryStream();
xmlDoc.Save(mem);
mem.Seek(0, SeekOrigin.Begin);
xmlDoc = new XmlDocument
{
PreserveWhitespace = true
};
xmlDoc.Load(mem);
xmlDoc = SignHelper.SignMessage(xmlDoc, cert, "#" + idBody, "#" + idTs, "#" + idX509);
xmlDoc = EncryptHelper.EncryptMessage(xmlDoc, oamCert, "#" + idBody, "#" + idTs, "#" + idOamCert);
return xmlDoc;
}
}
}

View file

@ -0,0 +1,131 @@
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using Kreta.Resources;
namespace Kreta.EESZTInterface.STS
{
public class DoRequest
{
public static XmlDocument GetSoapSamlResponse(string stsUri, X509Certificate2 sslAuthCert, XmlDocument soapSamlRequest)
{
try
{
HttpWebRequest request = GetHttpWebRequest(stsUri, sslAuthCert);
var response = WriteToHttpStream(request, soapSamlRequest);
var soapResponse = ThrowIfSoapFault(response, stsUri);
return soapResponse;
}
catch (WebException wex)
{
string exMessage = wex.Message;
if (wex.Response != null)
{
using (var responseReader = new StreamReader(wex.Response.GetResponseStream()))
{
exMessage = responseReader.ReadToEnd();
ThrowIfSoapFault(exMessage, wex.Response.ResponseUri.OriginalString);
}
}
throw new Exception(exMessage, wex);
}
catch
{
throw;
}
}
private static HttpWebRequest GetHttpWebRequest(string stsUri, X509Certificate2 sslAuthCert)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(stsUri);
request.Headers.Add("SOAPAction", STSValues.soapActionValue);
request.ContentType = "application/soap+xml;charset=\"utf-8\"";
request.Accept = "application/soap+xml";
request.Method = "POST";
request.ClientCertificates.Add(sslAuthCert);
return request;
}
private static string WriteToHttpStream(HttpWebRequest request, XmlDocument samlRequest)
{
var outputStream = new MemoryStream();
samlRequest.Save(outputStream);
request.ContentLength = outputStream.Length;
outputStream.Seek(0, SeekOrigin.Begin);
var outStr = outputStream.ToArray();
outputStream.Close();
using (Stream requestStream = request.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(requestStream))
{
requestStream.Write(outStr, 0, outStr.Length);
}
}
string responseString = string.Empty;
WebResponse response = request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseString = sr.ReadToEnd();
}
return responseString;
}
private static XmlDocument ThrowIfSoapFault(string response, string responseUri)
{
XmlDocument soapMessage = null;
try
{
soapMessage = ExtractDocumentFromResponse(response);
if (soapMessage == null)
{
throw new Exception();
}
}
catch (Exception ex)
{
throw new Exception(string.Format(EESZTInterfaceResource.NemMegfeleloSOAPValaszFormatum, responseUri, response), ex);
}
XmlElement fault = XmlHelper.GetElement("Fault", Namespaces.soap12Ns, soapMessage.DocumentElement);
if (fault == null)
{
return soapMessage;
}
var faultCodeNodes = XmlHelper.GetElement("Code", Namespaces.soap12Ns, fault);
var faultReasonNodes = XmlHelper.GetElement("Reason", Namespaces.soap12Ns, fault);
var exceptionDetailNodes = XmlHelper.GetElement("Detail", Namespaces.soap12Ns, fault);
throw new Exception("Hiba! Kód:" + faultCodeNodes.InnerText + " Részletek:" + faultReasonNodes.InnerText,
new Exception((exceptionDetailNodes == null) ? "" : exceptionDetailNodes.InnerText));
}
private static XmlDocument ExtractDocumentFromResponse(string response)
{
var soapResponse = new XmlDocument();
soapResponse.PreserveWhitespace = true;
soapResponse.LoadXml(response);
return soapResponse;
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
}
}

View file

@ -0,0 +1,237 @@

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;
using Kreta.Resources;
namespace Kreta.EESZTInterface.STS
{
class EncryptHelper
{
public static RSA TransportKey { get; set; }
private static SymmetricAlgorithm _sessionKey;
private static string _sessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url;
private static SymmetricAlgorithm SessionKey
{
get
{
if (_sessionKey == null)
{
_sessionKey = GetKeyInstance(_sessionKeyAlgorithm);
_sessionKey.GenerateKey();
}
return _sessionKey;
}
}
public static string SessionKeyAlgorithm
{
get { return _sessionKeyAlgorithm; }
set
{
// Validate that the URI used to identify the algorithm of the session key is probably correct. Not a complete validation, but should catch most obvious mistakes.
if (!value.StartsWith(Namespaces.xencNs))
{
throw new ArgumentException(EESZTInterfaceResource.SessionKeyAlgorithmMustBeSpecified);
}
_sessionKeyAlgorithm = value;
}
}
public static XmlDocument EncryptMessage(XmlDocument mySoap, X509Certificate2 oamcert, string IdBody, string IdTs,
string idOamCert)
{
string encKId = "EK-" + Guid.NewGuid().ToString().Replace("-", "");
string encDId = "ED-" + Guid.NewGuid().ToString().Replace("-", "");
// Create a symmetric key.
SessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url;
TransportKey = (RSA)oamcert.PublicKey.Key;
var encryptedData = new EncryptedData
{
Type = EncryptedXml.XmlEncElementContentUrl,
EncryptionMethod = new EncryptionMethod(_sessionKeyAlgorithm),
Id = encDId
};
var body = XmlHelper.GetElement(XmlHelper.BodyElementName, Namespaces.soap12Ns, mySoap.DocumentElement);
var requestSecurityToken = XmlHelper.GetElement(XmlHelper.RequestSecurityTokenElementName, Namespaces.nsNs, body);
var encryptedXml = new EncryptedXml();
var encryptedElement = encryptedXml.EncryptData(requestSecurityToken, SessionKey, false);
encryptedData.CipherData.CipherValue = encryptedElement;
encryptedData.KeyInfo = new KeyInfo();
var encryptedKey = new EncryptedKey
{
EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSAOAEPUrl),
CipherData = new CipherData(EncryptedXml.EncryptKey(SessionKey.Key, TransportKey, true)),
Id = encKId
};
var kInfo = new KeyInfo();
kInfo.Id = "KI-" + Guid.NewGuid().ToString().Replace("-", "");
XmlElement securityTokenReference = mySoap.CreateElement("wsse", "SecurityTokenReference", Namespaces.wsseNs);
securityTokenReference.SetAttribute("Id", Namespaces.wsuNs, "STR-" + Guid.NewGuid().ToString().Replace("-", ""));
XmlElement reference = mySoap.CreateElement("wsse", "Reference", Namespaces.wsseNs);
reference.SetAttribute("ValueType", STSValues.x509v3Value);
reference.SetAttribute("URI", idOamCert);
securityTokenReference.AppendChild(reference);
KeyInfoNode kInfoNode = new KeyInfoNode();
kInfoNode.Value = securityTokenReference;
kInfo.AddClause(kInfoNode);
encryptedKey.KeyInfo = kInfo;
DataReference dRef = new DataReference();
dRef.Uri = "#" + encDId;
encryptedKey.AddReference(dRef);
var headerSec = XmlHelper.GetElement(XmlHelper.SecurityElementName, Namespaces.wsseNs, mySoap.DocumentElement);
var enc = encryptedKey.GetXml();
XmlElement encKeyElement = headerSec.OwnerDocument.ImportNode(encryptedKey.GetXml(), true) as XmlElement;
SetEncPrefix(encKeyElement);
headerSec.InsertAfter(encKeyElement, XmlHelper.GetElementId(mySoap, idOamCert.Replace("#", "")));
kInfo = new KeyInfo();
securityTokenReference = mySoap.CreateElement("wsse", "SecurityTokenReference", Namespaces.wsseNs);
securityTokenReference.SetAttribute("xmlns:wsse11", Namespaces.wsse11Ns);
securityTokenReference.SetAttribute("TokenType", Namespaces.wsse11Ns, STSValues.encryptedKeyValue);
reference = mySoap.CreateElement("wsse", "Reference", Namespaces.wsseNs);
reference.SetAttribute("URI", "#" + encKId);
securityTokenReference.AppendChild(reference);
kInfoNode = new KeyInfoNode();
kInfoNode.Value = securityTokenReference;
kInfo.AddClause(kInfoNode);
encryptedData.KeyInfo = kInfo;
EncryptedXml.ReplaceElement(body, encryptedData, true);
SetEncPrefix(body);
return mySoap;
}
public static XmlDocument DecryptMessageAll(XmlDocument mySoap, X509Certificate2 userCert)
{
RSA publicKeyRSA = userCert.PrivateKey as RSA;
TransportKey = publicKeyRSA;
var bodyElement = XmlHelper.GetElement(XmlHelper.BodyElementName, Namespaces.soap12Ns, mySoap.DocumentElement);
var encryptedDataElement = XmlHelper.GetElement(XmlHelper.EncryptedDataElementName, Namespaces.xencNs, bodyElement);
var securityElement = XmlHelper.GetElement(XmlHelper.SecurityElementName, Namespaces.wsseNs, mySoap.DocumentElement);
var encryptedData = new EncryptedData();
encryptedData.LoadXml(encryptedDataElement);
string _sessionKeyAlgorithm;
SymmetricAlgorithm sessionKey;
if (encryptedData.EncryptionMethod != null)
{
_sessionKeyAlgorithm = encryptedData.EncryptionMethod.KeyAlgorithm;
sessionKey = ExtractSessionKey(securityElement, encryptedDataElement, _sessionKeyAlgorithm);
}
else
{
sessionKey = ExtractSessionKey(securityElement, encryptedDataElement, string.Empty);
}
var encryptedXml = new EncryptedXml(mySoap);
encryptedXml.ReplaceData(encryptedDataElement, encryptedXml.DecryptData(encryptedData, sessionKey));
return mySoap;
}
private static SymmetricAlgorithm ExtractSessionKey(XmlElement securityElement, XmlElement encryptedData, string keyAlgorithm)
{
// Check if there are any <EncryptedKey> elements immediately below the EncryptedAssertion element.
foreach (XmlNode node in securityElement.ChildNodes)
{
if (node.LocalName == XmlHelper.EncryptedKeyElementName && node.NamespaceURI == Namespaces.xencNs)
{
return ToSymmetricKey((XmlElement)node, keyAlgorithm);
}
}
// Check if the key is embedded in the <EncryptedData> element.
if (encryptedData != null)
{
var encryptedKeyElement = XmlHelper.GetElement(XmlHelper.EncryptedKeyElementName, Namespaces.xencNs, encryptedData);
if (encryptedKeyElement != null)
{
return ToSymmetricKey(encryptedKeyElement, keyAlgorithm);
}
}
throw new Exception(EESZTInterfaceResource.EncryptedKeyNemTalalhato);
}
private static SymmetricAlgorithm ToSymmetricKey(XmlElement encryptedKeyElement, string keyAlgorithm)
{
var encryptedKey = new EncryptedKey();
encryptedKey.LoadXml(encryptedKeyElement);
var useOaep = true;
if (encryptedKey.EncryptionMethod != null)
{
useOaep = encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl;
}
if (encryptedKey.CipherData.CipherValue != null)
{
var key = GetKeyInstance(keyAlgorithm);
key.Key = EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, TransportKey, useOaep);
return key;
}
throw new NotImplementedException(EESZTInterfaceResource.UnableToDecodeCipherData);
}
private static SymmetricAlgorithm GetKeyInstance(string algorithm)
{
SymmetricAlgorithm result;
switch (algorithm)
{
case EncryptedXml.XmlEncTripleDESUrl:
result = TripleDES.Create();
break;
case EncryptedXml.XmlEncAES128Url:
result = new RijndaelManaged { KeySize = 128 };
break;
case EncryptedXml.XmlEncAES192Url:
result = new RijndaelManaged { KeySize = 192 };
break;
case EncryptedXml.XmlEncAES256Url:
default:
result = new RijndaelManaged { KeySize = 256 };
break;
}
return result;
}
private static void SetEncPrefix(XmlElement encKeyElement)
{
foreach (XmlNode xnode in encKeyElement.SelectNodes($"descendant-or-self::*[namespace-uri()='{Namespaces.dsNs}']"))
{
xnode.Prefix = "ds";
}
foreach (XmlNode xnode in encKeyElement.SelectNodes($"descendant-or-self::*[namespace-uri()='{Namespaces.xencNs}']"))
{
xnode.Prefix = "xenc";
}
}
}
}

View file

@ -0,0 +1,320 @@
using System;
using System.Collections;
using System.Reflection;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;
using Kreta.Resources;
namespace Kreta.EESZTInterface.STS
{
class PrefixedSignedXML : SignedXml
{
private string signatureValueId;
public PrefixedSignedXML(XmlDocument document)
: base(document)
{ }
public PrefixedSignedXML(XmlElement element)
: base(element)
{ }
public PrefixedSignedXML()
: base()
{ }
/// <summary>
/// Setting this property will add an ID attribute to the SignatureValue element.
/// This is required when constructing a XAdES-T signature.
/// </summary>
public string SignatureValueId
{
get
{
return this.signatureValueId;
}
set
{
this.signatureValueId = value;
}
}
public override XmlElement GetIdElement(XmlDocument doc, string id)
{
// check to see if it's a standard ID reference
XmlElement idElem = base.GetIdElement(doc, id);
if (idElem == null)
{
XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("wsu", Namespaces.wsuNs);
idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement;
}
return idElem;
}
/// <summary>
/// Copy of System.Security.Cryptography.Xml.SignedXml.ComputeSignature() which will end up calling
/// our own GetC14NDigest with a namespace prefix for all XmlDsig nodes
/// </summary>
public new void ComputeSignature()
{
this.BuildDigestedReferences();
AsymmetricAlgorithm signingKey = this.SigningKey;
if (signingKey == null)
{
throw new CryptographicException(EESZTInterfaceResource.CryptographyXmlLoadKeyFailed);
}
if (this.SignedInfo.SignatureMethod == null)
{
if (!(signingKey is DSA))
{
if (!(signingKey is RSA))
{
throw new CryptographicException(EESZTInterfaceResource.CryptographyXmlCreatedKeyFailed);
}
if (this.SignedInfo.SignatureMethod == null)
{
this.SignedInfo.SignatureMethod = STSValues.signatureMethodRSAValue;
}
}
else
{
this.SignedInfo.SignatureMethod = STSValues.signatureMethodDSAValue;
}
}
SignatureDescription description = CryptoConfig.CreateFromName(this.SignedInfo.SignatureMethod) as SignatureDescription;
if (description == null)
{
throw new CryptographicException(EESZTInterfaceResource.CryptographyXmlSignatureDescriptionNotCreated);
}
HashAlgorithm hash = description.CreateDigest();
if (hash == null)
{
throw new CryptographicException(EESZTInterfaceResource.CryptographyXmlCreateHashAlgorithmFailed);
}
//this.GetC14NDigest(hash);
this.GetC14NDigest(hash, "ds");
//
this.m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);
}
/// <summary>
/// Returns the XML representation of the this object
/// </summary>
/// <returns>XML element containing the state of this object</returns>
public new XmlElement GetXml()
{
XmlElement retVal;
XmlNodeList xmlNodeList;
XmlNamespaceManager xmlNamespaceManager;
retVal = base.GetXml();
if (this.signatureValueId != null && this.signatureValueId != "")
{ //Id on Signature value is needed for XAdES-T. We inject it here.
xmlNamespaceManager = new XmlNamespaceManager(retVal.OwnerDocument.NameTable);
xmlNamespaceManager.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
xmlNodeList = retVal.SelectNodes("ds:SignatureValue", xmlNamespaceManager);
if (xmlNodeList.Count > 0)
{
((XmlElement)xmlNodeList[0]).SetAttribute("Id", this.signatureValueId);
}
}
// Add "ds" namespace prefix to all XmlDsig nodes in the signature
SetPrefix("ds", retVal);
return retVal;
}
/// <summary>
/// Copy of System.Security.Cryptography.Xml.SignedXml.BuildDigestedReferences() which will add a "ds"
/// namespace prefix to all XmlDsig nodes
/// </summary>
private void BuildDigestedReferences()
{
ArrayList references = this.SignedInfo.References;
//this.m_refProcessed = new bool[references.Count];
Type SignedXml_Type = typeof(SignedXml);
FieldInfo SignedXml_m_refProcessed = SignedXml_Type.GetField("m_refProcessed", BindingFlags.NonPublic | BindingFlags.Instance);
SignedXml_m_refProcessed.SetValue(this, new bool[references.Count]);
//
//this.m_refLevelCache = new int[references.Count];
FieldInfo SignedXml_m_refLevelCache = SignedXml_Type.GetField("m_refLevelCache", BindingFlags.NonPublic | BindingFlags.Instance);
SignedXml_m_refLevelCache.SetValue(this, new int[references.Count]);
//
//ReferenceLevelSortOrder comparer = new ReferenceLevelSortOrder();
Assembly System_Security_Assembly = Assembly.Load("System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
Type ReferenceLevelSortOrder_Type = System_Security_Assembly.GetType("System.Security.Cryptography.Xml.SignedXml+ReferenceLevelSortOrder");
ConstructorInfo ReferenceLevelSortOrder_Constructor = ReferenceLevelSortOrder_Type.GetConstructor(new Type[] { });
Object comparer = ReferenceLevelSortOrder_Constructor.Invoke(null);
//
//comparer.References = references;
PropertyInfo ReferenceLevelSortOrder_References = ReferenceLevelSortOrder_Type.GetProperty("References", BindingFlags.Public | BindingFlags.Instance);
ReferenceLevelSortOrder_References.SetValue(comparer, references, null);
//
ArrayList list2 = new ArrayList();
foreach (Reference reference in references)
{
list2.Add(reference);
}
list2.Sort((IComparer)comparer);
//CanonicalXmlNodeList refList = new CanonicalXmlNodeList();
Type CanonicalXmlNodeList_Type = System_Security_Assembly.GetType("System.Security.Cryptography.Xml.CanonicalXmlNodeList");
ConstructorInfo CanonicalXmlNodeList_Constructor = CanonicalXmlNodeList_Type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
Object refList = CanonicalXmlNodeList_Constructor.Invoke(null);
//
//
MethodInfo CanonicalXmlNodeList_Add = CanonicalXmlNodeList_Type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
//
foreach (DataObject obj2 in this.m_signature.ObjectList)
{
//refList.Add(obj2.GetXml());
XmlElement xml = obj2.GetXml();
SetPrefix("ds", xml); // <---
CanonicalXmlNodeList_Add.Invoke(refList, new object[] { xml });
//
}
//
FieldInfo SignedXml_m_containingDocument = SignedXml_Type.GetField("m_containingDocument", BindingFlags.NonPublic | BindingFlags.Instance);
Type Reference_Type = typeof(Reference);
MethodInfo Reference_UpdateHashValue = Reference_Type.GetMethod("UpdateHashValue", BindingFlags.NonPublic | BindingFlags.Instance);
//
foreach (Reference reference2 in list2)
{
if (reference2.DigestMethod == null)
{
reference2.DigestMethod = STSValues.digestMethodSHA1Value;
}
//reference2.UpdateHashValue(this.m_containingDocument, refList);
object m_containingDocument = SignedXml_m_containingDocument.GetValue(this);
Reference_UpdateHashValue.Invoke(reference2, new object[] { m_containingDocument, refList });
//
if (reference2.Id != null)
{
//refList.Add(reference2.GetXml());
XmlElement xml = reference2.GetXml();
SetPrefix("ds", xml); // <---
CanonicalXmlNodeList_Add.Invoke(refList, new object[] { xml });
//
}
}
}
/// <summary>
/// Copy of System.Security.Cryptography.Xml.SignedXml.GetC14NDigest() which will add a
/// namespace prefix to all XmlDsig nodes
/// </summary>
private byte[] GetC14NDigest(HashAlgorithm hash, string prefix)
{
//if (!this.bCacheValid || !this.SignedInfo.CacheValid)
//{
Type SignedXml_Type = typeof(SignedXml);
FieldInfo SignedXml_bCacheValid = SignedXml_Type.GetField("bCacheValid", BindingFlags.NonPublic | BindingFlags.Instance);
bool bCacheValid = (bool)SignedXml_bCacheValid.GetValue(this);
Type SignedInfo_Type = typeof(SignedInfo);
PropertyInfo SignedInfo_CacheValid = SignedInfo_Type.GetProperty("CacheValid", BindingFlags.NonPublic | BindingFlags.Instance);
bool CacheValid = (bool)SignedInfo_CacheValid.GetValue(this.SignedInfo, null);
FieldInfo SignedXml__digestedSignedInfo = SignedXml_Type.GetField("_digestedSignedInfo", BindingFlags.NonPublic | BindingFlags.Instance);
if (!bCacheValid || !CacheValid)
{
//
//string securityUrl = (this.m_containingDocument == null) ? null : this.m_containingDocument.BaseURI;
FieldInfo SignedXml_m_containingDocument = SignedXml_Type.GetField("m_containingDocument", BindingFlags.NonPublic | BindingFlags.Instance);
XmlDocument m_containingDocument = (XmlDocument)SignedXml_m_containingDocument.GetValue(this);
string securityUrl = m_containingDocument?.BaseURI;
//
//XmlResolver xmlResolver = this.m_bResolverSet ? this.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl);
FieldInfo SignedXml_m_bResolverSet = SignedXml_Type.GetField("m_bResolverSet", BindingFlags.NonPublic | BindingFlags.Instance);
bool m_bResolverSet = (bool)SignedXml_m_bResolverSet.GetValue(this);
FieldInfo SignedXml_m_xmlResolver = SignedXml_Type.GetField("m_xmlResolver", BindingFlags.NonPublic | BindingFlags.Instance);
XmlResolver m_xmlResolver = (XmlResolver)SignedXml_m_xmlResolver.GetValue(this);
XmlResolver xmlResolver = m_bResolverSet ? m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl);
//
//XmlDocument document = Utils.PreProcessElementInput(this.SignedInfo.GetXml(), xmlResolver, securityUrl);
Assembly System_Security_Assembly = Assembly.Load("System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
Type Utils_Type = System_Security_Assembly.GetType("System.Security.Cryptography.Xml.Utils");
MethodInfo Utils_PreProcessElementInput = Utils_Type.GetMethod("PreProcessElementInput", BindingFlags.NonPublic | BindingFlags.Static);
XmlElement xml = this.SignedInfo.GetXml();
SetPrefix(prefix, xml); // <---
XmlDocument document = (XmlDocument)Utils_PreProcessElementInput.Invoke(null, new object[] { xml, xmlResolver, securityUrl });
//
//CanonicalXmlNodeList namespaces = (this.m_context == null) ? null : Utils.GetPropagatedAttributes(this.m_context);
FieldInfo SignedXml_m_context = SignedXml_Type.GetField("m_context", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo Utils_GetPropagatedAttributes = Utils_Type.GetMethod("GetPropagatedAttributes", BindingFlags.NonPublic | BindingFlags.Static);
object m_context = SignedXml_m_context.GetValue(this);
object namespaces = (m_context == null) ? null : Utils_GetPropagatedAttributes.Invoke(null, new object[] { m_context });
//
// Utils.AddNamespaces(document.DocumentElement, namespaces);
Type CanonicalXmlNodeList_Type = System_Security_Assembly.GetType("System.Security.Cryptography.Xml.CanonicalXmlNodeList");
MethodInfo Utils_AddNamespaces = Utils_Type.GetMethod("AddNamespaces", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(XmlElement), CanonicalXmlNodeList_Type }, null);
Utils_AddNamespaces.Invoke(null, new object[] { document.DocumentElement, namespaces });
//
//Transform canonicalizationMethodObject = this.SignedInfo.CanonicalizationMethodObject;
System.Security.Cryptography.Xml.Transform canonicalizationMethodObject = this.SignedInfo.CanonicalizationMethodObject;
//
canonicalizationMethodObject.Resolver = xmlResolver;
//canonicalizationMethodObject.BaseURI = securityUrl;
Type Transform_Type = typeof(System.Security.Cryptography.Xml.Transform);
PropertyInfo Transform_BaseURI = Transform_Type.GetProperty("BaseURI", BindingFlags.NonPublic | BindingFlags.Instance);
Transform_BaseURI.SetValue(canonicalizationMethodObject, securityUrl, null);
//
canonicalizationMethodObject.LoadInput(document);
//this._digestedSignedInfo = canonicalizationMethodObject.GetDigestedOutput(hash);
SignedXml__digestedSignedInfo.SetValue(this, canonicalizationMethodObject.GetDigestedOutput(hash));
//
//this.bCacheValid = true;
SignedXml_bCacheValid.SetValue(this, true);
//
}
//return this._digestedSignedInfo;
byte[] _digestedSignedInfo = (byte[])SignedXml__digestedSignedInfo.GetValue(this);
return _digestedSignedInfo;
//
}
private void SetPrefix(string prefix, XmlNode node)
{
foreach (XmlNode n in node.ChildNodes)
SetPrefix(prefix, n);
if (node.NamespaceURI == Namespaces.dsNs)
{
node.Prefix = prefix;
}
else if (node.NamespaceURI == Namespaces.c14nNs)
{
node.Prefix = "ec";
}
}
}
}

View file

@ -0,0 +1,16 @@
namespace Kreta.EESZTInterface.STS
{
public class STSValues
{
public const string x509v3Value = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
public const string base64BinaryValue = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
public const string issueValue = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue";
public const string samlv2Value = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0";
public const string finalActionValue = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal";
public const string signatureMethodRSAValue = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
public const string signatureMethodDSAValue = "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
public const string digestMethodSHA1Value = "http://www.w3.org/2000/09/xmldsig#sha1";
public const string encryptedKeyValue = "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey";
public const string soapActionValue = "\"http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue\"";
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Xml;
namespace Kreta.EESZTInterface.STS
{
public class SamlAssertion
{
public const string LocalName = "Assertion";
public string Id { get; }
public string Issuer { get; }
public string UserId { get; }
public string UserName { get; }
public DateTime NotBefore { get; }
public DateTime NotOnOrAfter { get; }
public XmlElement SamlAssertionElement { get; }
public string Original { get; }
public SamlAssertion(string content)
{
Original = content;
var xDoc = new XmlDocument();
xDoc.LoadXml(content);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);
nsmgr.AddNamespace("saml", Namespaces.samlNs);
SamlAssertionElement = xDoc.DocumentElement;
Id = SamlAssertionElement.Attributes["ID"].Value;
Issuer = SamlAssertionElement.SelectSingleNode("descendant::saml:Issuer", nsmgr).InnerText;
UserId = SamlAssertionElement.SelectSingleNode("descendant::saml:NameID", nsmgr).InnerText;
UserName = SamlAssertionElement.SelectSingleNode("descendant::saml:Attribute[@Name=\"displayName\"]", nsmgr).InnerText;
var authStatementNode = SamlAssertionElement.SelectSingleNode("descendant::saml:Conditions", nsmgr);
NotBefore = DateTime.Parse(authStatementNode.Attributes["NotBefore"].Value).ToUniversalTime();
NotOnOrAfter = DateTime.Parse(authStatementNode.Attributes["NotOnOrAfter"].Value).ToUniversalTime();
}
}
}

View file

@ -0,0 +1,129 @@
using System;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.Xml.Serialization;
using Kreta.EESZTInterface.STS.Saml20;
using Kreta.Resources;
namespace Kreta.EESZTInterface.STS
{
public class SamlRequest
{
private readonly X509Certificate2 sslCert;
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public SamlRequest(X509Certificate2 sslCerrtificate)
{
sslCert = sslCerrtificate;
}
public string GetX509Saml(string interfaceUrl, X509Certificate2 stsCert, X509Certificate2 userCert)
{
var rst = CreateSoap.CreateX509Soap(stsCert, userCert);
rst = DoRequest.GetSoapSamlResponse($"{interfaceUrl}/STS_x509", sslCert, rst);
rst = DecryptFromRSTResponse(rst, stsCert, userCert);
return XmlToString(GetSamlFromRSTR(rst));
}
private string XmlToString(XmlDocument xmlDoc)
{
if (xmlDoc.FirstChild is XmlDeclaration)
{
xmlDoc.RemoveChild(xmlDoc.FirstChild);
}
return xmlDoc.OuterXml;
}
private XmlDocument GetSamlFromRSTR(XmlDocument rstResponse)
{
var actionElement = XmlHelper.GetElement("Action", Namespaces.addressingNs, rstResponse.DocumentElement);
if (!actionElement.InnerText.ToLower().Equals(STSValues.finalActionValue.ToLower()))
throw new Exception(EESZTInterfaceResource.NemMegfeleloActionErtek);
var deserializer = new XmlSerializer(typeof(AssertionType));
AssertionType assetion;
var body = XmlHelper.GetElement("Body", Namespaces.soap12Ns, rstResponse.DocumentElement);
var assertionElement = XmlHelper.GetElement("Assertion", Namespaces.samlNs, body);
if (assertionElement == null)
throw new Exception(EESZTInterfaceResource.AssertionElementNemTalalhato);
var saml = new XmlDocument
{
PreserveWhitespace = true
};
saml.LoadXml(assertionElement.OuterXml);
using (TextReader xmlreader = new StringReader(assertionElement.OuterXml))
{
try
{
assetion = (AssertionType)deserializer.Deserialize(xmlreader);
}
catch (Exception ex)
{
throw new Exception(EESZTInterfaceResource.AssertionElementNemMegfelelo, ex);
}
}
X509DataType x509dt;
X509Certificate2 samlCert = null;
foreach (var item in assetion.Signature.KeyInfo.Items)
{
if (item.GetType().Equals(typeof(X509DataType)))
{
x509dt = (X509DataType)item;
for (int i1 = 0; i1 < x509dt.ItemsElementName.Length; i1++)
{
if (x509dt.ItemsElementName[i1].Equals(ItemsChoiceType.X509Certificate))
{
samlCert = new X509Certificate2((byte[])x509dt.Items[i1]);
break;
}
}
}
if (samlCert != null)
{
break;
}
}
if (samlCert == null)
throw new Exception(EESZTInterfaceResource.SamlTanusitvanyNemTalalhato);
var samlXml = new XmlDocument
{
PreserveWhitespace = true
};
samlXml.LoadXml(assertionElement.OuterXml);
var valid = SignHelper.CheckSignature(samlXml, samlCert);
if (valid)
{
return saml;
}
throw new Exception(EESZTInterfaceResource.SamlAlairasaErvenytelen);
}
private XmlDocument DecryptFromRSTResponse(XmlDocument rstResponse, X509Certificate2 stsCert, X509Certificate2 userCert)
{
rstResponse = EncryptHelper.DecryptMessageAll(rstResponse, userCert);
if (SignHelper.CheckSignature(rstResponse, stsCert))
{
return rstResponse;
}
throw new Exception(EESZTInterfaceResource.RSTRalairasaErvenytelen);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,81 @@
using System;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;
namespace Kreta.EESZTInterface.STS
{
class SignHelper
{
public static XmlDocument SignMessage(XmlDocument mySoap, X509Certificate2 cert, string IdBody, string IdTs, string idX509)
{
PrefixedSignedXML signedXml = new PrefixedSignedXML(mySoap);
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
signedXml.SigningKey = cert.GetRSAPrivateKey();
signedXml.Signature.Id = "SIG-" + Guid.NewGuid().ToString().Replace("-", "");
var kInfo = new KeyInfo();
kInfo.Id = "KI-" + Guid.NewGuid().ToString().Replace("-", "");
XmlElement securityTokenReference = mySoap.CreateElement("wsse", "SecurityTokenReference", Namespaces.wsseNs);
securityTokenReference.SetAttribute("Id", Namespaces.wsuNs, "STR-" + Guid.NewGuid().ToString().Replace("-", ""));
XmlElement reference = mySoap.CreateElement("wsse", "Reference", Namespaces.wsseNs);
reference.SetAttribute("ValueType", STSValues.x509v3Value);
reference.SetAttribute("URI", idX509);
securityTokenReference.AppendChild(reference);
KeyInfoNode kInfoNode = new KeyInfoNode();
kInfoNode.Value = securityTokenReference;
kInfo.AddClause(kInfoNode);
signedXml.Signature.KeyInfo = kInfo;
XmlDsigExcC14NTransform canMethod = (XmlDsigExcC14NTransform)signedXml.SignedInfo.CanonicalizationMethodObject;
canMethod.InclusiveNamespacesPrefixList = "ns soap";
Reference tRef = new Reference() { DigestMethod = STSValues.digestMethodSHA1Value };
tRef.Uri = IdBody;
XmlDsigExcC14NTransform c14n = new XmlDsigExcC14NTransform("ns");
tRef.AddTransform(c14n);
signedXml.AddReference(tRef);
tRef = new Reference() { DigestMethod = STSValues.digestMethodSHA1Value };
tRef.Uri = IdTs;
c14n = new XmlDsigExcC14NTransform("wsse ns soap");
tRef.AddTransform(c14n);
signedXml.AddReference(tRef);
tRef = new Reference() { DigestMethod = STSValues.digestMethodSHA1Value };
tRef.Uri = idX509;
c14n = new XmlDsigExcC14NTransform("");
tRef.AddTransform(c14n);
signedXml.AddReference(tRef);
signedXml.ComputeSignature();
var ret = signedXml.CheckSignature(cert, true);
var xmlDsig = signedXml.GetXml();
XmlElement SecElement = XmlHelper.GetElement(XmlHelper.SecurityElementName, Namespaces.wsseNs, mySoap.DocumentElement);
SecElement.InsertAfter(mySoap.ImportNode(xmlDsig, true), XmlHelper.GetElementId(mySoap, idX509.Replace("#", "")));
if (mySoap.FirstChild is XmlDeclaration)
{
mySoap.RemoveChild(mySoap.FirstChild);
}
return mySoap;
}
public static bool CheckSignature(XmlDocument mySoap, X509Certificate2 cert)
{
var signedXml = new PrefixedSignedXML(mySoap);
var nodeList = XmlHelper.GetElement(XmlHelper.SignatureElementName, Namespaces.dsNs, mySoap.DocumentElement);
signedXml.LoadXml(nodeList);
return signedXml.CheckSignature(cert, true);
}
}
}