///<summary>Creates an UpdateFile object describing an existing file on disk.</summary> ///<param name="basePath">The path to the base local directory containing the source files.</param> ///<param name="relativePath">The relative path to the source file on disk to describe.</param> ///<param name="remotePath">The path on the FTP server where the file will be uploaded, relative to the base Updates directory.</param> ///<param name="signers">A collection of RSA instances containing the private key(s) to sign the file.</param> ///<remarks>This method is called by the update publisher.</remarks> public static UpdateFile Create(string basePath, string relativePath, Uri remotePath, IEnumerable <RSACryptoServiceProvider> signers) { if (remotePath == null) { throw new ArgumentNullException("remotePath"); } if (signers == null || !signers.Any()) { throw new ArgumentNullException("signers"); } var filePath = Path.Combine(basePath, relativePath); var info = new FileInfo(filePath); var retVal = new UpdateFile { RelativePath = relativePath, RemoteUrl = remotePath, Length = info.Length, DateModifiedUtc = info.LastWriteTimeUtc }; using (var hasher = hasherCreator()) using (var stream = File.OpenRead(filePath)) retVal.hash = hasher.ComputeHash(stream); retVal.signatures = signers.Select(s => s.SignHash(retVal.hash, signatureAlgorithm)).ToList().AsReadOnly(); return(retVal); }
///<summary>Creates an UpdateFile object describing an existing file on disk.</summary> ///<param name="basePath">The path to the base local directory containing the source files.</param> ///<param name="relativePath">The relative path to the source file on disk to describe.</param> ///<param name="remotePath">The path on the FTP server where the file will be uploaded, relative to the base Updates directory.</param> ///<param name="signers">A collection of RSA instances containing the private key(s) to sign the file.</param> ///<remarks>This method is called by the update publisher.</remarks> public static UpdateFile Create(string basePath, string relativePath, Uri remotePath, IEnumerable<RSACryptoServiceProvider> signers) { if (remotePath == null) throw new ArgumentNullException("remotePath"); if (signers == null || !signers.Any()) throw new ArgumentNullException("signers"); var filePath = Path.Combine(basePath, relativePath); var info = new FileInfo(filePath); var retVal = new UpdateFile { RelativePath = relativePath, RemoteUrl = remotePath, Length = info.Length, DateModifiedUtc = info.LastWriteTimeUtc }; using (var hasher = hasherCreator()) using (var stream = File.OpenRead(filePath)) retVal.hash = hasher.ComputeHash(stream); retVal.signatures = signers.Select(s => s.SignHash(retVal.hash, signatureAlgorithm)).ToList().AsReadOnly(); return retVal; }
///<summary>Parses an UpdateFile object from an XML element.</summary> ///<param name="element">An XML element from an update manifest.</param> public static UpdateFile FromXml(XElement element) { if (element == null) { throw new ArgumentNullException("element"); } var retVal = new UpdateFile { RelativePath = element.Attribute("RelativePath").Value, Length = long.Parse(element.Attribute("Size").Value, CultureInfo.InvariantCulture), DateModifiedUtc = DateTime.ParseExact(element.Attribute("Timestamp").Value, "o", CultureInfo.InvariantCulture).ToUniversalTime(), RemoteUrl = new Uri(element.Attribute("Url").Value, UriKind.Relative), hash = Convert.FromBase64String(element.Element("Hash").Value), signatures = element.Elements("Signature").Select(e => Convert.FromBase64String(e.Value)).ToList().AsReadOnly() }; if (!retVal.signatures.Any(s => UpdateConfig.Standard.UpdateVerifier.VerifyHash(retVal.hash, signatureAlgorithm, s))) { throw new InvalidDataException("Bad signature for " + retVal.RelativePath); } return(retVal); }
///<summary>Parses an UpdateFile object from an XML element.</summary> ///<param name="element">An XML element from an update manifest.</param> public static UpdateFile FromXml(XElement element) { if (element == null) throw new ArgumentNullException("element"); var retVal = new UpdateFile { RelativePath = element.Attribute("RelativePath").Value, Length = long.Parse(element.Attribute("Size").Value, CultureInfo.InvariantCulture), DateModifiedUtc = DateTime.ParseExact(element.Attribute("Timestamp").Value, "o", CultureInfo.InvariantCulture).ToUniversalTime(), RemoteUrl = new Uri(element.Attribute("Url").Value, UriKind.Relative), hash = Convert.FromBase64String(element.Element("Hash").Value), signatures = element.Elements("Signature").Select(e => Convert.FromBase64String(e.Value)).ToList().AsReadOnly() }; if (!retVal.signatures.Any(s => UpdateConfig.Standard.UpdateVerifier.VerifyHash(retVal.hash, signatureAlgorithm, s))) throw new InvalidDataException("Bad signature for " + retVal.RelativePath); return retVal; }
public TreeFile(UpdateFile uf, ReadOnlyCollection<string> updateFiles, string newBasePath) { FullPath = uf.RelativePath.Replace('/', '\\'); Size = uf.Length; if (!updateFiles.Contains(Path.Combine(newBasePath, uf.RelativePath), StringComparer.OrdinalIgnoreCase)) State = (int)FileState.Deleted; else if (uf.Matches(newBasePath)) State = (int)FileState.Identical; else State = (int)FileState.Changed; }