예제 #1
0
 internal void SetCertificatePart(CertificatePart certificatePart) 
 { 
     Debug.Assert(certificatePart != null, "Logic Error: Not expecting setting certificate part to null on digital signature");
     _certificatePart = certificatePart; 
 }
        public PackageDigitalSignature Sign(
            IEnumerable<Uri> parts,
            X509Certificate certificate, 
            IEnumerable<PackageRelationshipSelector> relationshipSelectors,
            String signatureId, 
            IEnumerable<System.Security.Cryptography.Xml.DataObject> signatureObjects, 
            IEnumerable<System.Security.Cryptography.Xml.Reference> objectReferences)
        { 
            if (ReadOnly)
                throw new InvalidOperationException(SR.Get(SRID.CannotSignReadOnlyFile));

            VerifySignArguments(parts, certificate, relationshipSelectors, signatureId, signatureObjects, objectReferences); 

            // substitute default id if none given 
            if ((signatureId == null) || (signatureId == String.Empty)) 
            {
                signatureId = "packageSignature";   // default 
            }

            // Make sure the list reflects what's in the package.
            // Do this before adding the new signature part because we don't want it included until it 
            // is fully formed (and delaying the add saves us having to remove it in case there is an
            // error during the Sign call). 
            EnsureSignatures(); 

            Uri newSignaturePartName = GenerateSignaturePartName(); 
            if (_container.PartExists(newSignaturePartName))
                throw new ArgumentException(SR.Get(SRID.DuplicateSignature));

            // Pre-create origin part if it does not already exist. 
            // Do this before signing to allow for signing the package relationship part (because a Relationship
            // is added from the Package to the Origin part by this call) and the Origin Relationship part in case this is 
            // a Publishing signature and the caller wants the addition of more signatures to break this signature. 
            PackageRelationship relationshipToNewSignature = OriginPart.CreateRelationship(newSignaturePartName, TargetMode.Internal,
                    _originToSignatureRelationshipType); 
            _container.Flush();     // ensure the origin relationship part is persisted so that any signature will include this newest relationship

            VerifyPartsExist(parts);
 
            // sign the data and optionally embed the certificate
            bool embedCertificateInSignaturePart = (_certificateEmbeddingOption == CertificateEmbeddingOption.InSignaturePart); 
 
            // convert cert to version2 - more functionality
            X509Certificate2 exSigner = certificate as X509Certificate2; 
            if (exSigner == null)
                exSigner = new X509Certificate2(certificate.Handle);

            //PRESHARP: Parameter to this public method must be validated:  A null-dereference can occur here. 
            //      Parameter 'exSigner' to this public method must be validated:  A null-dereference can occur here.
            //This is a false positive as the checks above can gurantee no null dereference will occur 
#pragma warning disable 6506 

            PackageDigitalSignature signature = null; 
            PackagePart newSignaturePart = null;
            try
            {
                // create the new part 
                newSignaturePart = _container.CreatePart(newSignaturePartName, XmlDigitalSignatureProcessor.ContentType.ToString());
 
                // do the actual signing - only Xml signatures currently supported 
                signature = XmlDigitalSignatureProcessor.Sign(this, newSignaturePart, parts, relationshipSelectors, exSigner, signatureId, embedCertificateInSignaturePart,
                    signatureObjects, objectReferences); 
            }
            catch (InvalidOperationException)
            {
                // bad hash algorithm - revert changes 
                // guarantees proper cleanup including removal of Origin if appropriate
                // Note: _signatures.Count reflects the number of signatures that were 
                // existing before this sign method was called. So we want to leave those 
                // untouched and clean up what we added in this method prior to the
                // exception. If the count is zero, we will also delete the origin part. 
                InternalRemoveSignature(newSignaturePartName, _signatures.Count);
                _container.Flush();    // actually persist the revert
                throw;
            } 
            catch (System.IO.IOException)
            { 
                // failure to open part - revert changes 
                // guarantees proper cleanup including removal of Origin if appropriate
                // Note: _signatures.Count reflects the number of signatures that were 
                // existing before this sign method was called. So we want to leave those
                // untouched and clean up what we added in this method prior to the
                // exception. If the count is zero, we will also delete the origin part.
                InternalRemoveSignature(newSignaturePartName, _signatures.Count); 
                _container.Flush();    // actually persist the revert
                throw; 
            } 
            catch (System.Security.Cryptography.CryptographicException)
            { 
                // failure to sign - revert changes
                // guarantees proper cleanup including removal of Origin if appropriate
                // Note: _signatures.Count reflects the number of signatures that were
                // existing before this sign method was called. So we want to leave those 
                // untouched and clean up what we added in this method prior to the
                // exception. If the count is zero, we will also delete the origin part. 
                InternalRemoveSignature(newSignaturePartName, _signatures.Count); 
                _container.Flush();    // actually persist the revert
                throw; 
            }

            // add to the list
            _signatures.Add(signature); 

            // embed certificate if called for 
            if (_certificateEmbeddingOption == CertificateEmbeddingOption.InCertificatePart) 
            {
                // create the cert part 
                // auto-generate a certificate name - will be the same for the same certificate
                Uri certificatePartName = PackUriHelper.CreatePartUri(new Uri(
                    CertificatePart.PartNamePrefix + exSigner.SerialNumber + CertificatePart.PartNameExtension, UriKind.Relative));
 
                // create the serialization helper class (side-effect of creating or opening the part)
                CertificatePart certPart = new CertificatePart(_container, certificatePartName); 
                certPart.SetCertificate(exSigner); 

                // establish a relationship 
                newSignaturePart.CreateRelationship(certificatePartName, TargetMode.Internal, CertificatePart.RelationshipType);
                signature.SetCertificatePart(certPart);
            }
#pragma warning restore 6506 

            _container.Flush(); 
 
            // return to caller in case they need it
            return signature; 
        }
예제 #3
0
        //-----------------------------------------------------
        // 
        //  Internal Properties
        // 
        //------------------------------------------------------ 
        /// <summary>
        /// Get certificate part - null if none 
        /// </summary>
        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;
        }