// The goal behind this method is to pump the input stream through the transforms and get back something that // can be hashed internal Stream TransformToOctetStream(Object inputObject, Type inputType, XmlResolver resolver, string strBaseUri) { Object currentInput = inputObject; foreach (Object obj in m_transforms) { Transform transform = obj as Transform; if (transform.AcceptsType(currentInput.GetType())) { //in this case, no translation necessary, pump it through transform.Resolver = resolver; transform.BaseURI = strBaseUri; transform.LoadInput(currentInput); currentInput = transform.GetOutput(); } else { // We need translation // For now, we just know about Stream->{XmlNodeList,XmlDocument} and {XmlNodeList,XmlDocument}->Stream if (currentInput is Stream) { if (transform.AcceptsType(typeof(XmlDocument))) { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; XmlValidatingReader valReader = SignedXml.PreProcessStreamInput((Stream)currentInput, resolver, strBaseUri); doc.Load(valReader); transform.LoadInput(doc); currentInput = transform.GetOutput(); continue; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } if (currentInput is XmlNodeList) { if (transform.AcceptsType(typeof(Stream))) { CanonicalXml c14n = new CanonicalXml((XmlNodeList)currentInput, false); MemoryStream ms = new MemoryStream(c14n.GetBytes()); transform.LoadInput((Stream)ms); currentInput = transform.GetOutput(); continue; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } if (currentInput is XmlDocument) { if (transform.AcceptsType(typeof(Stream))) { CanonicalXml c14n = new CanonicalXml((XmlDocument)currentInput); MemoryStream ms = new MemoryStream(c14n.GetBytes()); transform.LoadInput((Stream)ms); currentInput = transform.GetOutput(); continue; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); } } // Final processing, either we already have a stream or have to canonicalize if (currentInput is Stream) { return(currentInput as Stream); } if (currentInput is XmlNodeList) { CanonicalXml c14n = new CanonicalXml((XmlNodeList)currentInput, false); MemoryStream ms = new MemoryStream(c14n.GetBytes()); return(ms); } if (currentInput is XmlDocument) { CanonicalXml c14n = new CanonicalXml((XmlDocument)currentInput); MemoryStream ms = new MemoryStream(c14n.GetBytes()); return(ms); } throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_TransformIncorrectInputType")); }
/// <summary> /// Log that an X509 chain is being built for a certificate /// </summary> /// <param name="signedXml">SignedXml object building the chain</param> /// <param name="chain">chain built for the certificate</param> /// <param name="certificate">certificate having the chain built for it</param> internal static void LogVerifyX509Chain(SignedXml signedXml, X509Chain chain, X509Certificate certificate) { Debug.Assert(signedXml != null, "signedXml != null"); Debug.Assert(certificate != null, "certificate != null"); Debug.Assert(chain != null, "chain != null"); if (InformationLoggingEnabled) { string buildMessage = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_BuildX509Chain"), GetKeyName(certificate)); WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.X509Verification, buildMessage); } if (VerboseLoggingEnabled) { // Dump out the flags and other miscelanious information used for building string revocationMode = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_RevocationMode"), chain.ChainPolicy.RevocationFlag); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationMode); string revocationFlag = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_RevocationFlag"), chain.ChainPolicy.RevocationFlag); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationFlag); string verificationFlags = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_VerificationFlag"), chain.ChainPolicy.VerificationFlags); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationFlags); string verificationTime = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_VerificationTime"), chain.ChainPolicy.VerificationTime); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationTime); string urlTimeout = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_UrlTimeout"), chain.ChainPolicy.UrlRetrievalTimeout); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, urlTimeout); } // If there were any errors in the chain, make sure to dump those out if (InformationLoggingEnabled) { foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status != X509ChainStatusFlags.NoError) { string logMessage = String.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_X509ChainError"), status.Status, status.StatusInformation); WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.X509Verification, logMessage); } } } // Finally, dump out the chain itself if (VerboseLoggingEnabled) { StringBuilder chainElements = new StringBuilder(); chainElements.Append(SecurityResources.GetResourceString("Log_CertificateChain")); foreach (X509ChainElement element in chain.ChainElements) { chainElements.AppendFormat(CultureInfo.InvariantCulture, " {0}", GetKeyName(element.Certificate)); } WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, chainElements.ToString()); } }
public void ComputeSignature(KeyedHashAlgorithm macAlg) { if (macAlg == null) { throw new ArgumentNullException("macAlg"); } HMAC hash = macAlg as HMAC; if (hash == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_SignatureMethodKeyMismatch")); } int signatureLength; if (m_signature.SignedInfo.SignatureLength == null) { signatureLength = hash.HashSize; } else { signatureLength = Convert.ToInt32(m_signature.SignedInfo.SignatureLength, null); } // signatureLength should be less than hash size if (signatureLength < 0 || signatureLength > hash.HashSize) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength")); } if (signatureLength % 8 != 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength2")); } BuildDigestedReferences(); switch (hash.HashName) { case "SHA1": SignedInfo.SignatureMethod = SignedXml.XmlDsigHMACSHA1Url; break; case "SHA256": SignedInfo.SignatureMethod = SignedXml.XmlDsigMoreHMACSHA256Url; break; case "SHA384": SignedInfo.SignatureMethod = SignedXml.XmlDsigMoreHMACSHA384Url; break; case "SHA512": SignedInfo.SignatureMethod = SignedXml.XmlDsigMoreHMACSHA512Url; break; case "MD5": SignedInfo.SignatureMethod = SignedXml.XmlDsigMoreHMACMD5Url; break; case "RIPEMD160": SignedInfo.SignatureMethod = SignedXml.XmlDsigMoreHMACRIPEMD160Url; break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_SignatureMethodKeyMismatch")); } byte[] hashValue = GetC14NDigest(hash); SignedXmlDebugLog.LogSigning(this, hash); m_signature.SignatureValue = new byte[signatureLength / 8]; Buffer.BlockCopy(hashValue, 0, m_signature.SignatureValue, 0, signatureLength / 8); }
private void DecryptEncryptedGrants(XmlNodeList encryptedGrantList, IRelDecryptor decryptor) { XmlElement encryptionMethod = null; XmlElement keyInfo = null; XmlElement cipherData = null; EncryptionMethod encryptionMethodObj = null; KeyInfo keyInfoObj = null; CipherData cipherDataObj = null; for (int i = 0, count = encryptedGrantList.Count; i < count; i++) { encryptionMethod = encryptedGrantList[i].SelectSingleNode("//r:encryptedGrant/enc:EncryptionMethod", _namespaceManager) as XmlElement; keyInfo = encryptedGrantList[i].SelectSingleNode("//r:encryptedGrant/dsig:KeyInfo", _namespaceManager) as XmlElement; cipherData = encryptedGrantList[i].SelectSingleNode("//r:encryptedGrant/enc:CipherData", _namespaceManager) as XmlElement; if ((encryptionMethod != null) && (keyInfo != null) && (cipherData != null)) { encryptionMethodObj = new EncryptionMethod(); keyInfoObj = new KeyInfo(); cipherDataObj = new CipherData(); encryptionMethodObj.LoadXml(encryptionMethod); keyInfoObj.LoadXml(keyInfo); cipherDataObj.LoadXml(cipherData); MemoryStream toDecrypt = null; Stream decryptedContent = null; StreamReader streamReader = null; try { toDecrypt = new MemoryStream(cipherDataObj.CipherValue); decryptedContent = _relDecryptor.Decrypt(encryptionMethodObj, keyInfoObj, toDecrypt); if ((decryptedContent == null) || (decryptedContent.Length == 0)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_XrmlUnableToDecryptGrant")); } streamReader = new StreamReader(decryptedContent); string clearContent = streamReader.ReadToEnd(); encryptedGrantList[i].ParentNode.InnerXml = clearContent; } finally { if (toDecrypt != null) { toDecrypt.Close(); } if (decryptedContent != null) { decryptedContent.Close(); } if (streamReader != null) { streamReader.Close(); } } encryptionMethodObj = null; keyInfoObj = null; cipherDataObj = null; } encryptionMethod = null; keyInfo = null; cipherData = null; } }
public override void LoadInput(object obj) { // Check if the Context property is set before this transform is invoked. if (Context == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_XrmlMissingContext")); } _license = new XmlDocument(); _license.PreserveWhitespace = true; _namespaceManager = new XmlNamespaceManager(_license.NameTable); _namespaceManager.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl); _namespaceManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); _namespaceManager.AddNamespace("r", NamespaceUriCore); XmlElement currentIssuerContext = null; XmlElement currentLicenseContext = null; XmlNode signatureNode = null; // Get the nearest issuer node currentIssuerContext = Context.SelectSingleNode("ancestor-or-self::r:issuer[1]", _namespaceManager) as XmlElement; if (currentIssuerContext == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_XrmlMissingIssuer")); } signatureNode = currentIssuerContext.SelectSingleNode("descendant-or-self::dsig:Signature[1]", _namespaceManager) as XmlElement; if (signatureNode != null) { signatureNode.ParentNode.RemoveChild(signatureNode); } // Get the nearest license node currentLicenseContext = currentIssuerContext.SelectSingleNode("ancestor-or-self::r:license[1]", _namespaceManager) as XmlElement; if (currentLicenseContext == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_XrmlMissingLicence")); } XmlNodeList issuerList = currentLicenseContext.SelectNodes("descendant-or-self::r:license[1]/r:issuer", _namespaceManager); // Remove all issuer nodes except current for (int i = 0, count = issuerList.Count; i < count; i++) { if (issuerList[i] == currentIssuerContext) { continue; } if ((issuerList[i].LocalName == ElementIssuer) && (issuerList[i].NamespaceURI == NamespaceUriCore)) { issuerList[i].ParentNode.RemoveChild(issuerList[i]); } } XmlNodeList encryptedGrantList = currentLicenseContext.SelectNodes("/r:license/r:grant/r:encryptedGrant", _namespaceManager); if (encryptedGrantList.Count > 0) { if (_relDecryptor == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_XrmlMissingIRelDecryptor")); } DecryptEncryptedGrants(encryptedGrantList, _relDecryptor); } _license.InnerXml = currentLicenseContext.OuterXml; }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException("value"); } // SignedInfo XmlElement signedInfoElement = value; if (!signedInfoElement.LocalName.Equals("SignedInfo")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // Id attribute -- optional m_id = Utils.GetAttribute(signedInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl); // CanonicalizationMethod -- must be present XmlElement canonicalizationMethodElement = signedInfoElement.SelectSingleNode("ds:CanonicalizationMethod", nsm) as XmlElement; if (canonicalizationMethodElement == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/CanonicalizationMethod"); } m_canonicalizationMethod = Utils.GetAttribute(canonicalizationMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); m_canonicalizationMethodTransform = null; if (canonicalizationMethodElement.ChildNodes.Count > 0) { this.CanonicalizationMethodObject.LoadInnerXml(canonicalizationMethodElement.ChildNodes); } // SignatureMethod -- must be present XmlElement signatureMethodElement = signedInfoElement.SelectSingleNode("ds:SignatureMethod", nsm) as XmlElement; if (signatureMethodElement == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/SignatureMethod"); } m_signatureMethod = Utils.GetAttribute(signatureMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); // Now get the output length if we are using a MAC algorithm XmlElement signatureLengthElement = signatureMethodElement.SelectSingleNode("ds:HMACOutputLength", nsm) as XmlElement; if (signatureLengthElement != null) { m_signatureLength = signatureLengthElement.InnerXml; } // flush out any reference that was there m_references.Clear(); XmlNodeList referenceNodes = signedInfoElement.SelectNodes("ds:Reference", nsm); if (referenceNodes != null) { foreach (XmlNode node in referenceNodes) { XmlElement referenceElement = node as XmlElement; Reference reference = new Reference(); AddReference(reference); reference.LoadXml(referenceElement); } } // Save away the cached value m_cachedXml = signedInfoElement; }
public void LoadXml(XmlElement value) { // Make sure we don't get passed null if (value == null) { throw new ArgumentNullException("value"); } // Signature XmlElement signatureElement = value; if (!signatureElement.LocalName.Equals("Signature")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Signature"); } // Id attribute -- optional _id = Utils.GetAttribute(signatureElement, "Id", SignedXml.XmlDsigNamespaceUrl); XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // SignedInfo XmlElement signedInfoElement = signatureElement.SelectSingleNode("ds:SignedInfo", nsm) as XmlElement; if (signedInfoElement == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo"); } SignedInfo = new SignedInfo(); SignedInfo.LoadXml(signedInfoElement); // SignatureValue XmlElement signatureValueElement = signatureElement.SelectSingleNode("ds:SignatureValue", nsm) as XmlElement; if (signatureValueElement == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/SignatureValue"); } _signatureValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(signatureValueElement.InnerText)); _signatureValueId = Utils.GetAttribute(signatureValueElement, "Id", SignedXml.XmlDsigNamespaceUrl); XmlNodeList keyInfoNodes = signatureElement.SelectNodes("ds:KeyInfo", nsm); _keyInfo = new KeyInfo(); if (keyInfoNodes != null) { foreach (XmlNode node in keyInfoNodes) { XmlElement keyInfoElement = node as XmlElement; if (keyInfoElement != null) { _keyInfo.LoadXml(keyInfoElement); } } } XmlNodeList objectNodes = signatureElement.SelectNodes("ds:Object", nsm); _embeddedObjects.Clear(); if (objectNodes != null) { foreach (XmlNode node in objectNodes) { XmlElement objectElement = node as XmlElement; if (objectElement != null) { DataObject dataObj = new DataObject(); dataObj.LoadXml(objectElement); _embeddedObjects.Add(dataObj); } } } // Select all elements that have Id attributes XmlNodeList nodeList = signatureElement.SelectNodes("//*[@Id]", nsm); if (nodeList != null) { foreach (XmlNode node in nodeList) { _referencedItems.Add(node); } } }
internal static byte[] AESKeyWrapDecrypt(byte[] rgbKey, byte[] rgbEncryptedWrappedKeyData) { int N = (rgbEncryptedWrappedKeyData.Length >> 3) - 1; // The information wrapped need not actually be a key, but it needs to be a multiple of 64 bits if ((rgbEncryptedWrappedKeyData.Length % 8 != 0) || N <= 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); } byte[] rgbOutput = new byte[N << 3]; Aes aes = Aes.Create(); aes.Key = rgbKey; // Use ECB mode, no padding aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; using (aes) using (ICryptoTransform dec = aes.CreateDecryptor()) { // special case: only 1 block -- 8 bytes if (N == 1) { byte[] temp = dec.TransformFinalBlock(rgbEncryptedWrappedKeyData, 0, rgbEncryptedWrappedKeyData.Length); // checksum the key for (int index = 0; index < 8; index++) { if (temp[index] != s_rgbAES_KW_IV[index]) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); } } // rgbOutput is LSB(temp) Buffer.BlockCopy(temp, 8, rgbOutput, 0, 8); return(rgbOutput); } // second case: more than 1 block Int64 t = 0; // initialize the C_i's Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 8, rgbOutput, 0, rgbOutput.Length); byte[] rgbA = new byte[8]; byte[] rgbBlock = new byte[16]; Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 0, rgbA, 0, 8); for (int j = 5; j >= 0; j--) { for (int i = N; i >= 1; i--) { t = i + j * N; for (int k = 0; k < 8; k++) { byte tmp = (byte)((t >> (8 * (7 - k))) & 0xFF); rgbA[k] ^= tmp; } Buffer.BlockCopy(rgbA, 0, rgbBlock, 0, 8); Buffer.BlockCopy(rgbOutput, 8 * (i - 1), rgbBlock, 8, 8); byte[] rgbB = dec.TransformFinalBlock(rgbBlock, 0, 16); Buffer.BlockCopy(rgbB, 8, rgbOutput, 8 * (i - 1), 8); Buffer.BlockCopy(rgbB, 0, rgbA, 0, 8); } } // checksum the key for (int index = 0; index < 8; index++) { if (rgbA[index] != s_rgbAES_KW_IV[index]) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); } } return(rgbOutput); } }