Imported Upstream version 5.16.0.100

Former-commit-id: 38faa55fb9669e35e7d8448b15c25dc447f25767
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-08-07 15:19:03 +00:00
parent 0a9828183b
commit 7d7f676260
4419 changed files with 170950 additions and 90273 deletions

View File

@@ -364,7 +364,13 @@ namespace System.Security.Cryptography.Xml
public const string XmlDsigMinimalCanonicalizationUrl = "http://www.w3.org/2000/09/xmldsig#minimal";
public const string XmlDsigNamespaceUrl = "http://www.w3.org/2000/09/xmldsig#";
public const string XmlDsigRSASHA1Url = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
public const string XmlDsigRSASHA256Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
public const string XmlDsigRSASHA384Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
public const string XmlDsigRSASHA512Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";
public const string XmlDsigSHA1Url = "http://www.w3.org/2000/09/xmldsig#sha1";
public const string XmlDsigSHA256Url = "http://www.w3.org/2001/04/xmlenc#sha256";
public const string XmlDsigSHA384Url = "http://www.w3.org/2001/04/xmldsig-more#sha384";
public const string XmlDsigSHA512Url = "http://www.w3.org/2001/04/xmlenc#sha512";
public const string XmlDsigXPathTransformUrl = "http://www.w3.org/TR/1999/REC-xpath-19991116";
public const string XmlDsigXsltTransformUrl = "http://www.w3.org/TR/1999/REC-xslt-19991116";
public const string XmlLicenseTransformUrl = "urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform";

View File

@@ -0,0 +1,2 @@
# Type must be public in implementation for serialization to work but we don't want to expose it publicly in the contract as it isn't public on .NET Framework
TypesMustExist : Type 'System.Security.Cryptography.Xml.CryptoSignedXmlRecursionException' does not exist in the implementation but it does exist in the contract.

View File

@@ -73,7 +73,6 @@
<Compile Include="System\Security\Cryptography\Xml\TransformChain.cs" />
<Compile Include="System\Security\Cryptography\Xml\TransformInputType.cs" />
<Compile Include="System\Security\Cryptography\Xml\Utils.cs" />
<Compile Include="System\Security\Cryptography\Xml\X509IssuerSerial.cs" />
<Compile Include="System\Security\Cryptography\Xml\XmlDecryptionTransform.cs" />
<Compile Include="System\Security\Cryptography\Xml\XmlDsigBase64Transform.cs" />
<Compile Include="System\Security\Cryptography\Xml\XmlDsigC14NTransform.cs" />
@@ -106,6 +105,7 @@
<Reference Include="System.Security.Cryptography.Csp" />
<Reference Include="System.Security.Cryptography.Encoding" />
<Reference Include="System.Security.Cryptography.Primitives" />
<Reference Include="System.Security.Cryptography.Pkcs" />
<Reference Include="System.Security.Cryptography.X509Certificates" />
<Reference Include="System.Security.Permissions" />
<Reference Include="System.Text.Encoding.Extensions" />

View File

@@ -118,7 +118,7 @@ namespace System.Security.Cryptography.Xml
internal byte[] GetDigestedBytes(HashAlgorithm hash)
{
_c14nDoc.WriteHash(hash, DocPosition.BeforeRootElement, _ancMgr);
hash.TransformFinalBlock(new byte[0], 0, 0);
hash.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
byte[] res = (byte[])hash.Hash.Clone();
// reinitialize the hash so it is still usable after the call
hash.Initialize();

View File

@@ -74,7 +74,8 @@ namespace System.Security.Cryptography.Xml
throw new ArgumentNullException(nameof(value));
ReferenceType = value.LocalName;
Uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
string uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
Uri = uri ?? throw new CryptographicException(SR.Cryptography_Xml_UriRequired);
// Transforms
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);

View File

@@ -2,15 +2,21 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.Security.Cryptography.Xml
{
internal static class CryptoHelpers
{
[SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 needed for compat.")]
[SuppressMessage("Microsoft.Security", "CA5351", Justification = "HMACMD5 needed for compat.")]
public static object CreateFromName(string name)
private static readonly char[] _invalidChars = new char[] { ',', '`', '[', '*', '&' };
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 needed for compat.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "HMACMD5 needed for compat.")]
public static object CreateFromKnownName(string name)
{
switch (name)
{
@@ -73,7 +79,23 @@ namespace System.Security.Cryptography.Xml
return TripleDES.Create();
}
return CryptoConfig.CreateFromName(name);
return null;
}
public static T CreateFromName<T>(string name) where T : class
{
if (name == null || name.IndexOfAny(_invalidChars) >= 0)
{
return null;
}
try
{
return (CreateFromKnownName(name) ?? CryptoConfig.CreateFromName(name)) as T;
}
catch (Exception)
{
return null;
}
}
}
}

View File

@@ -20,7 +20,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
var item = (AsymmetricSignatureDeformatter)CryptoHelpers.CreateFromName(DeformatterAlgorithm);
var item = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(HashAlgorithm);
return item;
@@ -28,7 +28,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
var item = (AsymmetricSignatureFormatter)CryptoHelpers.CreateFromName(FormatterAlgorithm);
var item = (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(HashAlgorithm);
return item;

View File

@@ -112,7 +112,11 @@ namespace System.Security.Cryptography.Xml
throw new ArgumentNullException(nameof(value));
ReferenceType = value.LocalName;
Uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
string uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
if (uri == null)
throw new ArgumentNullException(SR.Cryptography_Xml_UriRequired);
Uri = uri;
// Transforms
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);

View File

@@ -197,21 +197,38 @@ namespace System.Security.Cryptography.Xml
if (cipherData.CipherReference.CipherValue != null)
return cipherData.CipherReference.CipherValue;
Stream decInputStream = null;
if (cipherData.CipherReference.Uri == null)
{
throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
}
// See if the CipherReference is a local URI
if (cipherData.CipherReference.Uri.Length == 0)
{
// self referenced Uri
string baseUri = (_document == null ? null : _document.BaseURI);
TransformChain tc = cipherData.CipherReference.TransformChain;
if (tc == null)
{
throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
}
decInputStream = tc.TransformToOctetStream(_document, _xmlResolver, baseUri);
}
else if (cipherData.CipherReference.Uri[0] == '#')
{
string idref = Utils.ExtractIdFromLocalUri(cipherData.CipherReference.Uri);
// Serialize
inputStream = new MemoryStream(_encoding.GetBytes(GetIdElement(_document, idref).OuterXml));
XmlElement idElem = GetIdElement(_document, idref);
if (idElem == null || idElem.OuterXml == null)
{
throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
}
inputStream = new MemoryStream(_encoding.GetBytes(idElem.OuterXml));
string baseUri = (_document == null ? null : _document.BaseURI);
TransformChain tc = cipherData.CipherReference.TransformChain;
if (tc == null)
{
throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
}
decInputStream = tc.TransformToOctetStream(inputStream, _xmlResolver, baseUri);
}
else
@@ -361,7 +378,11 @@ namespace System.Security.Cryptography.Xml
if (key == null)
throw new CryptographicException(SR.Cryptography_Xml_MissingDecryptionKey);
SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoHelpers.CreateFromName(symmetricAlgorithmUri);
SymmetricAlgorithm symAlg = CryptoHelpers.CreateFromName<SymmetricAlgorithm>(symmetricAlgorithmUri);
if (symAlg == null)
{
throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
}
symAlg.Key = key;
return symAlg;
}
@@ -394,6 +415,10 @@ namespace System.Security.Cryptography.Xml
object kek = _keyNameMapping[keyName];
if (kek != null)
{
if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null)
{
throw new 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 SymmetricAlgorithm)
return EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (SymmetricAlgorithm)kek);
@@ -414,6 +439,10 @@ namespace System.Security.Cryptography.Xml
{
if (privateKey != null)
{
if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null)
{
throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
}
fOAEP = (encryptedKey.EncryptionMethod != null && encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl);
return EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKey, fOAEP);
}
@@ -456,7 +485,16 @@ namespace System.Security.Cryptography.Xml
if (encryptionKey != null)
{
// this is a symmetric algorithm for sure
SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoHelpers.CreateFromName(encryptedKey.EncryptionMethod.KeyAlgorithm);
SymmetricAlgorithm symAlg = CryptoHelpers.CreateFromName<SymmetricAlgorithm>(encryptedKey.EncryptionMethod.KeyAlgorithm);
if (symAlg == null)
{
throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
}
symAlg.Key = encryptionKey;
if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null)
{
throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
}
symAlg.Key = encryptionKey;
return EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, symAlg);
}

View File

@@ -66,7 +66,7 @@ namespace System.Security.Cryptography.Xml
internal byte[] GetDigestedBytes(HashAlgorithm hash)
{
_c14nDoc.WriteHash(hash, DocPosition.BeforeRootElement, _ancMgr);
hash.TransformFinalBlock(new byte[0], 0, 0);
hash.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
byte[] res = (byte[])hash.Hash.Clone();
// reinitialize the hash so it is still usable after the call
hash.Initialize();

View File

@@ -71,6 +71,8 @@ namespace System.Security.Cryptography.Xml
XmlElement keyInfoElement = value;
_id = Utils.GetAttribute(keyInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl);
if (!Utils.VerifyAttributes(keyInfoElement, "Id"))
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo");
XmlNode child = keyInfoElement.FirstChild;
while (child != null)
@@ -83,6 +85,10 @@ namespace System.Security.Cryptography.Xml
// 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 CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo/KeyValue");
}
XmlNodeList nodeList2 = elem.ChildNodes;
foreach (XmlNode node2 in nodeList2)
{
@@ -94,7 +100,8 @@ namespace System.Security.Cryptography.Xml
}
}
}
KeyInfoClause keyInfoClause = (KeyInfoClause)CryptoHelpers.CreateFromName(kicString);
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();

View File

@@ -16,7 +16,7 @@ namespace System.Security.Cryptography.Xml
{
public class KeyInfoX509Data : KeyInfoClause
{
// An array of certificates representing the certificate chain
// An array of certificates representing the certificate chain
private ArrayList _certificates = null;
// An array of issuer serial structs
private ArrayList _issuerSerials = null;
@@ -167,7 +167,7 @@ namespace System.Security.Cryptography.Xml
if (_issuerSerials == null)
_issuerSerials = new ArrayList();
_issuerSerials.Add(new X509IssuerSerial(issuerName, h.ToString()));
_issuerSerials.Add(Utils.CreateX509IssuerSerial(issuerName, h.ToString()));
}
// When we load an X509Data from Xml, we know the serial number is in decimal representation.
@@ -175,7 +175,7 @@ namespace System.Security.Cryptography.Xml
{
if (_issuerSerials == null)
_issuerSerials = new ArrayList();
_issuerSerials.Add(new X509IssuerSerial(issuerName, serialNumber));
_issuerSerials.Add(Utils.CreateX509IssuerSerial(issuerName, serialNumber));
}
public byte[] CRL

View File

@@ -16,7 +16,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
var item = (AsymmetricSignatureDeformatter)CryptoHelpers.CreateFromName(DeformatterAlgorithm);
var item = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(DigestAlgorithm);
return item;
@@ -24,7 +24,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
var item = (AsymmetricSignatureFormatter)CryptoHelpers.CreateFromName(FormatterAlgorithm);
var item = (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(DigestAlgorithm);
return item;

View File

@@ -219,25 +219,52 @@ namespace System.Security.Cryptography.Xml
_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 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();
XmlElement transformsElement = value.SelectSingleNode("ds:Transforms", nsm) as XmlElement;
if (transformsElement != null)
XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm);
if (transformsNodes != null && transformsNodes.Count != 0)
{
if (transformsNodes.Count > 1)
{
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms");
}
hasTransforms = true;
XmlElement transformsElement = transformsNodes[0] as XmlElement;
if (!Utils.VerifyAttributes(transformsElement, (string[])null))
{
throw new 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 CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms");
}
if (transformNodes.Count > Utils.MaxTransformsPerReference)
{
throw new 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);
Transform transform = CryptoHelpers.CreateFromName(algorithm) as Transform;
if (transform == null)
if (algorithm == null || !Utils.VerifyAttributes(transformElement, "Algorithm"))
{
throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
}
Transform transform = CryptoHelpers.CreateFromName<Transform>(algorithm);
if (transform == null)
{
throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
}
AddTransform(transform);
// let the transform read the children of the transformElement for data
transform.LoadInnerXml(transformElement.ChildNodes);
@@ -267,16 +294,27 @@ namespace System.Security.Cryptography.Xml
}
// DigestMethod
XmlElement digestMethodElement = value.SelectSingleNode("ds:DigestMethod", nsm) as XmlElement;
if (digestMethodElement == null)
XmlNodeList digestMethodNodes = value.SelectNodes("ds:DigestMethod", nsm);
if (digestMethodNodes == null || digestMethodNodes.Count == 0 || digestMethodNodes.Count > 1)
throw new 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 CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod");
// DigestValue
XmlElement digestValueElement = value.SelectSingleNode("ds:DigestValue", nsm) as XmlElement;
if (digestValueElement == null)
XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm);
if (digestValueNodes == null || digestValueNodes.Count == 0 || digestValueNodes.Count > 1)
throw new 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 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 CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference");
// cache the Xml
_cachedXml = value;
@@ -304,7 +342,7 @@ namespace System.Security.Cryptography.Xml
{
// refList is a list of elements that might be targets of references
// Now's the time to create our hashing algorithm
_hashAlgorithm = CryptoHelpers.CreateFromName(_digestMethod) as HashAlgorithm;
_hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(_digestMethod);
if (_hashAlgorithm == null)
throw new CryptographicException(SR.Cryptography_Xml_CreateHashAlgorithmFailed);

View File

@@ -148,37 +148,53 @@ namespace System.Security.Cryptography.Xml
// Id attribute -- optional
_id = Utils.GetAttribute(signatureElement, "Id", SignedXml.XmlDsigNamespaceUrl);
if (!Utils.VerifyAttributes(signatureElement, "Id"))
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Signature");
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
int expectedChildNodes = 0;
// SignedInfo
XmlElement signedInfoElement = signatureElement.SelectSingleNode("ds:SignedInfo", nsm) as XmlElement;
if (signedInfoElement == null)
XmlNodeList signedInfoNodes = signatureElement.SelectNodes("ds:SignedInfo", nsm);
if (signedInfoNodes == null || signedInfoNodes.Count == 0 || signedInfoNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo");
XmlElement signedInfoElement = signedInfoNodes[0] as XmlElement;
expectedChildNodes += signedInfoNodes.Count;
SignedInfo = new SignedInfo();
SignedInfo.LoadXml(signedInfoElement);
// SignatureValue
XmlElement signatureValueElement = signatureElement.SelectSingleNode("ds:SignatureValue", nsm) as XmlElement;
if (signatureValueElement == null)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/SignatureValue");
XmlNodeList signatureValueNodes = signatureElement.SelectNodes("ds:SignatureValue", nsm);
if (signatureValueNodes == null || signatureValueNodes.Count == 0 || signatureValueNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignatureValue");
XmlElement signatureValueElement = signatureValueNodes[0] as XmlElement;
expectedChildNodes += signatureValueNodes.Count;
_signatureValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(signatureValueElement.InnerText));
_signatureValueId = Utils.GetAttribute(signatureValueElement, "Id", SignedXml.XmlDsigNamespaceUrl);
if (!Utils.VerifyAttributes(signatureValueElement, "Id"))
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignatureValue");
// KeyInfo - optional single element
XmlNodeList keyInfoNodes = signatureElement.SelectNodes("ds:KeyInfo", nsm);
_keyInfo = new KeyInfo();
if (keyInfoNodes != null)
{
if (keyInfoNodes.Count > 1)
{
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo");
}
foreach (XmlNode node in keyInfoNodes)
{
XmlElement keyInfoElement = node as XmlElement;
if (keyInfoElement != null)
_keyInfo.LoadXml(keyInfoElement);
}
expectedChildNodes += keyInfoNodes.Count;
}
// Object - zero or more elements allowed
XmlNodeList objectNodes = signatureElement.SelectNodes("ds:Object", nsm);
_embeddedObjects.Clear();
if (objectNodes != null)
@@ -193,6 +209,7 @@ namespace System.Security.Cryptography.Xml
_embeddedObjects.Add(dataObj);
}
}
expectedChildNodes += objectNodes.Count;
}
// Select all elements that have Id attributes
@@ -204,6 +221,11 @@ namespace System.Security.Cryptography.Xml
_referencedItems.Add(node);
}
}
// Verify that there aren't any extra nodes that aren't allowed
if (signatureElement.SelectNodes("*").Count != expectedChildNodes)
{
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Signature");
}
}
public void AddObject(DataObject dataObject)

View File

@@ -98,7 +98,7 @@ namespace System.Security.Cryptography.Xml
{
if (_canonicalizationMethodTransform == null)
{
_canonicalizationMethodTransform = CryptoHelpers.CreateFromName(CanonicalizationMethod) as Transform;
_canonicalizationMethodTransform = CryptoHelpers.CreateFromName<Transform>(CanonicalizationMethod);
if (_canonicalizationMethodTransform == null)
throw new CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_CreateTransformFailed, CanonicalizationMethod));
_canonicalizationMethodTransform.SignedXml = SignedXml;
@@ -213,24 +213,35 @@ namespace System.Security.Cryptography.Xml
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
int expectedChildNodes = 0;
// Id attribute -- optional
_id = Utils.GetAttribute(signedInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl);
if (!Utils.VerifyAttributes(signedInfoElement, "Id"))
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo");
// CanonicalizationMethod -- must be present
XmlElement canonicalizationMethodElement = signedInfoElement.SelectSingleNode("ds:CanonicalizationMethod", nsm) as XmlElement;
if (canonicalizationMethodElement == null)
XmlNodeList canonicalizationMethodNodes = signedInfoElement.SelectNodes("ds:CanonicalizationMethod", nsm);
if (canonicalizationMethodNodes == null || canonicalizationMethodNodes.Count == 0 || canonicalizationMethodNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/CanonicalizationMethod");
XmlElement canonicalizationMethodElement = canonicalizationMethodNodes.Item(0) as XmlElement;
expectedChildNodes += canonicalizationMethodNodes.Count;
_canonicalizationMethod = Utils.GetAttribute(canonicalizationMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
if (_canonicalizationMethod == null || !Utils.VerifyAttributes(canonicalizationMethodElement, "Algorithm"))
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/CanonicalizationMethod");
_canonicalizationMethodTransform = null;
if (canonicalizationMethodElement.ChildNodes.Count > 0)
CanonicalizationMethodObject.LoadInnerXml(canonicalizationMethodElement.ChildNodes);
// SignatureMethod -- must be present
XmlElement signatureMethodElement = signedInfoElement.SelectSingleNode("ds:SignatureMethod", nsm) as XmlElement;
if (signatureMethodElement == null)
XmlNodeList signatureMethodNodes = signedInfoElement.SelectNodes("ds:SignatureMethod", nsm);
if (signatureMethodNodes == null || signatureMethodNodes.Count == 0 || signatureMethodNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/SignatureMethod");
XmlElement signatureMethodElement = signatureMethodNodes.Item(0) as XmlElement;
expectedChildNodes += signatureMethodNodes.Count;
_signatureMethod = Utils.GetAttribute(signatureMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
if (_signatureMethod == null || !Utils.VerifyAttributes(signatureMethodElement, "Algorithm"))
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/SignatureMethod");
// Now get the output length if we are using a MAC algorithm
XmlElement signatureLengthElement = signatureMethodElement.SelectSingleNode("ds:HMACOutputLength", nsm) as XmlElement;
@@ -240,9 +251,14 @@ namespace System.Security.Cryptography.Xml
// flush out any reference that was there
_references.Clear();
// Reference - 0 or more
XmlNodeList referenceNodes = signedInfoElement.SelectNodes("ds:Reference", nsm);
if (referenceNodes != null)
{
if (referenceNodes.Count > Utils.MaxReferencesPerSignedInfo)
{
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/Reference");
}
foreach (XmlNode node in referenceNodes)
{
XmlElement referenceElement = node as XmlElement;
@@ -250,6 +266,12 @@ namespace System.Security.Cryptography.Xml
AddReference(reference);
reference.LoadXml(referenceElement);
}
expectedChildNodes += referenceNodes.Count;
// Verify that there aren't any extra nodes that aren't allowed
if (signedInfoElement.SelectNodes("*").Count != expectedChildNodes)
{
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo");
}
}
// Save away the cached value

View File

@@ -68,15 +68,15 @@ namespace System.Security.Cryptography.Xml
public const string XmlDsigRSASHA1Url = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
public const string XmlDsigHMACSHA1Url = "http://www.w3.org/2000/09/xmldsig#hmac-sha1";
internal const string XmlDsigSHA256Url = "http://www.w3.org/2001/04/xmlenc#sha256";
internal const string XmlDsigRSASHA256Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
public const string XmlDsigSHA256Url = "http://www.w3.org/2001/04/xmlenc#sha256";
public const string XmlDsigRSASHA256Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
// Yes, SHA384 is in the xmldsig-more namespace even though all the other SHA variants are in xmlenc. That's the standard.
internal const string XmlDsigSHA384Url = "http://www.w3.org/2001/04/xmldsig-more#sha384";
internal const string XmlDsigRSASHA384Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
public const string XmlDsigSHA384Url = "http://www.w3.org/2001/04/xmldsig-more#sha384";
public const string XmlDsigRSASHA384Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
internal const string XmlDsigSHA512Url = "http://www.w3.org/2001/04/xmlenc#sha512";
internal const string XmlDsigRSASHA512Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";
public const string XmlDsigSHA512Url = "http://www.w3.org/2001/04/xmlenc#sha512";
public const string XmlDsigRSASHA512Url = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";
public const string XmlDsigC14NTransformUrl = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
public const string XmlDsigC14NWithCommentsTransformUrl = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";
@@ -410,7 +410,7 @@ namespace System.Security.Cryptography.Xml
}
// See if there is a signature description class defined in the Config file
SignatureDescription signatureDescription = CryptoHelpers.CreateFromName(SignedInfo.SignatureMethod) as SignatureDescription;
SignatureDescription signatureDescription = CryptoHelpers.CreateFromName<SignatureDescription>(SignedInfo.SignatureMethod);
if (signatureDescription == null)
throw new CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated);
HashAlgorithm hashAlg = signatureDescription.CreateDigest();
@@ -653,7 +653,7 @@ namespace System.Security.Cryptography.Xml
}
// See if we're signed witn an HMAC algorithm
HMAC hmac = CryptoHelpers.CreateFromName(SignatureMethod) as HMAC;
HMAC hmac = CryptoHelpers.CreateFromName<HMAC>(SignatureMethod);
if (hmac == null)
{
// We aren't signed with an HMAC algorithm, so we cannot have a truncated HMAC
@@ -1017,7 +1017,7 @@ namespace System.Security.Cryptography.Xml
SignedXmlDebugLog.LogBeginCheckSignedInfo(this, m_signature.SignedInfo);
SignatureDescription signatureDescription = CryptoHelpers.CreateFromName(SignatureMethod) as SignatureDescription;
SignatureDescription signatureDescription = CryptoHelpers.CreateFromName<SignatureDescription>(SignatureMethod);
if (signatureDescription == null)
throw new CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated);

View File

@@ -698,6 +698,8 @@ namespace System.Security.Cryptography.Xml
if (VerboseLoggingEnabled)
{
HashAlgorithm hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(reference.DigestMethod);
string hashAlgorithmName = hashAlgorithm == null ? "null" : hashAlgorithm.GetType().Name;
string logMessage = string.Format(CultureInfo.InvariantCulture,
SR.Log_SigningReference,
GetObjectId(reference),
@@ -705,7 +707,7 @@ namespace System.Security.Cryptography.Xml
reference.Id,
reference.Type,
reference.DigestMethod,
CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name);
hashAlgorithmName);
WriteLine(signedXml,
TraceEventType.Verbose,
@@ -831,11 +833,13 @@ namespace System.Security.Cryptography.Xml
if (VerboseLoggingEnabled)
{
HashAlgorithm hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(reference.DigestMethod);
string hashAlgorithmName = hashAlgorithm == null ? "null" : hashAlgorithm.GetType().Name;
string logMessage = string.Format(CultureInfo.InvariantCulture,
SR.Log_ReferenceHash,
GetObjectId(reference),
reference.DigestMethod,
CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name,
hashAlgorithmName,
FormatBytes(actualHash),
FormatBytes(expectedHash));
@@ -1043,11 +1047,13 @@ namespace System.Security.Cryptography.Xml
if (InformationLoggingEnabled)
{
HashAlgorithm hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(reference.DigestMethod);
string hashAlgorithmName = hashAlgorithm == null ? "null" : hashAlgorithm.GetType().Name;
string logMessage = string.Format(CultureInfo.InvariantCulture,
SR.Log_SignedXmlRecursionLimit,
GetObjectId(reference),
reference.DigestMethod,
CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name);
hashAlgorithmName);
WriteLine(signedXml,
TraceEventType.Information,

View File

@@ -200,7 +200,7 @@ namespace System.Security.Cryptography.Xml
{
XmlElement transformElement = (XmlElement)transformNodes.Item(i);
string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
Transform transform = CryptoHelpers.CreateFromName(algorithm) as Transform;
Transform transform = CryptoHelpers.CreateFromName<Transform>(algorithm);
if (transform == null)
throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
// let the transform read the children of the transformElement for data

View File

@@ -81,6 +81,29 @@ namespace System.Security.Cryptography.Xml
return element.HasAttribute(localName) || element.HasAttribute(localName, namespaceURI);
}
internal static bool VerifyAttributes(XmlElement element, string expectedAttrName)
{
return VerifyAttributes(element, expectedAttrName == null ? null : new string[] { expectedAttrName });
}
internal static bool VerifyAttributes(XmlElement element, string[] expectedAttrNames)
{
foreach (XmlAttribute attr in element.Attributes)
{
// There are a few Xml Special Attributes that are always allowed on any node. Make sure we allow those here.
bool attrIsAllowed = attr.Name == "xmlns" || attr.Name.StartsWith("xmlns:") || attr.Name == "xml:space" || attr.Name == "xml:lang" || attr.Name == "xml:base";
int expectedInd = 0;
while (!attrIsAllowed && expectedAttrNames != null && expectedInd < expectedAttrNames.Length)
{
attrIsAllowed = attr.Name == expectedAttrNames[expectedInd];
expectedInd++;
}
if (!attrIsAllowed)
return false;
}
return true;
}
internal static bool IsNamespaceNode(XmlNode n)
{
return n.NodeType == XmlNodeType.Attribute && (n.Prefix.Equals("xmlns") || (n.Prefix.Length == 0 && n.LocalName.Equals("xmlns")));
@@ -309,7 +332,7 @@ namespace System.Security.Cryptography.Xml
// initialize the return value
discardComments = true;
// Deal with XPointer of type #xpointer(id("ID")). Other XPointer support isn't handled here and is anyway optional
// Deal with XPointer of type #xpointer(id("ID")). Other XPointer support isn't handled here and is anyway optional
if (idref.StartsWith("xpointer(id(", StringComparison.Ordinal))
{
int startId = idref.IndexOf("id(", StringComparison.Ordinal);
@@ -328,7 +351,7 @@ namespace System.Security.Cryptography.Xml
{
string idref = uri.Substring(1);
// Deal with XPointer of type #xpointer(id("ID")). Other XPointer support isn't handled here and is anyway optional
// Deal with XPointer of type #xpointer(id("ID")). Other XPointer support isn't handled here and is anyway optional
if (idref.StartsWith("xpointer(id(", StringComparison.Ordinal))
{
int startId = idref.IndexOf("id(", StringComparison.Ordinal);
@@ -356,9 +379,9 @@ namespace System.Security.Cryptography.Xml
}
}
// Writes one stream (starting from the current position) into
// an output stream, connecting them up and reading until
// hitting the end of the input stream.
// Writes one stream (starting from the current position) into
// an output stream, connecting them up and reading until
// hitting the end of the input stream.
// returns the number of bytes copied
internal static long Pump(Stream input, Stream output)
{
@@ -482,7 +505,7 @@ namespace System.Security.Cryptography.Xml
}
}
// This method gets the attributes that should be propagated
// This method gets the attributes that should be propagated
internal static CanonicalXmlNodeList GetPropagatedAttributes(XmlElement elem)
{
if (elem == null)
@@ -606,6 +629,21 @@ namespace System.Security.Cryptography.Xml
return index + 1;
}
// Mimic the behavior of the X509IssuerSerial constructor with null and empty checks
internal static X509IssuerSerial CreateX509IssuerSerial(string issuerName, string serialNumber)
{
if (issuerName == null || issuerName.Length == 0)
throw new ArgumentException(SR.Arg_EmptyOrNullString, nameof(issuerName));
if (serialNumber == null || serialNumber.Length == 0)
throw new ArgumentException(SR.Arg_EmptyOrNullString, nameof(serialNumber));
return new X509IssuerSerial()
{
IssuerName = issuerName,
SerialNumber = serialNumber
};
}
internal static X509Certificate2Collection BuildBagOfCerts(KeyInfoX509Data keyInfoX509Data, CertUsageType certUsageType)
{
X509Certificate2Collection collection = new X509Certificate2Collection();
@@ -620,7 +658,7 @@ namespace System.Security.Cryptography.Xml
collection.Add(certificate);
break;
case CertUsageType.Decryption:
decryptionIssuerSerials.Add(new X509IssuerSerial(certificate.IssuerName.Name, certificate.SerialNumber));
decryptionIssuerSerials.Add(CreateX509IssuerSerial(certificate.IssuerName.Name, certificate.SerialNumber));
break;
}
}
@@ -759,5 +797,8 @@ namespace System.Security.Cryptography.Xml
{
return (AsymmetricAlgorithm)certificate.GetRSAPublicKey();
}
internal const int MaxTransformsPerReference = 10;
internal const int MaxReferencesPerSignedInfo = 100;
}
}

Some files were not shown because too many files have changed in this diff Show More