public static bool CheckSignedInfo(AsymmetricKeyParameter key, SignedXml signedXml, Signature m_signature) { if (key == null) { throw new ArgumentNullException(nameof(key)); } SignedXmlDebugLog.LogBeginCheckSignedInfo(signedXml, m_signature.SignedInfo); ISigner signatureDescription = CryptoHelpers.CreateFromName <ISigner>(signedXml.SignatureMethod); if (signatureDescription == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated); } try { signatureDescription.Init(false, key); } catch (Exception) { return(false); } CheckSignatureManager.GetC14NDigest(new SignerHashWrapper(signatureDescription), signedXml); return(signatureDescription.VerifySignature(m_signature.GetSignatureValue())); }
/// <summary> /// Log the hash comparison when verifying a reference /// </summary> /// <param name="signedXml">SignedXml object verifying the signature</param> /// <param name="reference">reference being verified</param> /// <param name="actualHash">actual hash value of the reference</param> /// <param name="expectedHash">hash value the signature expected the reference to have</param> internal static void LogVerifyReferenceHash(SignedXml signedXml, Reference reference, byte[] actualHash, byte[] expectedHash) { Debug.Assert(signedXml != null, "signedXml != null"); Debug.Assert(reference != null, "reference != null"); Debug.Assert(actualHash != null, "actualHash != null"); Debug.Assert(expectedHash != null, "expectedHash != null"); if (VerboseLoggingEnabled) { string logMessage = string.Format(CultureInfo.InvariantCulture, SR.Log_ReferenceHash, GetObjectId(reference), reference.DigestMethod, CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name, FormatBytes(actualHash), FormatBytes(expectedHash)); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifyReference, logMessage); } }
// Validation function to see if the current signature is signed with a truncated HMAC - one which // has a signature length of fewer bits than the whole HMAC output. private bool DoesSignatureUseTruncatedHmac() { // If we're not using the SignatureLength property, then we're not truncating the signature length if (SignedInfo.SignatureLength == null) { return(false); } // See if we're signed witn an HMAC algorithm IMac hmac = CryptoHelpers.CreateFromName <IMac>(SignatureMethod); if (hmac == null) { // We aren't signed with an HMAC algorithm, so we cannot have a truncated HMAC return(false); } // Figure out how many bits the signature is using int actualSignatureSize = 0; if (!int.TryParse(SignedInfo.SignatureLength, out actualSignatureSize)) { // If the value wasn't a valid integer, then we'll conservatively reject it all together return(true); } // Make sure the full HMAC signature size is the same size that was specified in the XML // signature. If the actual signature size is not exactly the same as the full HMAC size, then // reject the signature. return(actualSignatureSize != hmac.GetMacSize()); }
internal void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); XmlNodeList transformNodes = value.SelectNodes("ds:Transform", nsm); if (transformNodes.Count == 0) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Transforms"); } _transforms.Clear(); for (int i = 0; i < transformNodes.Count; ++i) { XmlElement transformElement = (XmlElement)transformNodes.Item(i); string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); Transform transform = CryptoHelpers.CreateFromName <Transform>(algorithm); if (transform == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UnknownTransform); } // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); _transforms.Add(transform); } }
public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) { var item = (AsymmetricSignatureFormatter)CryptoHelpers.CreateFromName(FormatterAlgorithm); item.SetKey(key); item.SetHashAlgorithm(DigestAlgorithm); return(item); }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } XmlElement keyInfoElement = value; _id = Utils.GetAttribute(keyInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(keyInfoElement, "Id")) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo"); } XmlNode child = keyInfoElement.FirstChild; while (child != null) { XmlElement elem = child as XmlElement; if (elem != null) { // Create the right type of KeyInfoClause; we use a combination of the namespace and tag name (local name) string kicString = elem.NamespaceURI + " " + elem.LocalName; // Special-case handling for KeyValue -- we have to go one level deeper if (kicString == "http://www.w3.org/2000/09/xmldsig# KeyValue") { if (!Utils.VerifyAttributes(elem, (string[])null)) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo/KeyValue"); } XmlNodeList nodeList2 = elem.ChildNodes; foreach (XmlNode node2 in nodeList2) { XmlElement elem2 = node2 as XmlElement; if (elem2 != null) { kicString += "/" + elem2.LocalName; break; } } } KeyInfoClause keyInfoClause = CryptoHelpers.CreateFromName <KeyInfoClause>(kicString); // if we don't know what kind of KeyInfoClause we're looking at, use a generic KeyInfoNode: if (keyInfoClause == null) { keyInfoClause = new KeyInfoNode(); } // Ask the create clause to fill itself with the corresponding XML keyInfoClause.LoadXml(elem); // Add it to our list of KeyInfoClauses AddClause(keyInfoClause); } child = child.NextSibling; } }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } XmlElement keyInfoElement = value; _id = ElementUtils.GetAttribute(keyInfoElement, "Id", NS.XmlDsigNamespaceUrl); if (!ElementUtils.VerifyAttributes(keyInfoElement, "Id")) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo"); } XmlNode child = keyInfoElement.FirstChild; while (child != null) { XmlElement elem = child as XmlElement; if (elem != null) { string kicString = elem.NamespaceURI + " " + elem.LocalName; if (kicString == "http://www.w3.org/2000/09/xmldsig# KeyValue") { if (!ElementUtils.VerifyAttributes(elem, (string[])null)) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo/KeyValue"); } XmlNodeList nodeList2 = elem.ChildNodes; foreach (XmlNode node2 in nodeList2) { XmlElement elem2 = node2 as XmlElement; if (elem2 != null) { kicString += "/" + elem2.LocalName; break; } } } KeyInfoClause keyInfoClause = CryptoHelpers.CreateFromName <KeyInfoClause>(kicString); if (keyInfoClause == null) { keyInfoClause = new KeyInfoNode(); } keyInfoClause.LoadXml(elem); AddClause(keyInfoClause); } child = child.NextSibling; } }
public void ComputeSignature() { SignedXmlDebugLog.LogBeginSignatureComputation(this, _context); BuildDigestedReferences(); // Load the key AsymmetricKeyParameter key = SigningKey; if (key == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_LoadKeyFailed); } // Check the signature algorithm associated with the key so that we can accordingly set the signature method if (SignedInfo.SignatureMethod == null) { if (key is DsaKeyParameters) { SignedInfo.SignatureMethod = XmlDsigDSAUrl; } else if (key is RsaKeyParameters) { // Default to RSA-SHA1 if (SignedInfo.SignatureMethod == null) { SignedInfo.SignatureMethod = XmlDsigRSASHA256Url; } } else { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_CreatedKeyFailed); } } // See if there is a signature description class defined in the Config file ISigner signatureDescription = CryptoHelpers.CreateFromName(SignedInfo.SignatureMethod) as ISigner; if (signatureDescription == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated); } signatureDescription.Init(true, key); GetC14NDigest(signatureDescription); //SignedXmlDebugLog.LogSigning(this, key, signatureDescription, hashAlg, asymmetricSignatureFormatter); m_signature.SignatureValue = signatureDescription.GenerateSignature(); }
public void ComputeSignature() { SignedXmlDebugLog.LogBeginSignatureComputation(this, _context); ReferenceManager.BuildDigestedReferences(this); AsymmetricKeyParameter key = SigningKey; if (key == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_LoadKeyFailed); } if (SignedInfo.SignatureMethod == null) { if (key is DsaKeyParameters) { SignedInfo.SignatureMethod = XmlNameSpace.Url[NS.XmlDsigDSAUrl]; } else if (key is RsaKeyParameters) { SignedInfo.SignatureMethod = XmlNameSpace.Url[NS.XmlDsigRSASHA256Url]; } else { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_CreatedKeyFailed); } } ISigner signatureDescription = CryptoHelpers.CreateFromName <ISigner>(SignedInfo.SignatureMethod); if (signatureDescription == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated); } signatureDescription.Init(true, key); CheckSignatureManager.GetC14NDigest(new SignerHashWrapper(signatureDescription), this); SignedXmlDebugLog.LogSigning(this, key, signatureDescription); MSignature.SetSignatureValue(signatureDescription.GenerateSignature()); }
/// <summary> /// Write information when user hits the Signed XML recursion depth limit issue. /// This is helpful in debugging this kind of issues. /// </summary> /// <param name="signedXml">SignedXml object verifying the signature</param> /// <param name="reference">reference being verified</param> internal static void LogSignedXmlRecursionLimit(SignedXml signedXml, Reference reference) { Debug.Assert(signedXml != null, "signedXml != null"); Debug.Assert(reference != null, "reference != null"); if (InformationLoggingEnabled) { string logMessage = string.Format(CultureInfo.InvariantCulture, SR.Log_SignedXmlRecursionLimit, GetObjectId(reference), reference.DigestMethod, CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name); WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.VerifySignedInfo, logMessage); } }
private bool CheckSignedInfo(AsymmetricKeyParameter key) { if (key == null) { throw new ArgumentNullException("key"); } SignedXmlDebugLog.LogBeginCheckSignedInfo(this, m_signature.SignedInfo); ISigner signatureDescription = CryptoHelpers.CreateFromName(SignatureMethod) as ISigner; if (signatureDescription == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated); } // Let's see if the key corresponds with the SignatureMethod /*Type ta = Type.GetType(signatureDescription.KeyAlgorithm); * if (!IsKeyTheCorrectAlgorithm(key, ta)) * return false;*/ try { signatureDescription.Init(false, key); } catch (Exception) { return(false); } GetC14NDigest(signatureDescription); /*SignedXmlDebugLog.LogVerifySignedInfo(this, * key, * signatureDescription, * hashAlgorithm, * asymmetricSignatureDeformatter, * hashval, * m_signature.SignatureValue);*/ return(signatureDescription.VerifySignature(m_signature.SignatureValue)); }
/// <summary> /// Log the calculation of a hash value of a reference /// </summary> /// <param name="signedXml">SignedXml object driving the signature</param> /// <param name="reference">Reference being hashed</param> internal static void LogSigningReference(SignedXml signedXml, Reference reference) { Debug.Assert(signedXml != null, "signedXml != null"); Debug.Assert(reference != null, "reference != null"); if (VerboseLoggingEnabled) { string logMessage = string.Format(CultureInfo.InvariantCulture, SR.Log_SigningReference, GetObjectId(reference), reference.Uri, reference.Id, reference.Type, reference.DigestMethod, CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name); WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.SigningReference, logMessage); } }
private static bool DoesSignatureUseTruncatedHmac(SignedXml signedXml) { if (signedXml.SignedInfo.SignatureLength == null) { return(false); } IMac hmac = CryptoHelpers.CreateFromName <IMac>(signedXml.SignatureMethod); if (hmac == null) { return(false); } int actualSignatureSize = 0; if (!int.TryParse(signedXml.SignedInfo.SignatureLength, out actualSignatureSize)) { return(true); } return(actualSignatureSize != hmac.GetMacSize()); }
// Try to decrypt the EncryptedKey given the key mapping public virtual byte[] DecryptEncryptedKey(EncryptedKey encryptedKey, RsaKeyParameters privateKey = null) { if (encryptedKey == null) { throw new ArgumentNullException(nameof(encryptedKey)); } if (encryptedKey.KeyInfo == null) { return(null); } IEnumerator keyInfoEnum = encryptedKey.KeyInfo.GetEnumerator(); KeyInfoName kiName; KeyInfoX509Data kiX509Data; KeyInfoRetrievalMethod kiRetrievalMethod; KeyInfoEncryptedKey kiEncKey; EncryptedKey ek = null; bool fOAEP = false; while (keyInfoEnum.MoveNext()) { kiName = keyInfoEnum.Current as KeyInfoName; if (kiName != null) { // Get the decryption key from the key mapping string keyName = kiName.Value; object kek = _keyNameMapping[keyName]; if (kek != null) { if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } // kek is either a SymmetricAlgorithm or an RSA key, otherwise, we wouldn't be able to insert it in the hash table if (kek is KeyParameter kp) { return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, kp)); } else if (kek is ParametersWithIV piv) { return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, piv.Parameters as KeyParameter)); } // kek is an RSA key: get fOAEP from the algorithm, default to false fOAEP = (encryptedKey.EncryptionMethod != null && encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl); return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (RsaKeyParameters)kek, fOAEP)); } break; } kiX509Data = keyInfoEnum.Current as KeyInfoX509Data; if (kiX509Data != null) { IList <X509Certificate> collection = Utils.BuildBagOfCerts(kiX509Data, CertUsageType.Decryption); foreach (X509Certificate certificate in collection) { if (privateKey != null) { if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } fOAEP = (encryptedKey.EncryptionMethod != null && encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl); return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKey, fOAEP)); } } break; } kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod; if (kiRetrievalMethod != null) { string idref = Utils.ExtractIdFromLocalUri(kiRetrievalMethod.Uri); ek = new EncryptedKey(); ek.LoadXml(GetIdElement(_document, idref)); try { //Following checks if XML dsig processing is in loop and within the limit defined by machine // admin or developer. Once the recursion depth crosses the defined limit it will throw exception. _xmlDsigSearchDepthCounter++; if (IsOverXmlDsigRecursionLimit()) { //Throw exception once recursion limit is hit. throw new CryptoSignedXmlRecursionException(); } else { return(DecryptEncryptedKey(ek, privateKey)); } } finally { _xmlDsigSearchDepthCounter--; } } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; // recursively process EncryptedKey elements byte[] encryptionKey = DecryptEncryptedKey(ek, privateKey); if (encryptionKey != null) { // this is a symmetric algorithm for sure IBlockCipher blockSymAlg = CryptoHelpers.CreateFromName <IBlockCipher>(encryptedKey.EncryptionMethod.KeyAlgorithm); if (blockSymAlg == null) { IBufferedCipher bufferedSymAlg = CryptoHelpers.CreateFromName <IBufferedCipher>(encryptedKey.EncryptionMethod.KeyAlgorithm); if (bufferedSymAlg == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } } if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, new KeyParameter(encryptionKey))); } } } return(null); }
// What we want to do is pump the input throug the TransformChain and then // hash the output of the chain document is the document context for resolving relative references internal byte[] CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList) { // refList is a list of elements that might be targets of references // Now's the time to create our hashing algorithm IDigest digest = CryptoHelpers.CreateFromName <IDigest>(_digestMethod); if (digest == null) { IMac mac = CryptoHelpers.CreateFromName <IMac>(_digestMethod); if (mac == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_CreateHashAlgorithmFailed); } // For compatibility to corefx' HMAC implementation byte[] randomKey = Utils.GenerateRandomBlock(mac.GetMacSize()); mac.Init(new KeyParameter(randomKey)); _hashAlgorithm = new MacHashWrapper(mac); } else { _hashAlgorithm = new DigestHashWrapper(digest); } // Let's go get the target. string baseUri = (document == null ? System.Environment.CurrentDirectory + "\\" : document.BaseURI); Stream hashInputStream = null; WebResponse response = null; Stream inputStream = null; XmlResolver resolver = null; _hashval = null; try { switch (_refTargetType) { case ReferenceTargetType.Stream: // This is the easiest case. We already have a stream, so just pump it through the TransformChain resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream((Stream)_refTarget, resolver, baseUri); break; case ReferenceTargetType.UriReference: // Second-easiest case -- dereference the URI & pump through the TransformChain // handle the special cases where the URI is null (meaning whole doc) // or the URI is just a fragment (meaning a reference to an embedded Object) if (_uri == null) { // We need to create a DocumentNavigator out of the XmlElement resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); // In the case of a Uri-less reference, we will simply pass null to the transform chain. // The first transform in the chain is expected to know how to retrieve the data to hash. hashInputStream = TransformChain.TransformToOctetStream((Stream)null, resolver, baseUri); } else if (_uri.Length == 0) { // This is the self-referential case. First, check that we have a document context. // The Enveloped Signature does not discard comments as per spec; those will be omitted during the transform chain process if (document == null) { throw new System.Security.Cryptography.CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } // Normalize the containing document resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); XmlDocument docWithNoComments = Utils.DiscardComments(Utils.PreProcessDocumentInput(document, resolver, baseUri)); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else if (_uri[0] == '#') { // If we get here, then we are constructing a Reference to an embedded DataObject // referenced by an Id = attribute. Go find the relevant object bool discardComments = true; string idref = Utils.GetIdFromLocalUri(_uri, out discardComments); if (idref == "xpointer(/)") { // This is a self referencial case if (document == null) { throw new System.Security.Cryptography.CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } // We should not discard comments here!!! resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(Utils.PreProcessDocumentInput(document, resolver, baseUri), resolver, baseUri); break; } XmlElement elem = SignedXml.GetIdElement(document, idref); if (elem != null) { _namespaces = Utils.GetPropagatedAttributes(elem.ParentNode as XmlElement); } if (elem == null) { // Go throw the referenced items passed in if (refList != null) { foreach (XmlNode node in refList) { XmlElement tempElem = node as XmlElement; if ((tempElem != null) && (Utils.HasAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl)) && (Utils.GetAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl).Equals(idref))) { elem = tempElem; if (_signedXml._context != null) { _namespaces = Utils.GetPropagatedAttributes(_signedXml._context); } break; } } } } if (elem == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidReference); } XmlDocument normDocument = Utils.PreProcessElementInput(elem, resolver, baseUri); // Add the propagated attributes Utils.AddNamespaces(normDocument.DocumentElement, _namespaces); resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); if (discardComments) { // We should discard comments before going into the transform chain XmlDocument docWithNoComments = Utils.DiscardComments(normDocument); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else { // This is an XPointer reference, do not discard comments!!! hashInputStream = TransformChain.TransformToOctetStream(normDocument, resolver, baseUri); } } else { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri); } break; case ReferenceTargetType.XmlElement: // We need to create a DocumentNavigator out of the XmlElement resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(Utils.PreProcessElementInput((XmlElement)_refTarget, resolver, baseUri), resolver, baseUri); break; default: throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri); } // Compute the new hash value hashInputStream = SignedXmlDebugLog.LogReferenceData(this, hashInputStream); // Default the buffer size to 4K. byte[] buffer = new byte[4096]; int bytesRead; _hashAlgorithm.Reset(); while ((bytesRead = hashInputStream.Read(buffer, 0, buffer.Length)) > 0) { _hashAlgorithm.BlockUpdate(buffer, 0, bytesRead); } _hashval = new byte[_hashAlgorithm.GetHashSize()]; _hashAlgorithm.DoFinal(_hashval, 0); } finally { if (hashInputStream != null) { hashInputStream.Close(); } if (response != null) { response.Close(); } if (inputStream != null) { inputStream.Close(); } } return(_hashval); }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } _id = Utils.GetAttribute(value, "Id", SignedXml.XmlDsigNamespaceUrl); _uri = Utils.GetAttribute(value, "URI", SignedXml.XmlDsigNamespaceUrl); _type = Utils.GetAttribute(value, "Type", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(value, new string[] { "Id", "URI", "Type" })) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // Transforms bool hasTransforms = false; TransformChain = new TransformChain(); XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm); if (transformsNodes != null && transformsNodes.Count != 0) { if (transformsNodes.Count > 1) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } hasTransforms = true; XmlElement transformsElement = transformsNodes[0] as XmlElement; if (!Utils.VerifyAttributes(transformsElement, (string[])null)) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes != null) { if (transformNodes.Count != transformsElement.SelectNodes("*").Count) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } if (transformNodes.Count > Utils.MaxTransformsPerReference) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } foreach (XmlNode transformNode in transformNodes) { XmlElement transformElement = transformNode as XmlElement; string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if (algorithm == null || !Utils.VerifyAttributes(transformElement, "Algorithm")) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UnknownTransform); } Transform transform = CryptoHelpers.CreateFromName <Transform>(algorithm); if (transform == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UnknownTransform); } AddTransform(transform); // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); // Hack! this is done to get around the lack of here() function support in XPath if (transform is XmlDsigEnvelopedSignatureTransform) { // Walk back to the Signature tag. Find the nearest signature ancestor // Signature-->SignedInfo-->Reference-->Transforms-->Transform XmlNode signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); XmlNodeList signatureList = transformElement.SelectNodes("//ds:Signature", nsm); if (signatureList != null) { int position = 0; foreach (XmlNode node in signatureList) { position++; if (node == signatureTag) { ((XmlDsigEnvelopedSignatureTransform)transform).SignaturePosition = position; break; } } } } } } } // DigestMethod XmlNodeList digestMethodNodes = value.SelectNodes("ds:DigestMethod", nsm); if (digestMethodNodes == null || digestMethodNodes.Count == 0 || digestMethodNodes.Count > 1) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } XmlElement digestMethodElement = digestMethodNodes[0] as XmlElement; _digestMethod = Utils.GetAttribute(digestMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if (_digestMethod == null || !Utils.VerifyAttributes(digestMethodElement, "Algorithm")) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } // DigestValue XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm); if (digestValueNodes == null || digestValueNodes.Count == 0 || digestValueNodes.Count > 1) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } XmlElement digestValueElement = digestValueNodes[0] as XmlElement; _digestValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(digestValueElement.InnerText)); if (!Utils.VerifyAttributes(digestValueElement, (string[])null)) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } // Verify that there aren't any extra nodes that aren't allowed int expectedChildNodeCount = hasTransforms ? 3 : 2; if (value.SelectNodes("*").Count != expectedChildNodeCount) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference"); } // cache the Xml _cachedXml = value; }
// default behaviour is to look for keys defined by an EncryptedKey clause // either directly or through a KeyInfoRetrievalMethod, and key names in the key mapping public virtual SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri) { if (encryptedData == null) { throw new ArgumentNullException("encryptedData"); } if (encryptedData.KeyInfo == null) { return(null); } IEnumerator keyInfoEnum = encryptedData.KeyInfo.GetEnumerator(); KeyInfoRetrievalMethod kiRetrievalMethod; KeyInfoName kiName; KeyInfoEncryptedKey kiEncKey; EncryptedKey ek = null; while (keyInfoEnum.MoveNext()) { kiName = keyInfoEnum.Current as KeyInfoName; if (kiName != null) { // Get the decryption key from the key mapping string keyName = kiName.Value; if ((SymmetricAlgorithm)_keyNameMapping[keyName] != null) { return((SymmetricAlgorithm)_keyNameMapping[keyName]); } // try to get it from a CarriedKeyName XmlNamespaceManager nsm = new XmlNamespaceManager(_document.NameTable); nsm.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); XmlNodeList encryptedKeyList = _document.SelectNodes("//enc:EncryptedKey", nsm); if (encryptedKeyList != null) { foreach (XmlNode encryptedKeyNode in encryptedKeyList) { XmlElement encryptedKeyElement = encryptedKeyNode as XmlElement; EncryptedKey ek1 = new EncryptedKey(); ek1.LoadXml(encryptedKeyElement); if (ek1.CarriedKeyName == keyName && ek1.Recipient == Recipient) { ek = ek1; break; } } } break; } kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod; if (kiRetrievalMethod != null) { string idref = Utils.ExtractIdFromLocalUri(kiRetrievalMethod.Uri); ek = new EncryptedKey(); ek.LoadXml(GetIdElement(_document, idref)); break; } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; break; } } // if we have an EncryptedKey, decrypt to get the symmetric key if (ek != null) { // now process the EncryptedKey, loop recursively // If the Uri is not provided by the application, try to get it from the EncryptionMethod if (symmetricAlgorithmUri == null) { if (encryptedData.EncryptionMethod == null) { throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm; } byte[] key = DecryptEncryptedKey(ek); if (key == null) { throw new CryptographicException(SR.Cryptography_Xml_MissingDecryptionKey); } SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoHelpers.CreateFromName(symmetricAlgorithmUri); symAlg.Key = key; return(symAlg); } return(null); }
public void LoadXml(XmlElement value) { LoadXml1(value); XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", XmlNameSpace.Url[NS.XmlDsigNamespaceUrl]); bool hasTransforms = false; TransformChain = new TransformChain(); XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm); if (transformsNodes != null && transformsNodes.Count != 0) { if (transformsNodes.Count > 1) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } hasTransforms = true; XmlElement transformsElement = transformsNodes[0] as XmlElement; if (!ElementUtils.VerifyAttributes(transformsElement, (string[])null)) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes != null) { if (transformNodes.Count != transformsElement.SelectNodes("*").Count) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } if (transformNodes.Count > CryptoUtils.MaxTransformsPerReference) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } foreach (XmlNode transformNode in transformNodes) { XmlElement transformElement = transformNode as XmlElement; string algorithm = ElementUtils.GetAttribute(transformElement, "Algorithm", NS.XmlDsigNamespaceUrl); if (algorithm == null || !ElementUtils.VerifyAttributes(transformElement, "Algorithm")) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UnknownTransform); } Transform transform = CryptoHelpers.CreateFromName <Transform>(algorithm); if (transform == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UnknownTransform); } AddTransform(transform); transform.LoadInnerXml(transformElement.ChildNodes); if (transform is XmlDsigEnvelopedSignatureTransform) { XmlNode signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); XmlNodeList signatureList = transformElement.SelectNodes("//ds:Signature", nsm); if (signatureList != null) { int position = 0; foreach (XmlNode node in signatureList) { position++; if (node == signatureTag) { ((XmlDsigEnvelopedSignatureTransform)transform).SignaturePosition = position; break; } } } } } } } LoadXml2(value, nsm, hasTransforms); }
internal byte[] CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList) { IDigest digest = CryptoHelpers.CreateFromName <IDigest>(_digestMethod); if (digest == null) { IMac mac = CryptoHelpers.CreateFromName <IMac>(_digestMethod); if (mac == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_CreateHashAlgorithmFailed); } byte[] randomKey = CryptoUtils.GenerateRandomBlock(mac.GetMacSize()); mac.Init(new KeyParameter(randomKey)); _hashAlgorithm = new MacHashWrapper(mac); } else { _hashAlgorithm = new DigestHashWrapper(digest); } string baseUri = document == null ? Environment.CurrentDirectory + "\\" : document.BaseURI; Stream hashInputStream = null; WebResponse response = null; Stream inputStream = null; XmlResolver resolver = null; _hashval = null; try { switch (_refTargetType) { case ReferenceTargetType.Stream: resolver = (GetSignedXml().ResolverSet ? GetSignedXml()._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream((Stream)_refTarget, resolver, baseUri); break; case ReferenceTargetType.UriReference: if (_uri == null) { resolver = (GetSignedXml().ResolverSet ? GetSignedXml()._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream((Stream)null, resolver, baseUri); } else if (_uri.Length == 0) { if (document == null) { throw new System.Security.Cryptography.CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } resolver = (GetSignedXml().ResolverSet ? GetSignedXml()._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); XmlDocument docWithNoComments = StreamUtils.DiscardComments(StreamUtils.PreProcessDocumentInput(document, resolver, baseUri)); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else if (_uri[0] == '#') { bool discardComments = true; string idref = ParserUtils.GetIdFromLocalUri(_uri, out discardComments); if (idref == "xpointer(/)") { if (document == null) { throw new System.Security.Cryptography.CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } resolver = (GetSignedXml().ResolverSet ? GetSignedXml()._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(StreamUtils.PreProcessDocumentInput(document, resolver, baseUri), resolver, baseUri); break; } XmlElement elem = GetSignedXml().GetIdElement(document, idref); if (elem != null) { _namespaces = ElementUtils.GetPropagatedAttributes(elem.ParentNode as XmlElement); } if (elem == null && refList != null) { foreach (XmlNode node in refList) { XmlElement tempElem = node as XmlElement; if ((tempElem != null) && (ElementUtils.HasAttribute(tempElem, "Id", XmlNameSpace.Url[NS.XmlDsigNamespaceUrl])) && (ElementUtils.GetAttribute(tempElem, "Id", NS.XmlDsigNamespaceUrl).Equals(idref))) { elem = tempElem; if (_signedXml._context != null) { _namespaces = ElementUtils.GetPropagatedAttributes(_signedXml._context); } break; } } } if (elem == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidReference); } XmlDocument normDocument = StreamUtils.PreProcessElementInput(elem, resolver, baseUri); ElementUtils.AddNamespaces(normDocument.DocumentElement, _namespaces); resolver = (GetSignedXml().ResolverSet ? GetSignedXml()._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); if (discardComments) { XmlDocument docWithNoComments = StreamUtils.DiscardComments(normDocument); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else { hashInputStream = TransformChain.TransformToOctetStream(normDocument, resolver, baseUri); } } else { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri); } break; case ReferenceTargetType.XmlElement: resolver = (GetSignedXml().ResolverSet ? GetSignedXml()._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(StreamUtils.PreProcessElementInput((XmlElement)_refTarget, resolver, baseUri), resolver, baseUri); break; default: throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri); } hashInputStream = SignedXmlDebugLog.LogReferenceData(this, hashInputStream); byte[] buffer = new byte[4096]; int bytesRead; _hashAlgorithm.Reset(); while ((bytesRead = hashInputStream.Read(buffer, 0, buffer.Length)) > 0) { _hashAlgorithm.BlockUpdate(buffer, 0, bytesRead); } _hashval = new byte[_hashAlgorithm.GetHashSize()]; _hashAlgorithm.DoFinal(_hashval, 0); } finally { if (hashInputStream != null) { hashInputStream.Close(); } if (response != null) { response.Close(); } if (inputStream != null) { inputStream.Close(); } } return(_hashval); }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException("value"); } _id = Utils.GetAttribute(value, "Id", SignedXml.XmlDsigNamespaceUrl); _uri = Utils.GetAttribute(value, "URI", SignedXml.XmlDsigNamespaceUrl); _type = Utils.GetAttribute(value, "Type", SignedXml.XmlDsigNamespaceUrl); XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // Transforms TransformChain = new TransformChain(); XmlElement transformsElement = value.SelectSingleNode("ds:Transforms", nsm) as XmlElement; if (transformsElement != null) { XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes != null) { foreach (XmlNode transformNode in transformNodes) { XmlElement transformElement = transformNode as XmlElement; string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); Transform transform = CryptoHelpers.CreateFromName(algorithm) as Transform; if (transform == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_UnknownTransform); } AddTransform(transform); // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); // Hack! this is done to get around the lack of here() function support in XPath if (transform is XmlDsigEnvelopedSignatureTransform) { // Walk back to the Signature tag. Find the nearest signature ancestor // Signature-->SignedInfo-->Reference-->Transforms-->Transform XmlNode signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); XmlNodeList signatureList = transformElement.SelectNodes("//ds:Signature", nsm); if (signatureList != null) { int position = 0; foreach (XmlNode node in signatureList) { position++; if (node == signatureTag) { ((XmlDsigEnvelopedSignatureTransform)transform).SignaturePosition = position; break; } } } } } } } // DigestMethod XmlElement digestMethodElement = value.SelectSingleNode("ds:DigestMethod", nsm) as XmlElement; if (digestMethodElement == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } _digestMethod = Utils.GetAttribute(digestMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); // DigestValue XmlElement digestValueElement = value.SelectSingleNode("ds:DigestValue", nsm) as XmlElement; if (digestValueElement == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } _digestValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(digestValueElement.InnerText)); // cache the Xml _cachedXml = value; }
// default behaviour is to look for keys defined by an EncryptedKey clause // either directly or through a KeyInfoRetrievalMethod, and key names in the key mapping public virtual ICipherParameters GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri) { if (encryptedData == null) { throw new ArgumentNullException(nameof(encryptedData)); } if (encryptedData.KeyInfo == null) { return(null); } IEnumerator keyInfoEnum = encryptedData.KeyInfo.GetEnumerator(); KeyInfoRetrievalMethod kiRetrievalMethod; KeyInfoName kiName; KeyInfoEncryptedKey kiEncKey; EncryptedKey ek = null; while (keyInfoEnum.MoveNext()) { kiName = keyInfoEnum.Current as KeyInfoName; if (kiName != null) { // Get the decryption key from the key mapping string keyName = kiName.Value; if (_keyNameMapping[keyName] as ICipherParameters != null) { return((ICipherParameters)_keyNameMapping[keyName]); } // try to get it from a CarriedKeyName XmlNamespaceManager nsm = new XmlNamespaceManager(_document.NameTable); nsm.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); XmlNodeList encryptedKeyList = _document.SelectNodes("//enc:EncryptedKey", nsm); if (encryptedKeyList != null) { foreach (XmlNode encryptedKeyNode in encryptedKeyList) { XmlElement encryptedKeyElement = encryptedKeyNode as XmlElement; EncryptedKey ek1 = new EncryptedKey(); ek1.LoadXml(encryptedKeyElement); if (ek1.CarriedKeyName == keyName && ek1.Recipient == Recipient) { ek = ek1; break; } } } break; } kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod; if (kiRetrievalMethod != null) { string idref = Utils.ExtractIdFromLocalUri(kiRetrievalMethod.Uri); ek = new EncryptedKey(); ek.LoadXml(GetIdElement(_document, idref)); break; } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; break; } } // if we have an EncryptedKey, decrypt to get the symmetric key if (ek != null) { // now process the EncryptedKey, loop recursively // If the Uri is not provided by the application, try to get it from the EncryptionMethod if (symmetricAlgorithmUri == null) { if (encryptedData.EncryptionMethod == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm; } byte[] key = DecryptEncryptedKey(ek); if (key == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingDecryptionKey); } IBufferedCipher symAlg = CryptoHelpers.CreateFromName <IBufferedCipher>(symmetricAlgorithmUri); if (symAlg == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } KeyParameter keyParam; if (symAlg.AlgorithmName.IndexOf("DESede", StringComparison.OrdinalIgnoreCase) >= 0) { keyParam = new DesEdeParameters(key); } else if (symAlg.AlgorithmName.IndexOf("DES", StringComparison.OrdinalIgnoreCase) >= 0) { keyParam = new DesParameters(key); } else { keyParam = new KeyParameter(key); } return(keyParam); } return(null); }