Esempio n. 1
0
		public abstract void ImportParameters(RSAParameters parameters);
		public override void ImportParameters(RSAParameters parameters)
		{
			_rsa.Modulus = parameters.Modulus;
			_rsa.Exponent = parameters.Exponent;
			_rsa.P = parameters.P;
			_rsa.Q = parameters.Q;
			_rsa.DP = parameters.DP;
			_rsa.DQ = parameters.DQ;
			_rsa.InverseQ = parameters.InverseQ;
			_rsa.D = parameters.D;
			bool privateKey = false;
			if(parameters.D!=null && parameters.D.Length > 0)
				privateKey = true;
			_rsa.BuildRawKey(privateKey);
		}
		public static void VerifySig(XmlDocument sigDoc)
		{
			try
			{
				XmlElement envelope = sigDoc.DocumentElement;

				XmlElement securityElem = LameXpath.SelectSingleNode(sigDoc, Elem.Security);
				if(securityElem != null)
				{
					XmlAttribute mustUndAtt = securityElem.Attributes[Attrib.mustUnderstand,Ns.soap];
					if(mustUndAtt != null)
						mustUndAtt.Value = "0";
				}

				XmlElement sigElem = LameXpath.SelectSingleNode(sigDoc, Elem.Signature);
				if(sigElem == null)
					return;

				XmlElement sigValElem = LameXpath.SelectSingleNode(sigElem, Elem.SignatureValue);
				byte [] baSigVal = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(sigValElem.InnerText);

				bool comments = false;
				bool exclusive = true;
				SHA1CryptoServiceProvider shaCsp = new SHA1CryptoServiceProvider();

				XmlElement sigMethElem = LameXpath.SelectSingleNode(sigElem, Elem.SignatureMethod);
				string segMeth = sigMethElem.Attributes["Algorithm"].Value;

				XmlElement signedInfoElem = LameXpath.SelectSingleNode(sigElem, Elem.SignedInfo);
				XmlDocument xdSignedInfo = new XmlDocument();
				xdSignedInfo.LoadXml(signedInfoElem.OuterXml);
				XmlCanonicalizer xc = new XmlCanonicalizer(comments, exclusive);
				MemoryStream ms = (MemoryStream) xc.Canonicalize(xdSignedInfo);
				byte [] baMs = new byte[ms.Length];
				ms.Read(baMs, 0, baMs.Length);

				ArrayList keyInfoRefElem = LameXpath.SelectChildNodes(sigElem, Elem.SecurityTokenReference, Elem.Reference);
				XmlElement keyInfoRef = (XmlElement) keyInfoRefElem[0];
				string secTokUri = keyInfoRef.Attributes["URI"].Value;
				secTokUri = secTokUri.TrimStart(new char[]{'#'});
				XmlElement secTokElem = LameXpath.SelectSingleNode(secTokUri, sigDoc);
			
				if(secTokElem.LocalName == Elem.UsernameToken)
				{
					XmlElement nonce = LameXpath.SelectSingleNode(secTokElem, Elem.Nonce);
					XmlElement created = LameXpath.SelectSingleNode(secTokElem, Elem.Created);
					//DerivedKeyGenerator seems to be off by 1?
					//byte [] baKey = P_SHA1.DeriveKey(ClearPassword, StrKeyLabel, nonce.InnerText, created.InnerText, NumKeyBytes);
					byte [] baKey = P_SHA1.DeriveKey(SigObj.ClearPassword, StrKeyLabel, nonce.InnerText, created.InnerText, NumKeyBytes);
					HMACSHA1 hmacSha = new HMACSHA1(baKey);
					byte [] baSig = hmacSha.ComputeHash(baMs);
					OpenNETCF.Security.Cryptography.NativeMethods.Format.SameBytes(baSigVal, baSig);
				}
				else if(secTokElem.LocalName == Elem.BinarySecurityToken)
				{
					byte [] baCert = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(secTokElem.InnerText);
					X509Certificate cert = new X509Certificate(baCert); //pub key to verify sig.
					byte [] exponent;
					byte [] modulus;
					DecodeCertKey.GetPublicRsaParams(cert, out exponent, out modulus);
					RSAParameters rsaParam = new RSAParameters();
					rsaParam.Exponent = exponent;
					rsaParam.Modulus = modulus;
					RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider();
					rsaCsp.ImportParameters(rsaParam);
               
					byte [] baUnsigHash = shaCsp.ComputeHash(baMs);
					bool valid = rsaCsp.VerifyHash(baUnsigHash, "SHA", baSigVal);
					if(valid == false)
						throw new Exception("signature is not valid");
				}
				else if(secTokElem.LocalName == Elem.SecurityContextToken)
				{
					//TODO how to validate signature?
				}
				else
				{
					throw new Exception("only support Username, BinarySecurity, and SecurityContext Token signature");
				}

				//verify reference hashes
				string refdName = String.Empty;
				ArrayList refNodes = LameXpath.SelectChildNodes(sigDoc, Elem.SignedInfo, Elem.Reference);
				foreach(object oXn in refNodes)
				{
					XmlNode xn = (XmlNode) oXn;
					string uriId = xn.Attributes[Attrib.URI].Value;
					uriId = uriId.TrimStart(new char[]{'#'});
					XmlElement digValElem = LameXpath.SelectSingleNode(xn, Elem.DigestValue);
					byte [] baDigest = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(digValElem.InnerText);

					XmlElement refdElem = LameXpath.SelectSingleNode(uriId, sigDoc);
					XmlDocument xdRefdElem = new XmlDocument();
					refdName = refdElem.LocalName; //for debug visibility
					xdRefdElem.LoadXml(refdElem.OuterXml);
					//not reusable
					xc = new XmlCanonicalizer(comments, exclusive);
					//MemoryStream ms = (MemoryStream) xc.Canonicalize(refdElem);
					ms = (MemoryStream) xc.Canonicalize(xdRefdElem);
					baMs = new byte[ms.Length];
					ms.Read(baMs, 0, baMs.Length);
					byte [] baHash = shaCsp.ComputeHash(baMs);
					try
					{
						OpenNETCF.Security.Cryptography.NativeMethods.Format.SameBytes(baDigest, baHash);
					}
					catch(Exception ex)
					{
						throw new Exception(refdName + ":" + ex.Message, ex);
					}
				}
			}
			finally
			{
				//ClearPassword = null;
				SigObj = null;
			}
		}
		public override RSAParameters ExportParameters(bool includePrivateParameters)
		{
			RSAParameters parameters = new RSAParameters();
			parameters.Modulus = _rsa.Modulus;
			parameters.Exponent = _rsa.Exponent;
			if(includePrivateParameters == true)
			{
				parameters.P = _rsa.P;
				parameters.Q = _rsa.Q;
				parameters.DP = _rsa.DP;
				parameters.DQ = _rsa.DQ;
				parameters.InverseQ = _rsa.InverseQ;
				parameters.D = _rsa.D;
			}
			return parameters;
		}