Example #1
0
        private static void VerifyIncrementalResult(HashAlgorithm referenceAlgorithm, IncrementalHash incrementalHash)
        {
            byte[] referenceHash = referenceAlgorithm.ComputeHash(s_inputBytes);
            const int StepA = 13;
            const int StepB = 7;

            int position = 0;

            while (position < s_inputBytes.Length - StepA)
            {
                incrementalHash.AppendData(s_inputBytes, position, StepA);
                position += StepA;
            }

            incrementalHash.AppendData(s_inputBytes, position, s_inputBytes.Length - position);

            byte[] incrementalA = incrementalHash.GetHashAndReset();
            Assert.Equal(referenceHash, incrementalA);

            // Now try again, verifying both immune to step size behaviors, and that GetHashAndReset resets.
            position = 0;

            while (position < s_inputBytes.Length - StepB)
            {
                incrementalHash.AppendData(s_inputBytes, position, StepA);
                position += StepA;
            }

            incrementalHash.AppendData(s_inputBytes, position, s_inputBytes.Length - position);

            byte[] incrementalB = incrementalHash.GetHashAndReset();
            Assert.Equal(referenceHash, incrementalB);
        }
Example #2
0
        public void SignDataVerifyHash_SHA1(DSASignatureFormat signatureFormat)
        {
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1;

            KeyDescription key = GetKey();

            byte[] signature = SignData(key, _typeNameBytes, hashAlgorithm, signatureFormat);
            CheckLength(key, signature, signatureFormat);

            using (IncrementalHash hash = IncrementalHash.CreateHash(hashAlgorithm))
            {
                hash.AppendData(_typeNameBytes);
                Assert.True(VerifyHash(key, hash.GetHashAndReset(), signature, signatureFormat));
            }
        }
Example #3
0
            public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
            {
                // TODO: This is an inefficient copy
                var block = inputBuffer.Take(inputOffset, inputCount);

                // Add the cipher text to the running hash
                _hmac.AppendData(block);

                // Add the associated_data_length bytes to the hash
                _hmac.AppendData(_associated_data_length);

                // Compute the tag
                _tag = _hmac.GetHashAndReset();

                return(_inner.TransformFinalBlock(inputBuffer, inputOffset, inputCount));
            }
Example #4
0
        public override void Flush()
        {
            FlushFinalBlock();
            byte[] cipherBuffer = new byte[Aes.BlockSize];
            int    read         = TmpStream.Read(cipherBuffer, 0, cipherBuffer.Length);

            while (read > 0)
            {
                Mac.AppendData(cipherBuffer, 0, read);
                base.Write(cipherBuffer, 0, read);
                read = TmpStream.Read(cipherBuffer, 0, cipherBuffer.Length);
            }
            byte[] auth = Mac.GetHashAndReset();
            base.Write(auth, 0, auth.Length);
            base.Flush();
        }
Example #5
0
        public static void VerifyEmptyHash(HashAlgorithm referenceAlgorithm, HashAlgorithmName hashAlgorithm)
        {
            using (referenceAlgorithm)
                using (IncrementalHash incrementalHash = IncrementalHash.CreateHash(hashAlgorithm))
                {
                    for (int i = 0; i < 10; i++)
                    {
                        incrementalHash.AppendData(Array.Empty <byte>());
                    }

                    byte[] referenceHash     = referenceAlgorithm.ComputeHash(Array.Empty <byte>());
                    byte[] incrementalResult = incrementalHash.GetHashAndReset();

                    Assert.Equal(referenceHash, incrementalResult);
                }
        }
            public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
            {
                // Encrypt the block
                var result = _inner.TransformFinalBlock(inputBuffer, inputOffset, inputCount);

                // Add it to the running hash
                _hmac.AppendData(result);

                // Add the associated_data_length bytes to the hash
                _hmac.AppendData(_associated_data_length);

                // Compute the tag
                _tag = _hmac.GetHashAndReset().Take(_hmac_key.Length);

                return(result);
            }
Example #7
0
        async Task CompleteCurrent(CancellationToken cancel)
        {
            if (stream == null)
            {
                return;
            }

            var hashResult = hash.GetHashAndReset();

            stream.Dispose();
            await streamProvider.Completed(stream, chunkOffset, chunkLength, hashResult, cancel).ConfigureAwait(false);

            chunkLength = 0;
            chunkOffset = position;
            stream      = null;
            hash        = null;
        }
Example #8
0
        private string GetDirectoryHash(string directory)
        {
            var files = Directory.EnumerateFiles(directory, "*.*", SearchOption.AllDirectories).OrderBy(x => x);

            using (IncrementalHash md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5))
            {
                foreach (var f in files)
                {
                    FileInfo info = new FileInfo(f);
                    md5.AppendData(Encoding.UTF8.GetBytes(info.FullName));                  //path
                    md5.AppendData(BitConverter.GetBytes(info.Length));                     //size
                    md5.AppendData(BitConverter.GetBytes(info.LastWriteTimeUtc.Ticks));     //last written
                }

                return((!files.Any() ? new byte[16] : md5.GetHashAndReset()).ToMD5String());                //Enforce empty hash string if no files
            }
        }
        private BsonDocument CreateFilesCollectionDocument()
        {
            var uploadDateTime = DateTime.UtcNow;

            return(new BsonDocument
            {
                { "_id", _idAsBsonValue },
                { "length", _length },
                { "chunkSize", _chunkSizeBytes },
                { "uploadDate", uploadDateTime },
                { "md5", () => BsonUtils.ToHexString(_md5.GetHashAndReset()), !_disableMD5 },
                { "filename", _filename },
                { "contentType", _contentType, _contentType != null },
                { "aliases", () => new BsonArray(_aliases.Select(a => new BsonString(a))), _aliases != null },
                { "metadata", _metadata, _metadata != null }
            });
        }
Example #10
0
        public IHttpActionResult eBayAccountDeletionGet(string challenge_code)
        {
            var verificationToken = "ZUJheUFjY291bnREZWxldGlvblRva2VuamltMDUxOQ==";
            var endpoint          = this.Request.RequestUri.AbsoluteUri;

            IncrementalHash sha256 = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);

            sha256.AppendData(Encoding.UTF8.GetBytes(challenge_code));
            sha256.AppendData(Encoding.UTF8.GetBytes(verificationToken));
            sha256.AppendData(Encoding.UTF8.GetBytes(endpoint));
            byte[] bytes = sha256.GetHashAndReset();
            var    retChallengeResponse = BitConverter.ToString(bytes).Replace("-", string.Empty).ToLower();


            return(Json(new { challengeResponse = retChallengeResponse }));

            //return Ok();
        }
        public static async Task <byte[]> ComputeHashAsync(this IncrementalHash algorithm, Stream inputStream, int bufferSize = 4096)
        {
            var buffer = new byte[bufferSize];

            while (true)
            {
                var read = await inputStream.ReadAsync(buffer, 0, bufferSize);

                if (read == 0)
                {
                    break;
                }

                algorithm.AppendData(buffer, 0, read);
            }

            return(algorithm.GetHashAndReset());
        }
Example #12
0
        /// <summary>
        /// compute the hash of a stream
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="hash"></param>
        /// <returns>hash bytes</returns>
        /// <remarks>
        /// this attempts to return the stream to the position it started from
        /// this makes it easy to compute the hash of a file, then directly
        /// read from the file for encryption/transmission/etc.
        /// </remarks>
        private byte[] _computeHash(Stream strm, IncrementalHash hash)
        {
            if (!strm.CanRead)
            {
                return(null);
            }
            long curpos = strm.Position;

            _writeBytesToHash(strm, hash);
            var hashoenc = hash.GetHashAndReset();

            if (strm.CanSeek)
            {
                strm.Seek(curpos, System.IO.SeekOrigin.Begin);
            }

            return(hashoenc);
        }
Example #13
0
        public bool TryWrite(Span <byte> buffer, out int written, ParsedFormat format = default)
        {
            if (!format.IsDefault)
            {
                throw new ArgumentOutOfRangeException(nameof(format));
            }
            if (buffer.Length < OutputSize)
            {
                written = 0; return(false);
            }

            var hash = _hash.GetHashAndReset();

            Debug.Assert(hash.Length == OutputSize);
            hash.AsSpan().CopyTo(buffer);

            written = OutputSize;
            return(true);
        }
Example #14
0
        /// <summary>
        /// Asynchronously calculate hash of all data in provided stream
        /// </summary>
        /// <param name="stream">Input stream containing data (caller is responsible for disposing)</param>
        /// <param name="hashprovider">Hash provider created by caller (who is responsible for disposing)</param>
        /// <remarks>
        /// Stream is assumed to be at Position 0 when received, and will be at ending position when returned; caller
        /// is responsible for resetting stream position after calling this function, if data must still be read
        /// </remarks>
        public static async Task <byte[]> GetStreamHash(Stream stream, IncrementalHash hashprovider)
        {
            var buffer = new byte[1024];

            while (stream.CanRead)
            {
                int br = await stream.ReadAsync(buffer, 0, 1000);

                if (br > 0)
                {
                    hashprovider.AppendData(buffer, 0, br);
                }
                else
                {
                    break;
                }
            }
            return(hashprovider.GetHashAndReset());
        }
Example #15
0
        private BEncodedString GetToken(Node node, byte[] secret)
        {
            //refresh secret if needed
            if (_lastSecretGeneration.Add(Timeout) < DateTime.UtcNow)
            {
                _lastSecretGeneration = DateTime.UtcNow;
                _secret.CopyTo(_previousSecret, 0);

                //PORT NOTE: Used GetNonZeroBytes() here before
                _random.GetBytes(_secret);
            }

            byte[] compactNode = node.CompactAddressPort().TextBytes;

            _sha1.AppendData(compactNode);
            _sha1.AppendData(secret);

            return(_sha1.GetHashAndReset());
        }
Example #16
0
        private static void VerifyGetCurrentHash(IncrementalHash single, IncrementalHash accumulated)
        {
            Span <byte> buf        = stackalloc byte[2048];
            Span <byte> fullDigest = stackalloc byte[512 / 8];
            Span <byte> curDigest  = stackalloc byte[fullDigest.Length];

            SequenceFill(buf);

            int       count = 0;
            const int Step  = 13;
            int       writtenA;
            int       writtenB;

            while (count + Step < buf.Length)
            {
                // Accumulate only the current slice
                accumulated.AppendData(buf.Slice(count, Step));

                // The comparison needs the whole thing, since we're
                // comparing GetHashAndReset vs GetCurrentHash.
                count += Step;
                single.AppendData(buf.Slice(0, count));

                writtenA = single.GetHashAndReset(fullDigest);
                writtenB = accumulated.GetCurrentHash(curDigest);

                Assert.Equal(
                    fullDigest.Slice(0, writtenA).ByteArrayToHex(),
                    curDigest.Slice(0, writtenB).ByteArrayToHex());
            }

            accumulated.AppendData(buf.Slice(count));
            single.AppendData(buf);

            writtenA = single.GetHashAndReset(fullDigest);

            // Drain/reset accumulated with this last call
            writtenB = accumulated.GetHashAndReset(curDigest);

            Assert.Equal(
                fullDigest.Slice(0, writtenA).ByteArrayToHex(),
                curDigest.Slice(0, writtenB).ByteArrayToHex());
        }
Example #17
0
        public byte[] GeneratePkgListKey(int key, string packageIndexName)
        {
            IncrementalHash md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5);

            md5.AppendData(new byte[] { 2, 0, 0, 0 });

            if (Convert.ToBoolean(key % 2))
            {
                md5.AppendData(s_PackageListKey[key / 2]);
                md5.AppendData(Encoding.Default.GetBytes(packageIndexName));
            }
            else
            {
                md5.AppendData(Encoding.Default.GetBytes(packageIndexName));
                md5.AppendData(s_PackageListKey[key / 2]);
            }

            return(md5.GetHashAndReset());
        }
Example #18
0
        /// <summary>
        /// Creates a name-based UUID using the algorithm from RFC 4122 §4.3.
        /// </summary>
        /// <param name="namespaceId">The ID of the namespace.</param>
        /// <param name="name">The name (within that namespace).</param>
        /// <param name="version">The version number of the UUID to create; this value must be either
        /// 3 (for MD5 hashing) or 5 (for SHA-1 hashing).</param>
        /// <returns>A UUID derived from the namespace and name.</returns>
        /// <remarks>See <a href="http://code.logos.com/blog/2011/04/generating_a_deterministic_guid.html">Generating a deterministic GUID</a>.</remarks>
        public static Guid Create(Guid namespaceId, string name, int version)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (version != 3 && version != 5)
            {
                throw new ArgumentOutOfRangeException(nameof(version), "version must be either 3 or 5.");
            }

            // convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3)
            // ASSUME: UTF-8 encoding is always appropriate
            byte[] nameBytes = Encoding.UTF8.GetBytes(name);

            // convert the namespace UUID to network order (step 3)
            byte[] namespaceBytes = namespaceId.ToByteArray();
            SwapByteOrder(namespaceBytes);

            // compute the hash of the name space ID concatenated with the name (step 4)
            byte[] hash;
            using (IncrementalHash incrementalHash = IncrementalHash.CreateHash(version == 3 ? HashAlgorithmName.MD5 : HashAlgorithmName.SHA1))
            {
                incrementalHash.AppendData(namespaceBytes);
                incrementalHash.AppendData(nameBytes);
                hash = incrementalHash.GetHashAndReset();
            }

            // most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12)
            byte[] newGuid = new byte[16];
            Array.Copy(hash, 0, newGuid, 0, 16);

            // set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3 (step 8)
            newGuid[6] = (byte)((newGuid[6] & 0x0F) | (version << 4));

            // set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively (step 10)
            newGuid[8] = (byte)((newGuid[8] & 0x3F) | 0x80);

            // convert the resulting UUID to local byte order (step 13)
            SwapByteOrder(newGuid);
            return(new Guid(newGuid));
        }
Example #19
0
            public void Finish(HttpResponse response, int maxSurrogateKeys)
            {
                if (hasDependency && !response.Headers.ContainsKey(HeaderNames.ETag))
                {
                    using (Profiler.Trace("CalculateEtag"))
                    {
                        var cacheBuffer = hasher.GetHashAndReset();
                        var cacheString = BitConverter.ToString(cacheBuffer).Replace("-", string.Empty).ToUpperInvariant();

                        response.Headers.Add(HeaderNames.ETag, cacheString);
                    }
                }

                if (keys.Count <= maxSurrogateKeys)
                {
                    var value = string.Join(" ", keys);

                    response.Headers.Add("Surrogate-Key", value);
                }
            }
Example #20
0
        public IHttpActionResult eBayAccountDeletionGet(string challenge_code)
        {
            string verificationToken = Convert.ToBase64String(Encoding.ASCII.GetBytes("eBayAccountDeletionTokenjim0519"));

            verificationToken = new string(verificationToken.Where(c => char.IsLetter(c)).ToArray());
            //verificationToken = "ZUJheUFjYbnREZWxldGlvblRvaVuamltMDUxOQ";
            var endpoint = this.Request.RequestUri.AbsoluteUri.Replace(this.Request.RequestUri.Query, "");

            IncrementalHash sha256 = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);

            sha256.AppendData(Encoding.UTF8.GetBytes(challenge_code));
            sha256.AppendData(Encoding.UTF8.GetBytes(verificationToken));
            sha256.AppendData(Encoding.UTF8.GetBytes(endpoint));
            byte[] bytes = sha256.GetHashAndReset();
            var    retChallengeResponse = BitConverter.ToString(bytes).Replace("-", string.Empty).ToLower();


            return(Json(new { challengeResponse = retChallengeResponse }));

            //return Ok();
        }
Example #21
0
        /// <summary>
        /// Returns the 10 byte AUTH CODE to be checked or appended immediately following the AES data stream.
        /// </summary>
        public byte[] GetAuthCode()
        {
            // We usually don't get advance notice of final block. Hash requres a TransformFinal.
            if (!_finalised)
            {
                var dummy = new byte[0];

#if !OS_WINDOWS
                incrementalHash.AppendData(dummy, 0, 0);
#else
                _hmacsha1.TransformFinalBlock(dummy, 0, 0);
#endif
                _finalised = true;
            }
#if !OS_WINDOWS
            byte[] incrementalA = incrementalHash.GetHashAndReset();
            return(incrementalA);
#else
            return(_hmacsha1.Hash);
#endif
        }
Example #22
0
        /// <summary>
        /// Check the given arguments and throw a <see cref="NetMQSecurityException"/> if something is amiss.
        /// </summary>
        /// <param name="contentType">This identifies the type of content: ChangeCipherSpec, Handshake, or ApplicationData.</param>
        /// <param name="seqNum"></param>
        /// <param name="frameIndex"></param>
        /// <param name="plainBytes"></param>
        /// <param name="mac"></param>
        /// <param name="padding"></param>
        /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.MACNotMatched"/>: MAC does not match message.</exception>
        public void ValidateBytes(ContentType contentType, ulong seqNum, int frameIndex,
                                  byte[] plainBytes, byte[] mac, byte[] padding)
        {
            if (SecurityParameters.MACAlgorithm != MACAlgorithm.Null)
            {
                byte[] seqNumBytes     = BitConverter.GetBytes(seqNum);
                byte[] versionAndType  = new[] { (byte)contentType, m_protocolVersion[0], m_protocolVersion[1] };
                byte[] messageSize     = BitConverter.GetBytes(plainBytes.Length);
                byte[] frameIndexBytes = BitConverter.GetBytes(frameIndex);

                //m_decryptionHMAC.Initialize();
                //m_decryptionHMAC.TransformBlock(seqNumBytes, 0, seqNumBytes.Length, seqNumBytes, 0);
                //m_decryptionHMAC.TransformBlock(versionAndType, 0, versionAndType.Length, versionAndType, 0);
                //m_decryptionHMAC.TransformBlock(messageSize, 0, messageSize.Length, messageSize, 0);
                //m_decryptionHMAC.TransformBlock(frameIndexBytes, 0, frameIndexBytes.Length, frameIndexBytes, 0);
                //m_decryptionHMAC.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

                //var hash = m_decryptionHMAC.Hash;

                m_decryptionHMAC.AppendData(seqNumBytes);
                m_decryptionHMAC.AppendData(versionAndType);
                m_decryptionHMAC.AppendData(messageSize);
                m_decryptionHMAC.AppendData(frameIndexBytes);
                m_decryptionHMAC.AppendData(plainBytes);
                var hash = m_decryptionHMAC.GetHashAndReset();

                if (!hash.SequenceEqual(mac))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.MACNotMatched, "MAC does not match message");
                }

                for (int i = 0; i < padding.Length; i++)
                {
                    if (padding[i] != padding.Length - 1)
                    {
                        throw new NetMQSecurityException(NetMQSecurityErrorCode.MACNotMatched, "MAC not matched message");
                    }
                }
            }
        }
Example #23
0
        public void SignatureFormatsAreNotCompatible(DSASignatureFormat signFormat, DSASignatureFormat verifyFormat)
        {
            if (!SupportsSha2)
            {
                return;
            }

            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1;
            const int         RetryCount    = 10;

            KeyDescription key = GetKey();

            byte[] hash;

            using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm))
            {
                hasher.AppendData(_typeNameBytes);
                hash = hasher.GetHashAndReset();
            }

            for (int i = 0; i < RetryCount; i++)
            {
                byte[] signature = SignData(
                    key,
                    _typeNameBytes,
                    hashAlgorithm,
                    signFormat);

                if (!VerifyData(key, _typeNameBytes, signature, hashAlgorithm, verifyFormat))
                {
                    Assert.False(
                        VerifyHash(key, hash, signature, verifyFormat),
                        $"VerifyHash({verifyFormat}) verifies after VerifyData({verifyFormat}) fails");

                    return;
                }
            }

            Assert.False(true, $"{RetryCount} {signFormat} signatures verified as {verifyFormat} signatures");
        }
Example #24
0
        private static Checksum ComputeChecksum(Stream stream, IncrementalHash hash)
        {
            using (var pooledBuffer = SharedPools.ByteArray.GetPooledObject())
            {
                stream.Seek(0, SeekOrigin.Begin);

                var buffer       = pooledBuffer.Object;
                var bufferLength = buffer.Length;
                int bytesRead;
                do
                {
                    bytesRead = stream.Read(buffer, 0, bufferLength);
                    if (bytesRead > 0)
                    {
                        hash.AppendData(buffer, 0, bytesRead);
                    }
                }while (bytesRead > 0);

                var bytes = hash.GetHashAndReset();
                return(new Checksum(bytes));
            }
        }
        public AMetric Generate(FileInfo file)
        {
            byte[] hash = null;
            using (FileStream fs = file.OpenRead())
            {
                if (fs.Length < 4 * hashedBytesCount)
                {
                    //if file is small enough just compute hash over the whole file, that way we save us the pain of checking for out of bounds etc
                    using (MD5 md5 = MD5.Create())
                    {
                        hash = md5.ComputeHash(fs);
                    }
                }
                else
                {
                    using (IncrementalHash incMd5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5))
                    {
                        byte[] block = new byte[hashedBytesCount];
                        //start
                        fs.Seek(0, SeekOrigin.Begin);
                        fs.Read(block, 0, block.Length);
                        incMd5.AppendData(block);

                        //middle
                        fs.Seek(fs.Length / 2 - hashedBytesCount / 2, SeekOrigin.Begin);
                        fs.Read(block, 0, block.Length);
                        incMd5.AppendData(block);

                        //end
                        fs.Seek(-hashedBytesCount, SeekOrigin.End);
                        fs.Read(block, 0, block.Length);
                        incMd5.AppendData(block);

                        hash = incMd5.GetHashAndReset();
                    }
                }
            }
            return(new HashMetric(hash));
        }
Example #26
0
        public bool TryCreateHash(ExecuteScriptCommandOptions options, out string hash)
        {
            if (options.NoCache)
            {
                _logger.Debug($"The script {options.File.Path} was executed with the '--no-cache' flag. Skipping cache.");
                hash = null;
                return(false);
            }

            var scriptFilesProvider = new ScriptFilesResolver();
            var allScriptFiles      = scriptFilesProvider.GetScriptFiles(options.File.Path);
            var projectFile         = new ScriptProjectProvider(_logFactory).CreateProjectFileFromScriptFiles(ScriptEnvironment.Default.TargetFramework, allScriptFiles.ToArray());

            if (!projectFile.IsCacheable)
            {
                _logger.Warning($"The script {options.File.Path} is not cacheable. For caching and optimal performance, ensure that the script only contains NuGet references with pinned/exact versions.");
                hash = null;
                return(false);
            }


            IncrementalHash incrementalHash = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);

            foreach (var scriptFile in allScriptFiles)
            {
                incrementalHash.AppendData(File.ReadAllBytes(scriptFile));
            }

            var configuration = options.OptimizationLevel.ToString();

            incrementalHash.AppendData(Encoding.UTF8.GetBytes(configuration));

            // Ensure that we don't run with the deps of an old target framework or SDK version.
            incrementalHash.AppendData(Encoding.UTF8.GetBytes(ScriptEnvironment.Default.NetCoreVersion.Tfm));
            incrementalHash.AppendData(Encoding.UTF8.GetBytes(ScriptEnvironment.Default.NetCoreVersion.Version));

            hash = Convert.ToBase64String(incrementalHash.GetHashAndReset());
            return(true);
        }
            public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
            {
                // TODO: This is an inefficient copy
                var block = inputBuffer.Take(inputOffset, inputCount);

                // Add the cipher text to the running hash
                _hmac.AppendData(block);

                // Add the associated_data_length bytes to the hash
                _hmac.AppendData(_associated_data_length);

                // Compute the tag, then compare it against the expected value
                // perform transforming the final block
                var tag = _hmac.GetHashAndReset().Take(_hmac_key.Length);

                if (!tag.SequenceEqualConstantTime(_tag))
                {
                    throw new CryptographicException("Data is no authentic");
                }

                return(_inner.TransformFinalBlock(inputBuffer, inputOffset, inputCount));
            }
        public static Rfc3161TimestampRequest CreateFromData(
            ReadOnlySpan <byte> data,
            HashAlgorithmName hashAlgorithm,
            Oid requestedPolicyId              = null,
            ReadOnlyMemory <byte>?nonce        = null,
            bool requestSignerCertificates     = false,
            X509ExtensionCollection extensions = null)
        {
            using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm))
            {
                hasher.AppendData(data);
                byte[] digest = hasher.GetHashAndReset();

                return(CreateFromHash(
                           digest,
                           hashAlgorithm,
                           requestedPolicyId,
                           nonce,
                           requestSignerCertificates,
                           extensions));
            }
        }
Example #29
0
        private byte Verify(byte[] challenge, String password)
        {
            byte[] passwordHash = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
            logger.Debug($"Password Hash: !{BitConverter.ToString(passwordHash).Replace("-", string.Empty)}!");

            IncrementalHash sha = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);

            sha.AppendData(challenge);
            sha.AppendData(passwordHash);
            byte[] proof = sha.GetHashAndReset();
            logger.Debug($"Proof: !{BitConverter.ToString(proof).Replace("-", string.Empty)}!");

            byte[] proofLength = BitConverter.GetBytes((short)proof.Length);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(proofLength);
            }

            PacketWriter proofPacket = new PacketWriter(TyrannyOpcode.AuthProof);

            proofPacket.Write(proofLength);
            proofPacket.Write(proof);
            tcpClient.Send(proofPacket);

            PacketReader proofAckPacket;

            if (tcpClient.Read(out proofAckPacket))
            {
                byte ack = proofAckPacket.ReadByte();
                logger.Debug($"Got Proof Ack: {ack}");

                return(ack);
            }
            else
            {
                throw new IOException("Failed to receive proof ack");
            }
        }
Example #30
0
        public void SealWithMac(
            ReadOnlySpan <char> password,
            HashAlgorithmName hashAlgorithm,
            int iterationCount)
        {
            if (iterationCount < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(iterationCount));
            }
            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Cryptography_Pkcs12_PfxIsSealed);
            }

            byte[]? rentedAuthSafe = null;
            Span <byte> authSafeSpan = default;

            byte[]? rentedMac = null;
            Span <byte> macSpan = default;
            Span <byte> salt    = stackalloc byte[0];

            try
            {
                AsnWriter contentsWriter = new AsnWriter(AsnEncodingRules.BER);

                using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm))
                {
                    contentsWriter.PushSequence();
                    if (_contents != null)
                    {
                        foreach (ContentInfoAsn contentInfo in _contents)
                        {
                            contentInfo.Encode(contentsWriter);
                        }
                    }
                    contentsWriter.PopSequence();

                    rentedAuthSafe = CryptoPool.Rent(contentsWriter.GetEncodedLength());

                    if (!contentsWriter.TryEncode(rentedAuthSafe, out int written))
                    {
                        Debug.Fail("TryEncode failed with a pre-allocated buffer");
                        throw new InvalidOperationException();
                    }

                    authSafeSpan = rentedAuthSafe.AsSpan(0, written);

                    // Get an array of the proper size for the hash.
                    byte[] macKey = hasher.GetHashAndReset();
                    rentedMac = CryptoPool.Rent(macKey.Length);
                    macSpan   = rentedMac.AsSpan(0, macKey.Length);

                    // Since the biggest supported hash is SHA-2-512 (64 bytes), the
                    // 128-byte cap here shouldn't ever come into play.
                    Debug.Assert(macKey.Length <= 128);
                    salt = stackalloc byte[Math.Min(macKey.Length, 128)];
                    RandomNumberGenerator.Fill(salt);

                    Pkcs12Kdf.DeriveMacKey(
                        password,
                        hashAlgorithm,
                        iterationCount,
                        salt,
                        macKey);

                    using (IncrementalHash mac = IncrementalHash.CreateHMAC(hashAlgorithm, macKey))
                    {
                        mac.AppendData(authSafeSpan);

                        if (!mac.TryGetHashAndReset(macSpan, out int bytesWritten) || bytesWritten != macSpan.Length)
                        {
                            Debug.Fail($"TryGetHashAndReset wrote {bytesWritten} of {macSpan.Length} bytes");
                            throw new CryptographicException();
                        }
                    }
                }

                // https://tools.ietf.org/html/rfc7292#section-4
                //
                // PFX ::= SEQUENCE {
                //   version    INTEGER {v3(3)}(v3,...),
                //   authSafe   ContentInfo,
                //   macData    MacData OPTIONAL
                // }
                AsnWriter writer = new AsnWriter(AsnEncodingRules.BER);
                {
                    writer.PushSequence();

                    writer.WriteInteger(3);

                    writer.PushSequence();
                    {
                        writer.WriteObjectIdentifierForCrypto(Oids.Pkcs7Data);

                        Asn1Tag contextSpecific0 = new Asn1Tag(TagClass.ContextSpecific, 0);

                        writer.PushSequence(contextSpecific0);
                        {
                            writer.WriteOctetString(authSafeSpan);
                            writer.PopSequence(contextSpecific0);
                        }

                        writer.PopSequence();
                    }

                    // https://tools.ietf.org/html/rfc7292#section-4
                    //
                    // MacData ::= SEQUENCE {
                    //   mac        DigestInfo,
                    //   macSalt    OCTET STRING,
                    //   iterations INTEGER DEFAULT 1
                    //   -- Note: The default is for historical reasons and its use is
                    //   -- deprecated.
                    // }
                    writer.PushSequence();
                    {
                        writer.PushSequence();
                        {
                            writer.PushSequence();
                            {
                                writer.WriteObjectIdentifierForCrypto(PkcsHelpers.GetOidFromHashAlgorithm(hashAlgorithm));
                                writer.PopSequence();
                            }

                            writer.WriteOctetString(macSpan);
                            writer.PopSequence();
                        }

                        writer.WriteOctetString(salt);

                        if (iterationCount > 1)
                        {
                            writer.WriteInteger(iterationCount);
                        }

                        writer.PopSequence();
                    }

                    writer.PopSequence();
                    _sealedData = writer.Encode();
                }
            }
            finally
            {
                CryptographicOperations.ZeroMemory(macSpan);
                CryptographicOperations.ZeroMemory(authSafeSpan);

                if (rentedMac != null)
                {
                    // Already cleared
                    CryptoPool.Return(rentedMac, clearSize: 0);
                }

                if (rentedAuthSafe != null)
                {
                    // Already cleared
                    CryptoPool.Return(rentedAuthSafe, clearSize: 0);
                }
            }
        }
Example #31
0
        private byte[]? InitKey(int mNumCyclesPower, byte[] salt, byte[] pass)
        {
            if (mNumCyclesPower == 0x3F)
            {
                var key = new byte[32];

                int pos;
                for (pos = 0; pos < salt.Length; pos++)
                {
                    key[pos] = salt[pos];
                }

                for (int i = 0; i < pass.Length && pos < 32; i++)
                {
                    key[pos++] = pass[i];
                }

                return(key);
            }
            else
            {
#if NETSTANDARD2_0
                using IncrementalHash sha = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);
                byte[] counter   = new byte[8];
                long   numRounds = 1L << mNumCyclesPower;
                for (long round = 0; round < numRounds; round++)
                {
                    sha.AppendData(salt, 0, salt.Length);
                    sha.AppendData(pass, 0, pass.Length);
                    sha.AppendData(counter, 0, 8);

                    // This mirrors the counter so we don't have to convert long to byte[] each round.
                    // (It also ensures the counter is little endian, which BitConverter does not.)
                    for (int i = 0; i < 8; i++)
                    {
                        if (++counter[i] != 0)
                        {
                            break;
                        }
                    }
                }
                return(sha.GetHashAndReset());
#else
                using var sha = SHA256.Create();
                byte[] counter   = new byte[8];
                long   numRounds = 1L << mNumCyclesPower;
                for (long round = 0; round < numRounds; round++)
                {
                    sha.TransformBlock(salt, 0, salt.Length, null, 0);
                    sha.TransformBlock(pass, 0, pass.Length, null, 0);
                    sha.TransformBlock(counter, 0, 8, null, 0);

                    // This mirrors the counter so we don't have to convert long to byte[] each round.
                    // (It also ensures the counter is little endian, which BitConverter does not.)
                    for (int i = 0; i < 8; i++)
                    {
                        if (++counter[i] != 0)
                        {
                            break;
                        }
                    }
                }

                sha.TransformFinalBlock(counter, 0, 0);
                return(sha.Hash);
#endif
            }
        }