/// <summary>
        /// Calculates the signature for this package.
        /// </summary>
        /// <param name="package">
        /// The package for whcih to calculate the signature.
        /// </param>
        /// <param name="privateKey">
        /// The private key to use.
        /// </param>
        /// <param name="compressedPayloadStream">
        /// The compressed payload.
        /// </param>
        public void CalculateSignature(RpmPackage package, PgpPrivateKey privateKey, Stream compressedPayloadStream)
        {
            RpmSignature signature = new RpmSignature(package);

            using (MemoryStream headerStream = this.GetHeaderStream(package))
                using (ConcatStream headerAndPayloadStream = new ConcatStream(leaveOpen: true, streams: new Stream[] { headerStream, compressedPayloadStream }))
                {
                    SHA1 sha = SHA1.Create();
                    signature.Sha1Hash = sha.ComputeHash(headerStream);

                    MD5 md5 = MD5.Create();
                    signature.MD5Hash = md5.ComputeHash(headerAndPayloadStream);

                    // Verify the PGP signatures
                    // 3 for the header
                    headerStream.Position        = 0;
                    signature.HeaderPgpSignature = PgpSigner.Sign(privateKey, headerStream);

                    headerAndPayloadStream.Position        = 0;
                    signature.HeaderAndPayloadPgpSignature = PgpSigner.Sign(privateKey, headerAndPayloadStream);

                    // Verify the signature size (header + compressed payload)
                    signature.HeaderAndPayloadSize = (int)headerAndPayloadStream.Length;
                }

            // Verify the payload size (header + uncompressed payload)

            using (Stream payloadStream = RpmPayloadReader.GetDecompressedPayloadStream(package, compressedPayloadStream))
            {
                signature.UncompressedPayloadSize = (int)payloadStream.Length;
            }
        }
Exemplo n.º 2
0
        public bool Verify(PgpPublicKey pgpPublicKey)
        {
            // 1 Verify the header signature immutable block: make sure all records are marked as immutable
            var immutableRegionSize = this.ImmutableRegionSize;
            var immutableEntryCount = -immutableRegionSize / Marshal.SizeOf<IndexHeader>();

            if (this.Package.Signature.Records.Count != immutableEntryCount)
            {
                return false;
            }

            // Store the header data and the header + payload data in substreams. This enables us to calculate hashes and
            // verify signatures using these data ranges.
            using (Stream headerStream = new SubStream(
                this.Package.Stream,
                this.Package.HeaderOffset,
                this.Package.PayloadOffset - this.Package.HeaderOffset,
                leaveParentOpen: true, readOnly: true))
            using (Stream headerAndPayloadStream = new SubStream(
                this.Package.Stream,
                this.Package.HeaderOffset,
                this.Package.Stream.Length - this.Package.HeaderOffset,
                leaveParentOpen: true,
                readOnly: true))
            {
                // Verify the SHA1 hash. This one covers the header block
                SHA1 sha = SHA1.Create();
                var calculatedShaValue = sha.ComputeHash(headerStream);
                var actualShaValue = this.Sha1Hash;

                if (!calculatedShaValue.SequenceEqual(actualShaValue))
                {
                    return false;
                }

                // Verify the MD5 hash. This one covers the header and the payload block
                MD5 md5 = MD5.Create();
                var calculatedMd5Value = md5.ComputeHash(headerAndPayloadStream);
                var actualMd5Value = this.MD5Hash;

                if (!calculatedMd5Value.SequenceEqual(actualMd5Value))
                {
                    return false;
                }

                // Verify the PGP signatures
                // 3 for the header
                var headerPgpSignature = this.HeaderPgpSignature;
                headerStream.Position = 0;

                if (!PgpSigner.VerifySignature(headerPgpSignature, pgpPublicKey, headerStream))
                {
                    return false;
                }

                var headerAndPayloadPgpSignature = this.HeaderAndPayloadPgpSignature;
                headerAndPayloadStream.Position = 0;

                if (!PgpSigner.VerifySignature(headerAndPayloadPgpSignature, pgpPublicKey, headerAndPayloadStream))
                {
                    return false;
                }
            }

            // Verify the signature size (header + compressed payload)
            var headerSize = this.HeaderAndPayloadSize;

            if (headerSize != this.Package.Stream.Length - this.Package.HeaderOffset)
            {
                return false;
            }

            // Verify the payload size (header + uncompressed payload)
            var expectedDecompressedPayloadSize = this.UncompressedPayloadSize;

            long actualDecompressedPayloadLength = 0;

            using (Stream payloadStream = RpmPayloadReader.GetDecompressedPayloadStream(this.Package))
            {
                actualDecompressedPayloadLength = payloadStream.Length;
            }

            if (expectedDecompressedPayloadSize != actualDecompressedPayloadLength)
            {
                return false;
            }

            return true;
        }
Exemplo n.º 3
0
 public PgpSignature Sign(Stream payload)
 {
     return(PgpSigner.Sign(this.privateKey, payload));
 }