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; }
//----------------------------------------------------- // // 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; }