public static (byte[] digest, Uri identifier) Digest(OpcPart part, HashAlgorithmName algorithmName)
 {
     using (var hashAlgorithm = HashAlgorithmTranslator.TranslateFromNameToxmlDSigUri(algorithmName, out var identifier))
     {
         using (var partStream = part.Open())
         {
             var digest = hashAlgorithm.ComputeHash(partStream);
             return(digest, identifier);
         }
     }
 }
Esempio n. 2
0
        public static (byte[] digest, Uri identifier) Digest(OpcPart part, HashAlgorithmName algorithmName)
        {
            var info = new HashAlgorithmInfo(algorithmName);

            using (var hashAlgorithm = info.Create())
            {
                using (var partStream = part.Open())
                {
                    var digest = hashAlgorithm.ComputeHash(partStream);
                    return(digest, info.XmlDSigIdentifier);
                }
            }
        }
 private static void PublishSignature(XmlDocument document, OpcPart signatureFile)
 {
     using (var copySignatureStream = signatureFile.Open())
     {
         copySignatureStream.SetLength(0L);
         using (var xmlWriter = new XmlTextWriter(copySignatureStream, System.Text.Encoding.UTF8))
         {
             //The .NET implementation of OPC used by Visual Studio does not tollerate "white space" nodes.
             xmlWriter.Formatting = Formatting.None;
             document.Save(xmlWriter);
         }
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Removes an existing part from the package, and its relationships.
        /// </summary>
        /// <param name="part">The part to remove from the package. Use <see cref="GetPart(Uri)"/> to obtain the part to remove.</param>
        /// <remarks>This does not validate or clean up other references to this part.</remarks>
        public void RemovePart(OpcPart part)
        {
            var relationshipUri   = part.Relationships.DocumentUri;
            var relationshipPath  = relationshipUri.ToPackagePath();
            var relationshipEntry = Archive.GetEntry(relationshipPath);

            relationshipEntry?.Delete();
            _partTracker.Remove(relationshipPath);

            var path = part.Uri.ToPackagePath();

            part.Entry.Delete();
            _partTracker.Remove(path);
        }
Esempio n. 5
0
        /// <summary>
        /// Gets a part by URI.
        /// </summary>
        /// <param name="partUri">A relative URI to the part.</param>
        /// <returns>An instance of <see cref="OpcPart"/>, or null if the part cannot be found.</returns>
        public OpcPart GetPart(Uri partUri)
        {
            var path = partUri.ToPackagePath();

            if (!_partTracker.TryGetValue(path, out OpcPart part))
            {
                var entry = Archive.GetEntry(path);
                if (entry == null)
                {
                    return(null);
                }
                part = new OpcPart(this, entry.FullName, entry, _mode);
                _partTracker.Add(path, part);
            }
            return(part);
        }
Esempio n. 6
0
        /// <summary>
        /// Gets all package-wide parts.
        /// </summary>
        /// <returns>An enumerable source of parts.</returns>
        public IEnumerable <OpcPart> GetParts()
        {
            foreach (var entry in Archive.Entries)
            {
                if (entry.FullName.Equals(CONTENT_TYPES_XML, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                if (!_partTracker.TryGetValue(entry.FullName, out OpcPart part))
                {
                    part = new OpcPart(this, entry.FullName, entry, _mode);
                    _partTracker.Add(entry.FullName, part);
                }
                yield return(part);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a new part.
        /// </summary>
        /// <param name="partUri">A relative URI where the part will exist in the package.</param>
        /// <param name="mimeType">The Content Type of the part. If the content type is not registered in the <see cref="ContentTypes"/>, it will automatically be added.</param>
        /// <returns>An instance of the part just created.</returns>
        public OpcPart CreatePart(Uri partUri, string mimeType)
        {
            var path = partUri.ToPackagePath();

            if (Archive.GetEntry(path) != null)
            {
                throw new InvalidOperationException("The part already exists.");
            }
            var extension = Path.GetExtension(path).TrimStart('.');

            if (!ContentTypes.Any(ct => string.Equals(extension, ct.Extension, StringComparison.OrdinalIgnoreCase)))
            {
                ContentTypes.Add(new OpcContentType(extension, mimeType.ToLower(), OpcContentTypeMode.Default));
            }
            var zipEntry = Archive.CreateEntry(path, CompressionLevel.NoCompression);
            var part     = new OpcPart(this, zipEntry.FullName, zipEntry, _mode);

            _partTracker.Add(zipEntry.FullName, part);
            return(part);
        }
        private static void ApplyTimestamp(XDocument originalSignatureDocument, OpcPart signaturePart, byte[] timestampSignature)
        {
            XNamespace xmlDSigNamespace      = OpcKnownUris.XmlDSig.AbsoluteUri;
            XNamespace xmlSignatureNamespace = OpcKnownUris.XmlDigitalSignature.AbsoluteUri;
            var        document  = new XDocument(originalSignatureDocument);
            var        signature = new XElement(xmlDSigNamespace + "Object",
                                                new XElement(xmlSignatureNamespace + "TimeStamp", new XAttribute("Id", "idSignatureTimestamp"),
                                                             new XElement(xmlSignatureNamespace + "Comment", ""),
                                                             new XElement(xmlSignatureNamespace + "EncodedTime", Convert.ToBase64String(timestampSignature))
                                                             )
                                                );

            document.Element(xmlDSigNamespace + "Signature").Add(signature);
            using (var copySignatureStream = signaturePart.Open())
            {
                using (var xmlWriter = new XmlTextWriter(copySignatureStream, System.Text.Encoding.UTF8))
                {
                    //The .NET implementation of OPC used by Visual Studio does not tollerate "white space" nodes.
                    xmlWriter.Formatting = Formatting.None;
                    document.Save(xmlWriter);
                }
            }
        }
        private static (XDocument document, byte[] signature) GetSignatureToTimestamp(OpcPart signaturePart)
        {
            XNamespace xmlDSigNamespace = OpcKnownUris.XmlDSig.AbsoluteUri;

            using (var signatureStream = signaturePart.Open())
            {
                var doc       = XDocument.Load(signatureStream);
                var signature = doc.Element(xmlDSigNamespace + "Signature")?.Element(xmlDSigNamespace + "SignatureValue")?.Value?.Trim();
                return(doc, Convert.FromBase64String(signature));
            }
        }
 internal OpcPackageTimestampBuilder(OpcPart part)
 {
     _part   = part;
     Timeout = TimeSpan.FromSeconds(30);
 }
 /// <summary>
 /// Dequeues a part from the signature builder. This file will not be part of the signature.
 /// </summary>
 /// <param name="part">The part to dequeue.</param>
 /// <returns>True if the file was dequeued, otherwise false.</returns>
 public bool DequeuePart(OpcPart part) => _enqueuedParts.Remove(part);
 /// <summary>
 /// Enqueues a part that will be part of the package signature.
 /// </summary>
 /// <param name="part">The part to enqueue.</param>
 public void EnqueuePart(OpcPart part) => _enqueuedParts.Add(part);
Esempio n. 13
0
 internal OpcSignature(OpcPart signaturePart)
 {
     _detached      = false;
     _signaturePart = signaturePart;
 }