Example #1
0
        /// <summary>
        /// Deserialize from the XML representation.
        /// </summary>
        /// <remarks>
        /// Based upon https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue.
        /// </remarks>
        /// <param name="value">
        /// An <see cref="XmlElement"/> containing the XML representation. This cannot be null.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value"/> cannot be null.
        /// </exception>
        /// <exception cref="CryptographicException">
        /// The XML has the incorrect schema or the DSA parameters are invalid.
        /// </exception>
        public override void LoadXml(XmlElement value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (value.Name != KeyValueElementName ||
                value.NamespaceURI != SignedXml.XmlDsigNamespaceUrl)
            {
                throw new CryptographicException(SR.Format(SR.WrongRootElement, KeyValueElementName, SignedXml.XmlDsigNamespaceUrl));
            }

            const string        xmlDsigNamespacePrefix = "dsig";
            XmlNamespaceManager xmlNamespaceManager    = new XmlNamespaceManager(value.OwnerDocument.NameTable);

            xmlNamespaceManager.AddNamespace(xmlDsigNamespacePrefix, SignedXml.XmlDsigNamespaceUrl);

            XmlNode dsaKeyValueElement = value.SelectSingleNode($"{xmlDsigNamespacePrefix}:{DSAKeyValueElementName}", xmlNamespaceManager);

            if (dsaKeyValueElement == null)
            {
                throw new CryptographicException(SR.Format(SR.MustContainChildElement, KeyValueElementName, DSAKeyValueElementName));
            }

            XmlNode yNode = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{YElementName}", xmlNamespaceManager);

            if (yNode == null)
            {
                throw new CryptographicException(SR.Format(SR.ElementMissing, YElementName));
            }

            XmlNode pNode = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{PElementName}", xmlNamespaceManager);
            XmlNode qNode = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{QElementName}", xmlNamespaceManager);

            if ((pNode == null && qNode != null) || (pNode != null && qNode == null))
            {
                throw new CryptographicException(SR.Format(SR.ElementCombinationMissing, PElementName, QElementName));
            }


            XmlNode gNode = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{GElementName}", xmlNamespaceManager);
            XmlNode jNode = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{JElementName}", xmlNamespaceManager);

            XmlNode seedNode        = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{SeedElementName}", xmlNamespaceManager);
            XmlNode pgenCounterNode = dsaKeyValueElement.SelectSingleNode($"{xmlDsigNamespacePrefix}:{PgenCounterElementName}", xmlNamespaceManager);

            if ((seedNode == null && pgenCounterNode != null) || (seedNode != null && pgenCounterNode == null))
            {
                throw new CryptographicException(SR.Format(SR.ElementCombinationMissing, SeedElementName, PgenCounterElementName));
            }

            try
            {
                Key.ImportParameters(new DSAParameters
                {
                    P       = (pNode != null) ? Convert.FromBase64String(pNode.InnerText) : null,
                    Q       = (qNode != null) ? Convert.FromBase64String(qNode.InnerText) : null,
                    G       = (gNode != null) ? Convert.FromBase64String(gNode.InnerText) : null,
                    Y       = Convert.FromBase64String(yNode.InnerText),
                    J       = (jNode != null) ? Convert.FromBase64String(jNode.InnerText) : null,
                    Seed    = (seedNode != null) ? Convert.FromBase64String(seedNode.InnerText) : null,
                    Counter = (pgenCounterNode != null) ? Utils.ConvertByteArrayToInt(Convert.FromBase64String(pgenCounterNode.InnerText)) : 0
                });
            }
            catch (Exception ex)
            {
                throw new CryptographicException($"An error occurred parsing the key components", ex);
            }
        }