/// <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); } }