예제 #1
0
        /// <summary>
        /// Test the DigestStream class implementation
        /// <para>Throws an Exception on failure</</para>
        /// </summary>
        public static void StreamDigestTest()
        {
            byte[]       data;
            MemoryStream instrm;
            MemoryStream outstrm = new MemoryStream();

            using (KeyGenerator kg = new KeyGenerator())
                data = kg.GetBytes(512);

            // data to digest
            instrm = new MemoryStream(data);
            byte[] code1;
            byte[] code2;

            using (DigestStream sd = new DigestStream(Digests.Keccak512))
            {
                sd.Initialize(instrm);
                code1 = sd.ComputeHash();
            }

            using (Keccak512 kc = new Keccak512())
                code2 = kc.ComputeHash(data);

            // compare the hash codes
            if (!Evaluate.AreEqual(code1, code2))
            {
                throw new Exception();
            }
        }
예제 #2
0
        /// <summary>
        /// Computes a unique identifier for this bytecode instance.
        /// </summary>
        /// <returns>ObjectId.</returns>
        public ObjectId ComputeId()
        {
            var effectBytecode = this;

            // We should most of the time have stages, unless someone is calling this method on a new EffectBytecode
            if (effectBytecode.Stages != null)
            {
                effectBytecode = (EffectBytecode)MemberwiseClone();

                effectBytecode.Stages = (ShaderBytecode[])effectBytecode.Stages.Clone();

                // Because ShaderBytecode.Data can vary, we are calculating the bytecodeId only with the ShaderBytecode.Id.
                for (int i = 0; i < effectBytecode.Stages.Length; i++)
                {
                    var newStage = effectBytecode.Stages[i].Clone();
                    effectBytecode.Stages[i] = newStage;
                    newStage.Data            = null;
                }
            }

            // Not optimized: Pre-calculate bytecodeId in order to avoid writing to same storage
            ObjectId newBytecodeId;
            var      memStream = new MemoryStream();

            using (var stream = new DigestStream(memStream))
            {
                effectBytecode.WriteTo(stream);
                newBytecodeId = stream.CurrentHash;
            }
            return(newBytecodeId);
        }
예제 #3
0
        /// <summary>Note: This can only be called after the message has been read.</summary>
        /// <returns>True, if the message verifies, false otherwise</returns>
        public bool Verify()
        {
            if (!IsIntegrityProtected())
            {
                throw new PgpException("data not integrity protected.");
            }

            DigestStream dIn = (DigestStream)encStream;

            //
            // make sure we are at the end.
            //
            while (encStream.ReadByte() >= 0)
            {
                // do nothing
            }

            //
            // process the MDC packet
            //
            byte[] lookAhead = truncStream.GetLookAhead();

            IDigest hash = dIn.ReadDigest();

            hash.BlockUpdate(lookAhead, 0, 2);
            byte[] digest = DigestUtilities.DoFinal(hash);

            byte[] streamDigest = new byte[digest.Length];
            Array.Copy(lookAhead, 2, streamDigest, 0, streamDigest.Length);

            return(Arrays.ConstantTimeAreEqual(digest, streamDigest));
        }
예제 #4
0
        internal ObjectId ComputeCommandHash(IPrepareContext prepareContext)
        {
            var stream = new DigestStream(Stream.Null);

            ComputeCommandHash(stream, prepareContext);

            return(stream.CurrentHash);
        }
예제 #5
0
 /// <summary>
 /// Computes the hash of the <see cref="NavigationSettings.Groups"/> field
 /// </summary>
 public static ObjectId ComputeGroupsHash(this NavigationSettings settings)
 {
     using (DigestStream stream = new DigestStream(Stream.Null))
     {
         BinarySerializationWriter writer = new BinarySerializationWriter(stream);
         writer.Write(settings.Groups);
         return(stream.CurrentHash);
     }
 }
예제 #6
0
        public unsafe void TestDigestStream()
        {
            string s1 = "abc";
            string s2 = "abcdefghijklmnopqrstuvwxyz";
            string s3 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz123456789";

            ObjectId xenkoHash;
            ObjectId dotNetHash;

            using (var ds = new DigestStream(new MemoryStream()))
            {
                ds.Write(Encoding.ASCII.GetBytes(s1), 0, s1.Length);
                xenkoHash = ds.CurrentHash;
            }
            using (var hashAlgorithm = new System.Security.Cryptography.SHA1Managed())
            {
                dotNetHash = new ObjectId(hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(s1)));
            }
            Assert.Equal(dotNetHash, xenkoHash);

            using (var ds = new DigestStream(new MemoryStream()))
            {
                ds.Write(Encoding.ASCII.GetBytes(s2), 0, s2.Length);
                xenkoHash = ds.CurrentHash;
            }
            using (var hashAlgorithm = new System.Security.Cryptography.SHA1Managed())
            {
                dotNetHash = new ObjectId(hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(s2)));
            }
            Assert.Equal(dotNetHash, xenkoHash);

            using (var ds = new DigestStream(new MemoryStream()))
            {
                ds.Write(Encoding.ASCII.GetBytes(s3), 0, s3.Length);
                xenkoHash = ds.CurrentHash;
            }
            using (var hashAlgorithm = new System.Security.Cryptography.SHA1Managed())
            {
                dotNetHash = new ObjectId(hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(s3)));
            }
            Assert.Equal(dotNetHash, xenkoHash);

            using (var ds = new DigestStream(new MemoryStream()))
            {
                ds.Write(Encoding.ASCII.GetBytes(s1), 0, s1.Length);
                ds.Write(Encoding.ASCII.GetBytes(s2), 0, s2.Length);
                ds.Write(Encoding.ASCII.GetBytes(s3), 0, s3.Length);
                xenkoHash = ds.CurrentHash;
            }
            using (var hashAlgorithm = new System.Security.Cryptography.SHA1Managed())
            {
                dotNetHash = new ObjectId(hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(s1 + s2 + s3)));
            }
            Assert.Equal(dotNetHash, xenkoHash);
        }
 internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
 {
     try
     {
         SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = keyData.EncAlgorithm;
         KeyParameter             parameters = PgpUtilities.DoMakeKeyFromPassPhrase(symmetricKeyAlgorithmTag, keyData.S2k, rawPassPhrase, clearPassPhrase);
         byte[] secKeyData = keyData.GetSecKeyData();
         if (secKeyData != null && secKeyData.Length > 0)
         {
             IBufferedCipher cipher = CipherUtilities.GetCipher(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag) + "/CFB/NoPadding");
             cipher.Init(forEncryption: false, new ParametersWithIV(parameters, new byte[cipher.GetBlockSize()]));
             byte[] array = cipher.DoFinal(secKeyData);
             symmetricKeyAlgorithmTag = (SymmetricKeyAlgorithmTag)array[0];
             parameters = ParameterUtilities.CreateKeyParameter(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag), array, 1, array.Length - 1);
         }
         IBufferedCipher bufferedCipher = CreateStreamCipher(symmetricKeyAlgorithmTag);
         byte[]          array2         = new byte[bufferedCipher.GetBlockSize()];
         bufferedCipher.Init(forEncryption: false, new ParametersWithIV(parameters, array2));
         encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), bufferedCipher, null));
         if (encData is SymmetricEncIntegrityPacket)
         {
             truncStream = new TruncatedStream(encStream);
             string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
             IDigest digest     = DigestUtilities.GetDigest(digestName);
             encStream = new DigestStream(truncStream, digest, null);
         }
         if (Streams.ReadFully(encStream, array2, 0, array2.Length) < array2.Length)
         {
             throw new EndOfStreamException("unexpected end of stream.");
         }
         int num  = encStream.ReadByte();
         int num2 = encStream.ReadByte();
         if (num < 0 || num2 < 0)
         {
             throw new EndOfStreamException("unexpected end of stream.");
         }
         bool flag  = array2[array2.Length - 2] == (byte)num && array2[array2.Length - 1] == (byte)num2;
         bool flag2 = num == 0 && num2 == 0;
         if (!flag && !flag2)
         {
             throw new PgpDataValidationException("quick check failed.");
         }
         return(encStream);
     }
     catch (PgpException ex)
     {
         throw ex;
     }
     catch (Exception exception)
     {
         throw new PgpException("Exception creating cipher", exception);
     }
 }
예제 #8
0
 private static ThumbnailData GetFolderThumbnail(IDispatcherService dispatcher)
 {
     using (var ds = new DigestStream(new MemoryStream()))
     {
         var bytes = Resources.Images.folder;
         ds.Write(bytes, 0, bytes.Length);
         var objectId = ds.CurrentHash;
         var data     = new ThumbnailData(objectId, new MemoryStream(bytes));
         data.PrepareForPresentation(dispatcher).Forget();
         return(data);
     }
 }
예제 #9
0
 private byte[] HashTest2(string FileName)
 {
     using (FileStream inStream = new FileStream(FileName, FileMode.Open))
     {
         using (DigestStream dgst = new DigestStream(new SHA512()))
         {
             dgst.Initialize(inStream);
             // linear processing
             dgst.IsConcurrent = false;
             return(dgst.ComputeHash());
         }
     }
 }
예제 #10
0
 private byte[] HashTest1(string FileName)
 {
     using (FileStream inStream = new FileStream(FileName, FileMode.Open))
     {
         using (DigestStream dgst = new DigestStream(new SHA512()))
         {
             dgst.Initialize(inStream);
             // run concurrent mode
             dgst.IsConcurrent = true;
             return(dgst.ComputeHash());
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Generates a Guid unique to this name
        /// </summary>
        /// <param name="name">the name to turn into a Guid</param>
        /// <returns>A unique Guid for the given name</returns>
        public static Guid DeviceNameToGuid(string name)
        {
            MemoryStream stream = new MemoryStream();
            DigestStream writer = new DigestStream(stream);

            {
                BinarySerializationWriter serializer = new HashSerializationWriter(writer);
                serializer.Write(typeof(IInputDevice).GetHashCode());
                serializer.Write(name);
            }

            return(writer.CurrentHash.ToGuid());
        }
예제 #12
0
        private static byte[] ComputeHash(object document)
        {
            var sha    = new Sha256Digest();
            var stream = new DigestStream(new MemoryStream(), null, sha);

            using (var writer = new StreamWriter(stream))
            {
                string mementoToString = JsonConvert.SerializeObject(document);
                writer.Write(mementoToString);
            }
            byte[] buffer = new byte[sha.GetDigestSize()];
            sha.DoFinal(buffer, 0);
            return(buffer);
        }
예제 #13
0
    public CmsTypedStream GetSignedContent()
    {
        if (_signedContent == null)
        {
            return(null);
        }
        Stream stream = _signedContent.ContentStream;

        foreach (IDigest value in _digests.Values)
        {
            stream = new DigestStream(stream, value, null);
        }
        return(new CmsTypedStream(_signedContent.ContentType, stream));
    }
예제 #14
0
        public CmsTypedStream GetSignedContent()
        {
            if (this._signedContent == null)
            {
                return(null);
            }
            Stream stream = this._signedContent.ContentStream;

            foreach (IDigest readDigest in this._digests.Values)
            {
                stream = new DigestStream(stream, readDigest, null);
            }
            return(new CmsTypedStream(this._signedContent.ContentType, stream));
        }
예제 #15
0
        /// <summary>
        /// Computes the command hash. If an error occurred, the hash is <see cref="ObjectId.Empty"/>
        /// </summary>
        /// <param name="prepareContext">The prepare context.</param>
        /// <returns>Hash of the command.</returns>
        internal ObjectId ComputeCommandHash(IPrepareContext prepareContext)
        {
            var stream = new DigestStream(Stream.Null);

            try
            {
                ComputeCommandHash(stream, prepareContext);
                return(stream.CurrentHash);
            }
            catch (Exception ex)
            {
                prepareContext.Logger.Error($"Unexpected error while computing the command hash for [{GetType().Name}].", ex);
            }
            return(ObjectId.Empty);
        }
예제 #16
0
        public CmsTypedStream GetSignedContent()
        {
            if (_signedContent == null)
            {
                return(null);
            }

            Stream digStream = _signedContent.ContentStream;

            foreach (IDigest digest in _digests.Values)
            {
                digStream = new DigestStream(digStream, digest, null);
            }

            return(new CmsTypedStream(_signedContent.ContentType, digStream));
        }
예제 #17
0
        private AsicePackageEntry CreateEntry(Stream contentStream, AsicePackageEntry entry)
        {
            var fileName   = entry.FileName ?? throw new ArgumentNullException(nameof(entry), "File name must be provided");
            var dataStream = contentStream ?? throw new ArgumentNullException(nameof(contentStream));
            var zipEntry   = Archive.CreateEntry(fileName);

            using (var zipStream = zipEntry.Open())
                using (var digestStream = new DigestStream(zipStream, null, MessageDigestAlgorithm.Digest))
                {
                    dataStream.CopyTo(digestStream);
                    dataStream.Flush();
                    entry.Digest = new DigestContainer(DigestUtilities.DoFinal(digestStream.WriteDigest()), MessageDigestAlgorithm);
                }

            return(entry);
        }
예제 #18
0
        public ObjectId ComputeFileHash(string filePath)
        {
            var inputVersionKey = new FileVersionKey(filePath);

            storage.LoadNewValues();

            // Perform a lock per file as it can be expensive to compute
            // them at the same time (for large file)
            object versionLock;

            lock (locks)
            {
                if (!locks.TryGetValue(inputVersionKey, out versionLock))
                {
                    versionLock = new object();
                    locks.Add(inputVersionKey, versionLock);
                }
            }

            var hash = ObjectId.Empty;

            lock (versionLock)
            {
                if (!storage.TryGetValue(inputVersionKey, out hash))
                {
                    // TODO: we might want to allow retries, timeout, etc. since file processed here are files currently being edited by user
                    try
                    {
                        using (var fileStream = File.OpenRead(filePath))
                            using (var stream = new DigestStream(Stream.Null))
                            {
                                fileStream.CopyTo(stream);
                                hash = stream.CurrentHash;
                            }
                    }
                    catch (Exception ex)
                    {
                        log.Debug("Cannot calculate hash for file [{0}]", ex, filePath);
                    }
                    storage[inputVersionKey] = hash;
                }
            }

            return(hash);
        }
예제 #19
0
            /// <summary>
            /// Computes a unique Id for this asset used to store intermediate / build cache data
            /// </summary>
            /// <returns>The object id for asset intermediate data</returns>
            private ObjectId ComputeAssetIntermediateDataId()
            {
                var stream = new DigestStream(Stream.Null);
                var writer = new BinarySerializationWriter(stream);

                writer.Context.SerializerSelector = SerializerSelector.AssetWithReuse;
                writer.Write(CommandCacheVersion);

                // Write binary format version
                writer.Write(DataSerializer.BinaryFormatVersion);

                // Compute assembly hash
                ComputeAssemblyHash(writer);

                // Write asset Id
                writer.Write(asset.Id);

                return(stream.CurrentHash);
            }
예제 #20
0
        private bool HashTest3()
        {
            byte[] data = new CSPPrng().GetBytes(33033);
            byte[] hash1;
            byte[] hash2;

            using (DigestStream dgt1 = new DigestStream(new SHA512()))
            {
                dgt1.Initialize(new MemoryStream(data));
                // run concurrent mode
                dgt1.IsConcurrent = true;
                hash1             = dgt1.ComputeHash();
            }

            using (SHA512 dgt2 = new SHA512())
                hash2 = dgt2.ComputeHash(data);

            return(Evaluate.AreEqual(hash1, hash2));
        }
    public bool Verify()
    {
        if (!IsIntegrityProtected())
        {
            throw new PgpException("data not integrity protected.");
        }
        DigestStream digestStream = (DigestStream)encStream;

        while (encStream.ReadByte() >= 0)
        {
        }
        byte[]  lookAhead = truncStream.GetLookAhead();
        IDigest digest    = digestStream.ReadDigest();

        digest.BlockUpdate(lookAhead, 0, 2);
        byte[] array  = DigestUtilities.DoFinal(digest);
        byte[] array2 = new byte[array.Length];
        Array.Copy(lookAhead, 2, array2, 0, array2.Length);
        return(Arrays.ConstantTimeAreEqual(array, array2));
    }
        /**
         * generate a signed object that for a CMS Signed Data
         * object using the given provider - if encapsulate is true a copy
         * of the message will be included in the signature. The content type
         * is set according to the OID represented by the string signedContentType.
         * @param out stream the CMS object is to be written to.
         * @param signedContentType OID for data to be signed.
         * @param encapsulate true if data should be encapsulated.
         * @param dataOutputStream output stream to copy the data being signed to.
         */
        public Stream Open(
            Stream outStream,
            string signedContentType,
            bool encapsulate,
            Stream dataOutputStream)
        {
            if (outStream == null)
            {
                throw new ArgumentNullException("outStream");
            }
            if (!outStream.CanWrite)
            {
                throw new ArgumentException("Expected writeable stream", "outStream");
            }
            if (dataOutputStream != null && !dataOutputStream.CanWrite)
            {
                throw new ArgumentException("Expected writeable stream", "dataOutputStream");
            }

            _messageDigestsLocked = true;

            //
            // ContentInfo
            //
            BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

            //
            // Signed Data
            //
            BerSequenceGenerator sigGen = new BerSequenceGenerator(
                sGen.GetRawOutputStream(), 0, true);

            sigGen.AddObject(CalculateVersion(signedContentType));

            Asn1EncodableVector digestAlgs = new Asn1EncodableVector();

            foreach (string digestOid in _messageDigestOids)
            {
                digestAlgs.Add(
                    new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance));
            }

            {
                byte[] tmp = new DerSet(digestAlgs).GetEncoded();
                sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length);
            }

            BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());

            eiGen.AddObject(new DerObjectIdentifier(signedContentType));

            Stream digStream;

            if (encapsulate)
            {
                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                    eiGen.GetRawOutputStream(), 0, true);

                digStream = octGen.GetOctetOutputStream(_bufferSize);

                if (dataOutputStream != null)
                {
                    digStream = new TeeOutputStream(dataOutputStream, digStream);
                }
            }
            else
            {
                if (dataOutputStream != null)
                {
                    digStream = dataOutputStream;
                }
                else
                {
                    digStream = new NullOutputStream();
                }
            }

            foreach (IDigest d in _messageDigests.Values)
            {
                digStream = new DigestStream(digStream, null, d);
            }

            return(new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen));
        }
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);

            try
            {
                c1.Init(false, privKey.Key);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("error setting asymmetric cipher", e);
            }

            BigInteger[] keyD = keyData.GetEncSessionKey();

            if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt ||
                keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
            {
                byte[] bi = keyD[0].ToByteArray();

                if (bi[0] == 0)
                {
                    c1.ProcessBytes(bi, 1, bi.Length - 1);
                }
                else
                {
                    c1.ProcessBytes(bi, 0, bi.Length);
                }
            }
            else
            {
                ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
                int size = (k.Parameters.P.BitLength + 7) / 8;

                byte[] bi = keyD[0].ToByteArray();

                int diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }

                bi = keyD[1].ToByteArray();

                diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }
            }

            byte[] plain;
            try
            {
                plain = c1.DoFinal();
            }
            catch (Exception e)
            {
                throw new PgpException("exception decrypting secret key", e);
            }

            if (!ConfirmCheckSum(plain))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
//            catch (NoSuchProviderException e)
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                byte[] keyBytes = new byte[plain.Length - 3];
                Array.Copy(plain, 1, keyBytes, 0, keyBytes.Length);

                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, keyBytes);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);
                    encStream   = new DigestStream(truncStream,
                                                   DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1)), null);
                }

                for (int i = 0; i != iv.Length; i++)
                {
                    int ch = encStream.ReadByte();

                    if (ch < 0)
                    {
                        throw new EndOfStreamException("unexpected end of stream.");
                    }

                    iv[i] = (byte)ch;
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
        /// <summary>
        ///     <p>
        ///         If buffer is non null stream assumed to be partial, otherwise the length will be used
        ///         to output a fixed length packet.
        ///     </p>
        ///     <p>
        ///         The stream created can be closed off by either calling Close()
        ///         on the stream or Close() on the generator. Closing the returned
        ///         stream does not close off the Stream parameter <c>outStr</c>.
        ///     </p>
        /// </summary>
        private Stream Open(Stream outStr, long length, byte[] buffer)
        {
            if (_cOut != null)
            {
                throw new InvalidOperationException("generator already in open state");
            }
            if (_methods.Count == 0)
            {
                throw new InvalidOperationException("No encryption methods specified");
            }
            if (outStr == null)
            {
                throw new ArgumentNullException("outStr");
            }

            _pOut = new BcpgOutputStream(outStr);

            KeyParameter key;

            if (_methods.Count == 1)
            {
                var pbeMethod = _methods[0] as PbeMethod;
                if (pbeMethod != null)
                {
                    key = pbeMethod.GetKey();
                }
                else
                {
                    var pubMethod = (PubMethod)_methods[0];

                    key = PgpUtilities.MakeRandomKey(_defAlgorithm, _rand);

                    var sessionInfo = CreateSessionInfo(_defAlgorithm, key);


                    try
                    {
                        pubMethod.AddSessionInfo(sessionInfo, _rand);
                    }
                    catch (Exception e)
                    {
                        throw new PgpException("exception encrypting session key", e);
                    }
                }

                _pOut.WritePacket((ContainedPacket)_methods[0]);
            }
            else // multiple methods
            {
                key = PgpUtilities.MakeRandomKey(_defAlgorithm, _rand);
                var sessionInfo = CreateSessionInfo(_defAlgorithm, key);

                for (var i = 0; i != _methods.Count; i++)
                {
                    var m = (EncMethod)_methods[i];

                    try
                    {
                        m.AddSessionInfo(sessionInfo, _rand);
                    }
                    catch (Exception e)
                    {
                        throw new PgpException("exception encrypting session key", e);
                    }

                    _pOut.WritePacket(m);
                }
            }

            var cName = PgpUtilities.GetSymmetricCipherName(_defAlgorithm);

            if (cName == null)
            {
                throw new PgpException("null cipher specified");
            }

            try
            {
                if (_withIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                _c = CipherUtilities.GetCipher(cName);

                // TODO Confirm the IV should be all zero bytes (not inLineIv - see below)
                var iv = new byte[_c.GetBlockSize()];
                _c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), _rand));

                if (buffer == null)
                {
                    //
                    // we have to Add block size + 2 for the Generated IV and + 1 + 22 if integrity protected
                    //
                    if (_withIntegrityPacket)
                    {
                        _pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected,
                                                     length + _c.GetBlockSize() + 2 + 1 + 22);
                        _pOut.WriteByte(1); // version number
                    }
                    else
                    {
                        _pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted,
                                                     length + _c.GetBlockSize() + 2, _oldFormat);
                    }
                }
                else
                {
                    if (_withIntegrityPacket)
                    {
                        _pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, buffer);
                        _pOut.WriteByte(1); // version number
                    }
                    else
                    {
                        _pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, buffer);
                    }
                }

                var blockSize = _c.GetBlockSize();
                var inLineIv  = new byte[blockSize + 2];
                _rand.NextBytes(inLineIv, 0, blockSize);
                Array.Copy(inLineIv, inLineIv.Length - 4, inLineIv, inLineIv.Length - 2, 2);

                Stream myOut = _cOut = new CipherStream(_pOut, null, _c);

                if (_withIntegrityPacket)
                {
                    var digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    var digest     = DigestUtilities.GetDigest(digestName);
                    myOut = _digestOut = new DigestStream(myOut, null, digest);
                }

                myOut.Write(inLineIv, 0, inLineIv.Length);

                return(new WrappedGeneratorStream(this, myOut));
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }
        }
        /// <summary>Return the decrypted input stream, using the passed in passphrase.</summary>
        public Stream GetDataStream(
            char[] passPhrase)
        {
            IBufferedCipher c;

            try
            {
                SymmetricKeyAlgorithmTag alg = keyData.EncAlgorithm;

                string cName = PgpUtilities.GetSymmetricCipherName(alg);

                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c != null)
            {
                try
                {
                    KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(
                        keyData.EncAlgorithm, keyData.S2k, passPhrase);

                    byte[] iv = new byte[c.GetBlockSize()];

                    c.Init(false, new ParametersWithIV(key, iv));

                    encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null));

                    if (encData is SymmetricEncIntegrityPacket)
                    {
                        truncStream = new TruncatedStream(encStream);

                        string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                        IDigest digest     = DigestUtilities.GetDigest(digestName);

                        encStream = new DigestStream(truncStream, digest, null);
                    }

                    for (int i = 0; i != iv.Length; i++)
                    {
                        int ch = encStream.ReadByte();

                        if (ch < 0)
                        {
                            throw new EndOfStreamException("unexpected end of stream.");
                        }

                        iv[i] = (byte)ch;
                    }

                    int v1 = encStream.ReadByte();
                    int v2 = encStream.ReadByte();

                    if (v1 < 0 || v2 < 0)
                    {
                        throw new EndOfStreamException("unexpected end of stream.");
                    }


                    // Note: the oracle attack on the "quick check" bytes is not deemed
                    // a security risk for PBE (see PgpPublicKeyEncryptedData)

                    bool repeatCheckPassed =
                        iv[iv.Length - 2] == (byte)v1 &&
                        iv[iv.Length - 1] == (byte)v2;

                    // Note: some versions of PGP appear to produce 0 for the extra
                    // bytes rather than repeating the two previous bytes
                    bool zeroesCheckPassed =
                        v1 == 0 &&
                        v2 == 0;

                    if (!repeatCheckPassed && !zeroesCheckPassed)
                    {
                        throw new PgpDataValidationException("quick check failed.");
                    }


                    return(encStream);
                }
                catch (PgpException e)
                {
                    throw e;
                }
                catch (Exception e)
                {
                    throw new PgpException("Exception creating cipher", e);
                }
            }
            else
            {
                return(encData.GetInputStream());
            }
        }
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            byte[] plain = fetchSymmetricKeyData(privKey);

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, plain, 1, plain.Length - 3);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);

                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);

                    encStream = new DigestStream(truncStream, digest, null);
                }

                if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
예제 #27
0
        private void UpgradeNavigationMeshGroups(IEnumerable <PackageLoadingAssetFile> navigationMeshAssets, PackageLoadingAssetFile gameSettingsAsset)
        {
            // Collect all unique groups from all navigation mesh assets
            Dictionary <ObjectId, YamlMappingNode> agentSettings = new Dictionary <ObjectId, YamlMappingNode>();

            foreach (var navigationMeshAsset in navigationMeshAssets)
            {
                using (var navigationMesh = navigationMeshAsset.AsYamlAsset())
                {
                    HashSet <ObjectId> selectedGroups = new HashSet <ObjectId>();
                    foreach (var setting in navigationMesh.DynamicRootNode.NavigationMeshAgentSettings)
                    {
                        var currentAgentSettings = setting.Value;
                        using (DigestStream digestStream = new DigestStream(Stream.Null))
                        {
                            BinarySerializationWriter writer = new BinarySerializationWriter(digestStream);
                            writer.Write((float)currentAgentSettings.Height);
                            writer.Write((float)currentAgentSettings.Radius);
                            writer.Write((float)currentAgentSettings.MaxClimb);
                            writer.Write((float)currentAgentSettings.MaxSlope.Radians);
                            if (!agentSettings.ContainsKey(digestStream.CurrentHash))
                            {
                                agentSettings.Add(digestStream.CurrentHash, currentAgentSettings.Node);
                            }
                            selectedGroups.Add(digestStream.CurrentHash);
                        }
                    }

                    // Replace agent settings with group reference on the navigation mesh
                    navigationMesh.DynamicRootNode.NavigationMeshAgentSettings = DynamicYamlEmpty.Default;
                    dynamic selectedGroupsMapping = navigationMesh.DynamicRootNode.SelectedGroups = new DynamicYamlMapping(new YamlMappingNode());
                    foreach (var selectedGroup in selectedGroups)
                    {
                        selectedGroupsMapping.AddChild(Guid.NewGuid().ToString("N"), selectedGroup.ToGuid().ToString("D"));
                    }
                }
            }

            // Add them to the game settings
            int groupIndex = 0;

            using (var gameSettings = gameSettingsAsset.AsYamlAsset())
            {
                var defaults = gameSettings.DynamicRootNode.Defaults;
                foreach (var setting in defaults)
                {
                    if (setting.Node.Tag == "!Xenko.Navigation.NavigationSettings,Xenko.Navigation")
                    {
                        var groups = setting.Groups as DynamicYamlArray;
                        foreach (var groupToAdd in agentSettings)
                        {
                            dynamic newGroup = new DynamicYamlMapping(new YamlMappingNode());
                            newGroup.Id            = groupToAdd.Key.ToGuid().ToString("D");
                            newGroup.Name          = $"Group {groupIndex++}";
                            newGroup.AgentSettings = groupToAdd.Value;
                            groups.Add(newGroup);
                        }
                    }
                }
            }
        }
예제 #28
0
        /**
         * generate a signed object that for a CMS Signed Data
         * object - if encapsulate is true a copy
         * of the message will be included in the signature. The content type
         * is set according to the OID represented by the string signedContentType.
         */
        public Stream Open(
            Stream outStream,
            string signedContentType,
            bool encapsulate)
        {
            //
            // ContentInfo
            //
            BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

            //
            // Signed Data
            //
            BerSequenceGenerator sigGen = new BerSequenceGenerator(
                sGen.GetRawOutputStream(), 0, true);

            sigGen.AddObject(CalculateVersion(signedContentType));

            Asn1EncodableVector digestAlgs = new Asn1EncodableVector();

            //
            // add the precalculated SignerInfo digest algorithms.
            //
            foreach (SignerInformation signer in _signers)
            {
                digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID));
            }

            //
            // add the new digests
            //
            foreach (SignerInf signer in _signerInfs)
            {
                digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID));
            }

            {
                byte[] tmp = new DerSet(digestAlgs).GetEncoded();
                sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length);
            }

            BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());

            eiGen.AddObject(new DerObjectIdentifier(signedContentType));

            Stream digStream;

            if (encapsulate)
            {
                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                    eiGen.GetRawOutputStream(), 0, true);

                if (_bufferSize != 0)
                {
                    digStream = octGen.GetOctetOutputStream(new byte[_bufferSize]);
                }
                else
                {
                    digStream = octGen.GetOctetOutputStream();
                }
            }
            else
            {
                digStream = new NullOutputStream();
            }

            foreach (IDigest d in _messageDigests)
            {
                digStream = new DigestStream(digStream, null, d);
            }

            return(new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen));
        }
        /// <summary>Return the decrypted input stream, using the passed in passphrase.</summary>
        public Stream GetDataStream(char[] passPhrase)
        {
            try
            {
                var keyAlgorithm = _keyData.EncAlgorithm;

                var key = PgpUtilities.MakeKeyFromPassPhrase(
                    keyAlgorithm, _keyData.S2K, passPhrase);


                var secKeyData = _keyData.GetSecKeyData();
                if (secKeyData != null && secKeyData.Length > 0)
                {
                    var keyCipher = CipherUtilities.GetCipher(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding");

                    keyCipher.Init(false,
                                   new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()]));

                    var keyBytes = keyCipher.DoFinal(secKeyData);

                    keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0];

                    key = ParameterUtilities.CreateKeyParameter(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm),
                        keyBytes, 1, keyBytes.Length - 1);
                }


                var c = CreateStreamCipher(keyAlgorithm);

                var iv = new byte[c.GetBlockSize()];

                c.Init(false, new ParametersWithIV(key, iv));

                EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c, null));

                if (EncData is SymmetricEncIntegrityPacket)
                {
                    TruncStream = new TruncatedStream(EncStream);

                    var digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    var digest     = DigestUtilities.GetDigest(digestName);

                    EncStream = new DigestStream(TruncStream, digest, null);
                }

                if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                var v1 = EncStream.ReadByte();
                var v2 = EncStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }


                // Note: the oracle attack on the "quick check" bytes is not deemed
                // a security risk for PBE (see PgpPublicKeyEncryptedData)

                var repeatCheckPassed =
                    iv[iv.Length - 2] == (byte)v1 &&
                    iv[iv.Length - 1] == (byte)v2;

                // Note: some versions of PGP appear to produce 0 for the extra
                // bytes rather than repeating the two previous bytes
                var zeroesCheckPassed = v1 == 0 && v2 == 0;
                if (!repeatCheckPassed && !zeroesCheckPassed)
                {
                    throw new PgpDataValidationException("quick check failed.");
                }


                return(EncStream);
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }
        }
예제 #30
0
        private Stream Open(Stream outStr, long length, byte[] buffer)
        {
            //IL_000d: Unknown result type (might be due to invalid IL or missing references)
            //IL_0025: Unknown result type (might be due to invalid IL or missing references)
            //IL_0033: Unknown result type (might be due to invalid IL or missing references)
            if (cOut != null)
            {
                throw new InvalidOperationException("generator already in open state");
            }
            if (((global::System.Collections.ICollection)methods).get_Count() == 0)
            {
                throw new InvalidOperationException("No encryption methods specified");
            }
            if (outStr == null)
            {
                throw new ArgumentNullException("outStr");
            }
            pOut = new BcpgOutputStream(outStr);
            KeyParameter keyParameter;

            if (((global::System.Collections.ICollection)methods).get_Count() == 1)
            {
                if (methods.get_Item(0) is PbeMethod)
                {
                    PbeMethod pbeMethod = (PbeMethod)methods.get_Item(0);
                    keyParameter = pbeMethod.GetKey();
                }
                else
                {
                    keyParameter = PgpUtilities.MakeRandomKey(defAlgorithm, rand);
                    byte[]    si        = CreateSessionInfo(defAlgorithm, keyParameter);
                    PubMethod pubMethod = (PubMethod)methods.get_Item(0);
                    try
                    {
                        pubMethod.AddSessionInfo(si, rand);
                    }
                    catch (global::System.Exception exception)
                    {
                        throw new PgpException("exception encrypting session key", exception);
                    }
                }
                pOut.WritePacket((ContainedPacket)methods.get_Item(0));
            }
            else
            {
                keyParameter = PgpUtilities.MakeRandomKey(defAlgorithm, rand);
                byte[] si2 = CreateSessionInfo(defAlgorithm, keyParameter);
                for (int i = 0; i != ((global::System.Collections.ICollection)methods).get_Count(); i++)
                {
                    EncMethod encMethod = (EncMethod)methods.get_Item(i);
                    try
                    {
                        encMethod.AddSessionInfo(si2, rand);
                    }
                    catch (global::System.Exception exception2)
                    {
                        throw new PgpException("exception encrypting session key", exception2);
                    }
                    pOut.WritePacket(encMethod);
                }
            }
            string symmetricCipherName = PgpUtilities.GetSymmetricCipherName(defAlgorithm);

            if (symmetricCipherName == null)
            {
                throw new PgpException("null cipher specified");
            }
            try
            {
                symmetricCipherName = ((!withIntegrityPacket) ? (symmetricCipherName + "/OpenPGPCFB/NoPadding") : (symmetricCipherName + "/CFB/NoPadding"));
                c = CipherUtilities.GetCipher(symmetricCipherName);
                byte[] iv = new byte[c.GetBlockSize()];
                c.Init(forEncryption: true, new ParametersWithRandom(new ParametersWithIV(keyParameter, iv), rand));
                if (buffer == null)
                {
                    if (withIntegrityPacket)
                    {
                        pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, length + c.GetBlockSize() + 2 + 1 + 22);
                        ((Stream)pOut).WriteByte((byte)1);
                    }
                    else
                    {
                        pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, length + c.GetBlockSize() + 2, oldFormat);
                    }
                }
                else if (withIntegrityPacket)
                {
                    pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, buffer);
                    ((Stream)pOut).WriteByte((byte)1);
                }
                else
                {
                    pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, buffer);
                }
                int    blockSize = c.GetBlockSize();
                byte[] array     = new byte[blockSize + 2];
                rand.NextBytes(array, 0, blockSize);
                global::System.Array.Copy((global::System.Array)array, array.Length - 4, (global::System.Array)array, array.Length - 2, 2);
                Stream val = (Stream)(object)(cOut = new CipherStream((Stream)(object)pOut, null, c));
                if (withIntegrityPacket)
                {
                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);
                    val = (Stream)(object)(digestOut = new DigestStream(val, null, digest));
                }
                val.Write(array, 0, array.Length);
                return((Stream)(object)new WrappedGeneratorStream(this, val));
            }
            catch (global::System.Exception exception3)
            {
                throw new PgpException("Exception creating cipher", exception3);
            }
        }