PackageDigitalSignature.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / System / IO / Packaging / PackageDigitalSignature.cs / 1 / PackageDigitalSignature.cs

                            //------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//  This class represents a PackageDigitalSignature.  It is immutable. 
//
// History: 
//  03/22/2004: BruceMac: Initial Implementation
//  01/21/2005: BruceMac: Update for DigSig Security Mitigation DCR
//
//----------------------------------------------------------------------------- 

using System; 
using System.Collections.Generic; 
using System.Windows;           // For Exception strings - SRID
using System.Text;              // for StringBuilder 
using System.Diagnostics;        // for Assert
using System.Security;          // for SecurityCritical
using System.Security.Cryptography.Xml;     // for Xml Signature classes
using System.Security.Cryptography.X509Certificates; 
using System.Security.Cryptography;
using MS.Internal.IO.Packaging;            // helper classes Certificate, HashStream 
using System.Collections.ObjectModel;       // for ReadOnlyCollection<> 

namespace System.IO.Packaging 
{
    /// 
    /// VerifyResult
    ///  
    public enum VerifyResult : int
    { 
        ///  
        /// Verification succeeded
        ///  
        Success,               // signature valid

        /// 
        /// Signature was invalid (tampering detected) 
        /// 
        InvalidSignature,      // hash incorrect 
 
        /// 
        /// Certificate was not embedded in container and caller did not supply one 
        /// 
        CertificateRequired,   // no certificate is embedded in container - caller must provide one

        ///  
        /// Certificate was invalid (perhaps expired?)
        ///  
        InvalidCertificate,    // certificate problem - verify does not fully verify cert 

        ///  
        /// PackagePart was missing - signature invalid
        /// 
        ReferenceNotFound,     // signature failed because a part is missing
 
        /// 
        /// Package not signed 
        ///  
        NotSigned               // no signatures were found
    } 

    /// 
    /// PackageDigitalSignature
    ///  
    public class PackageDigitalSignature
    { 
        #region Public Members 
        //-----------------------------------------------------
        // 
        //  Public Properties
        //
        //-----------------------------------------------------
        ///  
        /// Parts that are covered by this signature
        ///  
        /// read only list 
        /// Thrown if associated digital signature has been deleted.
        public ReadOnlyCollection SignedParts 
        {
            get
            {
                ThrowIfInvalidated(); 

                // wrap in read-only collection to protect against alteration 
                if (_signedParts == null) 
                    _signedParts = new ReadOnlyCollection(_processor.PartManifest);
 
                return _signedParts;
            }
        }
 
        /// 
        /// Relationships that are covered by this signature 
        ///  
        /// read only list
        /// Thrown if associated digital signature has been deleted. 
        public ReadOnlyCollection SignedRelationshipSelectors
        {
            get
            { 
                ThrowIfInvalidated();
 
                // wrap in read-only collection to protect against alteration 
                if (_signedRelationshipSelectors == null)
                    _signedRelationshipSelectors = new ReadOnlyCollection(_processor.RelationshipManifest); 

                return _signedRelationshipSelectors;
            }
        } 

        ///  
        /// The part that contains the actual signature - useful for counter-signing scenarios 
        /// 
        /// Thrown if associated digital signature has been deleted. 
        public PackagePart SignaturePart
        {
            get
            { 
                ThrowIfInvalidated();
 
                return _processor.SignaturePart; 
            }
        } 

        /// 
        /// Certificate of signer embedded in container
        ///  
        /// null if certificate was not embedded
        /// Thrown if associated digital signature has been deleted. 
        public X509Certificate Signer 
        {
            get 
            {
                ThrowIfInvalidated();

                return _processor.Signer; 
            }
        } 
 
        /// 
        /// Time signature was created - not a trusted TimeStamp 
        /// 
        /// 
        /// Thrown if associated digital signature has been deleted.
        public DateTime SigningTime 
        {
            get 
            { 
                ThrowIfInvalidated();
 
                return _processor.SigningTime;
            }
        }
 
        /// 
        /// Format of time returned by SigningTime (see PackageDigitalSignatureManager.TimeFormat for details) 
        ///  
        /// Thrown if associated digital signature has been deleted.
        public String TimeFormat 
        {
            get
            {
                ThrowIfInvalidated(); 

                return _processor.TimeFormat; 
            } 
        }
 
        /// 
        /// encrypted hash value
        /// 
        ///  
        /// Thrown if associated digital signature has been deleted.
        public byte[] SignatureValue 
        { 
            get
            { 
                ThrowIfInvalidated();

                return _processor.SignatureValue;
            } 
        }
 
        ///  
        /// Content Type of signature
        ///  
        /// Thrown if associated digital signature has been deleted.
        public String SignatureType
        {
            get 
            {
                ThrowIfInvalidated(); 
 
                return XmlDigitalSignatureProcessor.ContentType.ToString();
            } 
        }

        /// 
        /// Type-specific signature object 
        /// 
        ///  
        /// Provides access to the underlying class that performs the signature type-specific cryptographic 
        /// functions and serialization to/from the package part that houses the signature.
        ///  
        /// 
        /// Returns an object of type System.Security.Cryptography.Xml.Signature.
        /// Future signature types will return objects of different classes.
        ///  
        /// Thrown if associated digital signature has been deleted.
        public Signature Signature 
        { 
            get
            { 
                ThrowIfInvalidated();
                return _processor.Signature;
            }
            set 
            {
                ThrowIfInvalidated(); 
                if (value == null) 
                    throw new ArgumentNullException("value");
 
                _processor.Signature = value;
            }
        }
 
        /// 
        /// Where is the certificate? 
        ///  
        /// Thrown if associated digital signature has been deleted.
        public CertificateEmbeddingOption CertificateEmbeddingOption 
        {
            get
            {
                ThrowIfInvalidated(); 

                if (GetCertificatePart() == null) 
                { 
                    if (Signer == null)
                    { 
                        return CertificateEmbeddingOption.NotEmbedded;
                    }
                    else
                    { 
                        return CertificateEmbeddingOption.InSignaturePart;
                    } 
                } 
                else
                { 
                    return CertificateEmbeddingOption.InCertificatePart;
                }
            }
        } 

        //------------------------------------------------------ 
        // 
        //  Public Methods
        // 
        //-----------------------------------------------------
        /// 
        /// Returns ordered list of transforms applied to the given part
        ///  
        /// Thrown if associated digital signature has been deleted.
        public List GetPartTransformList(Uri partName) 
        { 
            ThrowIfInvalidated();
 
            // no need to clone this for return as it's already a single-use collection
            return _processor.GetPartTransformList(partName);
        }
 
        /// 
        /// Verify 
        ///  
        /// cannot use this overload with signatures created without embedding their certs
        ///  
        /// Thrown if associated digital signature has been deleted.
        public VerifyResult Verify()
        {
            ThrowIfInvalidated(); 

            if (Signer == null) 
                return VerifyResult.CertificateRequired; 

            return Verify(Signer); 
        }

        /// 
        /// Verify 
        /// 
        /// certificate used to create the signature 
        ///  
        /// Use this overload when the certificate is not embedded in the container at signing time
        /// Thrown if associated digital signature has been deleted. 
        ///
        ///     Critical: calls X509Certificate2 ctor which LinkDemands
        ///     TreatAsSafe: X509Certificate2 is only used internally and not returned
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public VerifyResult Verify(X509Certificate signingCertificate) 
        { 
            ThrowIfInvalidated();
 
            VerifyResult result = VerifyResult.NotSigned;

            if (signingCertificate == null)
                throw new ArgumentNullException("signingCertificate"); 

            // Check for part existence 
            foreach (Uri partUri in SignedParts) 
            {
                // check if they exist 
                if (!_manager.Package.PartExists(partUri))
                {
                    return VerifyResult.ReferenceNotFound;
                } 
            }
 
            // convert to Ex variant that has more functionality 
            X509Certificate2 certificate = signingCertificate as X509Certificate2;
            if (certificate == null) 
                certificate = new X509Certificate2(signingCertificate.Handle);

            // verify
            if (_processor.Verify(certificate)) 
                result = VerifyResult.Success;
            else 
                result = VerifyResult.InvalidSignature; 

            return result; 
        }

        #endregion
 
        #region Internal Members
        //------------------------------------------------------ 
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------
        /// 
        /// Constructor for creating a new signature
        ///  
        /// digital signature manager - to consult for hash, embedding and other options
        /// digital signature manager - to consult for hash, embedding and other options 
        internal PackageDigitalSignature( 
            PackageDigitalSignatureManager manager,
            XmlDigitalSignatureProcessor processor) 
        {
            Debug.Assert(processor.PackageSignature == null, "Logic Error: one processor per-signature");
            _manager = manager;
            _processor = processor; 
//            _processor.PackageSignature = this;
        } 
 
        /// 
        /// Constructor for use when opening an existing signature 
        /// 
        /// digital signature manager - to consult for hash, embedding and other options
        /// part that houses the signature
        internal PackageDigitalSignature( 
            PackageDigitalSignatureManager manager,
            PackagePart signaturePart) 
        { 
            _manager = manager;
            _processor = new XmlDigitalSignatureProcessor(manager, signaturePart, this); 
        }

        /// 
        /// This is called when the underlying signature is deleted - it prevents usage of the object 
        /// 
        internal void Invalidate() 
        { 
            _invalid = true;
        } 

        //-----------------------------------------------------
        //
        //  Internal Properties 
        //
        //------------------------------------------------------ 
        ///  
        /// Get certificate part - null if none
        ///  
        internal CertificatePart GetCertificatePart()
        {
            // lazy init
            if (_certificatePart == null && !_alreadyLookedForCertPart) 
            {
                PackageRelationshipCollection relationships = SignaturePart.GetRelationshipsByType( 
                    CertificatePart.RelationshipType); 
                foreach (PackageRelationship relationship in relationships)
                { 
                    // don't resolve if external
                    if (relationship.TargetMode != TargetMode.Internal)
                        throw new FileFormatException(SR.Get(SRID.PackageSignatureCorruption));
 
                    Uri resolvedUri = PackUriHelper.ResolvePartUri(SignaturePart.Uri, relationship.TargetUri);
 
                    // don't create if it doesn't exist 
                    if (!_manager.Package.PartExists(resolvedUri))
                    { 
                        continue;
                    }

                    // find the cert 
                    _certificatePart = new CertificatePart(_manager.Package, resolvedUri);
                    break; 
                } 
                _alreadyLookedForCertPart = true;
            } 

            return _certificatePart;
        }
 
        internal void SetCertificatePart(CertificatePart certificatePart)
        { 
            Debug.Assert(certificatePart != null, "Logic Error: Not expecting setting certificate part to null on digital signature"); 
            _certificatePart = certificatePart;
        } 

        #endregion

        #region Private Methods 

        //----------------------------------------------------- 
        // 
        //  Private Methods
        // 
        //-----------------------------------------------------
        /// 
        /// ThrowIfInvalidated - check on each access
        ///  
        private void ThrowIfInvalidated()
        { 
            if (_invalid) 
                throw new InvalidOperationException(SR.Get(SRID.SignatureDeleted));
        } 

        #endregion Private Methods

        //----------------------------------------------------- 
        //
        //  Private Fields 
        // 
        //------------------------------------------------------
        private PackageDigitalSignatureManager                     _manager; 
        private XmlDigitalSignatureProcessor                       _processor;
        private CertificatePart                                    _certificatePart;
        private ReadOnlyCollection                            _signedParts;
        private ReadOnlyCollection    _signedRelationshipSelectors; 
        private bool                                               _alreadyLookedForCertPart;
        private bool                                               _invalid;   // have we been invalidated? 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//  This class represents a PackageDigitalSignature.  It is immutable. 
//
// History: 
//  03/22/2004: BruceMac: Initial Implementation
//  01/21/2005: BruceMac: Update for DigSig Security Mitigation DCR
//
//----------------------------------------------------------------------------- 

using System; 
using System.Collections.Generic; 
using System.Windows;           // For Exception strings - SRID
using System.Text;              // for StringBuilder 
using System.Diagnostics;        // for Assert
using System.Security;          // for SecurityCritical
using System.Security.Cryptography.Xml;     // for Xml Signature classes
using System.Security.Cryptography.X509Certificates; 
using System.Security.Cryptography;
using MS.Internal.IO.Packaging;            // helper classes Certificate, HashStream 
using System.Collections.ObjectModel;       // for ReadOnlyCollection<> 

namespace System.IO.Packaging 
{
    /// 
    /// VerifyResult
    ///  
    public enum VerifyResult : int
    { 
        ///  
        /// Verification succeeded
        ///  
        Success,               // signature valid

        /// 
        /// Signature was invalid (tampering detected) 
        /// 
        InvalidSignature,      // hash incorrect 
 
        /// 
        /// Certificate was not embedded in container and caller did not supply one 
        /// 
        CertificateRequired,   // no certificate is embedded in container - caller must provide one

        ///  
        /// Certificate was invalid (perhaps expired?)
        ///  
        InvalidCertificate,    // certificate problem - verify does not fully verify cert 

        ///  
        /// PackagePart was missing - signature invalid
        /// 
        ReferenceNotFound,     // signature failed because a part is missing
 
        /// 
        /// Package not signed 
        ///  
        NotSigned               // no signatures were found
    } 

    /// 
    /// PackageDigitalSignature
    ///  
    public class PackageDigitalSignature
    { 
        #region Public Members 
        //-----------------------------------------------------
        // 
        //  Public Properties
        //
        //-----------------------------------------------------
        ///  
        /// Parts that are covered by this signature
        ///  
        /// read only list 
        /// Thrown if associated digital signature has been deleted.
        public ReadOnlyCollection SignedParts 
        {
            get
            {
                ThrowIfInvalidated(); 

                // wrap in read-only collection to protect against alteration 
                if (_signedParts == null) 
                    _signedParts = new ReadOnlyCollection(_processor.PartManifest);
 
                return _signedParts;
            }
        }
 
        /// 
        /// Relationships that are covered by this signature 
        ///  
        /// read only list
        /// Thrown if associated digital signature has been deleted. 
        public ReadOnlyCollection SignedRelationshipSelectors
        {
            get
            { 
                ThrowIfInvalidated();
 
                // wrap in read-only collection to protect against alteration 
                if (_signedRelationshipSelectors == null)
                    _signedRelationshipSelectors = new ReadOnlyCollection(_processor.RelationshipManifest); 

                return _signedRelationshipSelectors;
            }
        } 

        ///  
        /// The part that contains the actual signature - useful for counter-signing scenarios 
        /// 
        /// Thrown if associated digital signature has been deleted. 
        public PackagePart SignaturePart
        {
            get
            { 
                ThrowIfInvalidated();
 
                return _processor.SignaturePart; 
            }
        } 

        /// 
        /// Certificate of signer embedded in container
        ///  
        /// null if certificate was not embedded
        /// Thrown if associated digital signature has been deleted. 
        public X509Certificate Signer 
        {
            get 
            {
                ThrowIfInvalidated();

                return _processor.Signer; 
            }
        } 
 
        /// 
        /// Time signature was created - not a trusted TimeStamp 
        /// 
        /// 
        /// Thrown if associated digital signature has been deleted.
        public DateTime SigningTime 
        {
            get 
            { 
                ThrowIfInvalidated();
 
                return _processor.SigningTime;
            }
        }
 
        /// 
        /// Format of time returned by SigningTime (see PackageDigitalSignatureManager.TimeFormat for details) 
        ///  
        /// Thrown if associated digital signature has been deleted.
        public String TimeFormat 
        {
            get
            {
                ThrowIfInvalidated(); 

                return _processor.TimeFormat; 
            } 
        }
 
        /// 
        /// encrypted hash value
        /// 
        ///  
        /// Thrown if associated digital signature has been deleted.
        public byte[] SignatureValue 
        { 
            get
            { 
                ThrowIfInvalidated();

                return _processor.SignatureValue;
            } 
        }
 
        ///  
        /// Content Type of signature
        ///  
        /// Thrown if associated digital signature has been deleted.
        public String SignatureType
        {
            get 
            {
                ThrowIfInvalidated(); 
 
                return XmlDigitalSignatureProcessor.ContentType.ToString();
            } 
        }

        /// 
        /// Type-specific signature object 
        /// 
        ///  
        /// Provides access to the underlying class that performs the signature type-specific cryptographic 
        /// functions and serialization to/from the package part that houses the signature.
        ///  
        /// 
        /// Returns an object of type System.Security.Cryptography.Xml.Signature.
        /// Future signature types will return objects of different classes.
        ///  
        /// Thrown if associated digital signature has been deleted.
        public Signature Signature 
        { 
            get
            { 
                ThrowIfInvalidated();
                return _processor.Signature;
            }
            set 
            {
                ThrowIfInvalidated(); 
                if (value == null) 
                    throw new ArgumentNullException("value");
 
                _processor.Signature = value;
            }
        }
 
        /// 
        /// Where is the certificate? 
        ///  
        /// Thrown if associated digital signature has been deleted.
        public CertificateEmbeddingOption CertificateEmbeddingOption 
        {
            get
            {
                ThrowIfInvalidated(); 

                if (GetCertificatePart() == null) 
                { 
                    if (Signer == null)
                    { 
                        return CertificateEmbeddingOption.NotEmbedded;
                    }
                    else
                    { 
                        return CertificateEmbeddingOption.InSignaturePart;
                    } 
                } 
                else
                { 
                    return CertificateEmbeddingOption.InCertificatePart;
                }
            }
        } 

        //------------------------------------------------------ 
        // 
        //  Public Methods
        // 
        //-----------------------------------------------------
        /// 
        /// Returns ordered list of transforms applied to the given part
        ///  
        /// Thrown if associated digital signature has been deleted.
        public List GetPartTransformList(Uri partName) 
        { 
            ThrowIfInvalidated();
 
            // no need to clone this for return as it's already a single-use collection
            return _processor.GetPartTransformList(partName);
        }
 
        /// 
        /// Verify 
        ///  
        /// cannot use this overload with signatures created without embedding their certs
        ///  
        /// Thrown if associated digital signature has been deleted.
        public VerifyResult Verify()
        {
            ThrowIfInvalidated(); 

            if (Signer == null) 
                return VerifyResult.CertificateRequired; 

            return Verify(Signer); 
        }

        /// 
        /// Verify 
        /// 
        /// certificate used to create the signature 
        ///  
        /// Use this overload when the certificate is not embedded in the container at signing time
        /// Thrown if associated digital signature has been deleted. 
        ///
        ///     Critical: calls X509Certificate2 ctor which LinkDemands
        ///     TreatAsSafe: X509Certificate2 is only used internally and not returned
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public VerifyResult Verify(X509Certificate signingCertificate) 
        { 
            ThrowIfInvalidated();
 
            VerifyResult result = VerifyResult.NotSigned;

            if (signingCertificate == null)
                throw new ArgumentNullException("signingCertificate"); 

            // Check for part existence 
            foreach (Uri partUri in SignedParts) 
            {
                // check if they exist 
                if (!_manager.Package.PartExists(partUri))
                {
                    return VerifyResult.ReferenceNotFound;
                } 
            }
 
            // convert to Ex variant that has more functionality 
            X509Certificate2 certificate = signingCertificate as X509Certificate2;
            if (certificate == null) 
                certificate = new X509Certificate2(signingCertificate.Handle);

            // verify
            if (_processor.Verify(certificate)) 
                result = VerifyResult.Success;
            else 
                result = VerifyResult.InvalidSignature; 

            return result; 
        }

        #endregion
 
        #region Internal Members
        //------------------------------------------------------ 
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------
        /// 
        /// Constructor for creating a new signature
        ///  
        /// digital signature manager - to consult for hash, embedding and other options
        /// digital signature manager - to consult for hash, embedding and other options 
        internal PackageDigitalSignature( 
            PackageDigitalSignatureManager manager,
            XmlDigitalSignatureProcessor processor) 
        {
            Debug.Assert(processor.PackageSignature == null, "Logic Error: one processor per-signature");
            _manager = manager;
            _processor = processor; 
//            _processor.PackageSignature = this;
        } 
 
        /// 
        /// Constructor for use when opening an existing signature 
        /// 
        /// digital signature manager - to consult for hash, embedding and other options
        /// part that houses the signature
        internal PackageDigitalSignature( 
            PackageDigitalSignatureManager manager,
            PackagePart signaturePart) 
        { 
            _manager = manager;
            _processor = new XmlDigitalSignatureProcessor(manager, signaturePart, this); 
        }

        /// 
        /// This is called when the underlying signature is deleted - it prevents usage of the object 
        /// 
        internal void Invalidate() 
        { 
            _invalid = true;
        } 

        //-----------------------------------------------------
        //
        //  Internal Properties 
        //
        //------------------------------------------------------ 
        ///  
        /// Get certificate part - null if none
        ///  
        internal CertificatePart GetCertificatePart()
        {
            // lazy init
            if (_certificatePart == null && !_alreadyLookedForCertPart) 
            {
                PackageRelationshipCollection relationships = SignaturePart.GetRelationshipsByType( 
                    CertificatePart.RelationshipType); 
                foreach (PackageRelationship relationship in relationships)
                { 
                    // don't resolve if external
                    if (relationship.TargetMode != TargetMode.Internal)
                        throw new FileFormatException(SR.Get(SRID.PackageSignatureCorruption));
 
                    Uri resolvedUri = PackUriHelper.ResolvePartUri(SignaturePart.Uri, relationship.TargetUri);
 
                    // don't create if it doesn't exist 
                    if (!_manager.Package.PartExists(resolvedUri))
                    { 
                        continue;
                    }

                    // find the cert 
                    _certificatePart = new CertificatePart(_manager.Package, resolvedUri);
                    break; 
                } 
                _alreadyLookedForCertPart = true;
            } 

            return _certificatePart;
        }
 
        internal void SetCertificatePart(CertificatePart certificatePart)
        { 
            Debug.Assert(certificatePart != null, "Logic Error: Not expecting setting certificate part to null on digital signature"); 
            _certificatePart = certificatePart;
        } 

        #endregion

        #region Private Methods 

        //----------------------------------------------------- 
        // 
        //  Private Methods
        // 
        //-----------------------------------------------------
        /// 
        /// ThrowIfInvalidated - check on each access
        ///  
        private void ThrowIfInvalidated()
        { 
            if (_invalid) 
                throw new InvalidOperationException(SR.Get(SRID.SignatureDeleted));
        } 

        #endregion Private Methods

        //----------------------------------------------------- 
        //
        //  Private Fields 
        // 
        //------------------------------------------------------
        private PackageDigitalSignatureManager                     _manager; 
        private XmlDigitalSignatureProcessor                       _processor;
        private CertificatePart                                    _certificatePart;
        private ReadOnlyCollection                            _signedParts;
        private ReadOnlyCollection    _signedRelationshipSelectors; 
        private bool                                               _alreadyLookedForCertPart;
        private bool                                               _invalid;   // have we been invalidated? 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK