PackageDigitalSignature.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / System / IO / Packaging / PackageDigitalSignature.cs / 1305600 / 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<> 
using MS.Internal.WindowsBase;
 
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<> 
using MS.Internal.WindowsBase;
 
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