/// <summary> /// Pads the signature with extra data. /// </summary> /// <param name="signature">The signature.</param> /// <param name="outputStream">The padded signature.</param> /// <param name="extra">The extra data passed by sigData.</param> protected override void PadSignature(byte[] signature, Stream outputStream, object extra) { var padData = (Tuple <long, long, Stream>)extra; var stopLength = padData.Item1; var position = padData.Item2; var input = padData.Item3; var key = GetPrimaryKey() as ISignerKey; outputStream.Write(FormatBytes, 0, FormatBytes.Length); outputStream.Write(key.GetKeyHash(), 0, KeyHashLength); var lengthBytes = Utility.GetBytes((int)(stopLength - position)); outputStream.Write(lengthBytes, 0, lengthBytes.Length); padData.Item3.Seek(position, SeekOrigin.Begin); using (var reader = new NondestructiveBinaryReader(input)) { var adjustedBufferSize = (int)Math.Min(BufferSize, (stopLength - input.Position)); while (reader.Peek() != -1 && input.Position < stopLength) { byte[] buffer = reader.ReadBytes(adjustedBufferSize); outputStream.Write(buffer, 0, buffer.Length); } } outputStream.Write(signature, 0, signature.Length); }
/// <summary> /// Signs the specified data. /// </summary> /// <param name="input">The input.</param> /// <param name="outstream">The outstream.</param> /// <param name="prefixData">The prefix data.</param> /// <param name="postfixData">The postfix data.</param> /// <param name="signatureData">The sig data.</param> /// <param name="inputLength"> Length of the input.</param> protected void Sign(Stream input, Stream outstream, object prefixData, object postfixData, object signatureData, long inputLength) { var stopLength = inputLength < 0 ? long.MaxValue : input.Position + inputLength; if (!(GetPrimaryKey() is ISignerKey key)) { throw MakeInvalidKeySetTypeException(); } using (var reader = new NondestructiveBinaryReader(input)) { using (var signingStream = key.GetSigningStream(this)) { PrefixDataSign(signingStream, prefixData); while (reader.Peek() != -1 && input.Position < stopLength) { var adjustedBufferSize = (int)Math.Min(BufferSize, (stopLength - input.Position)); byte[] buffer = reader.ReadBytes(adjustedBufferSize); signingStream.Write(buffer, 0, buffer.Length); } PostfixDataSign(signingStream, postfixData); signingStream.Finish(); var signature = signingStream.HashValue; PadSignature(signature, outstream, signatureData); } } }
public bool VerifyHidden(Stream input, Stream verifiedMessage, byte[] hidden, long inputLength) { var fullLength = inputLength < 0 ? input.Length : inputLength + input.Position; using (var reader = new NondestructiveBinaryReader(input)) { var header = reader.ReadBytes(KeyczarConst.HeaderLength); var length = Utility.ToInt32(reader.ReadBytes(4)); if (fullLength < input.Position + length) { throw new InvalidCryptoDataException("Data doesn't appear to have signatures attached!"); } using (var sigStream = new MemoryStream()) { using (Utility.ResetStreamWhenFinished(input)) { sigStream.Write(header, 0, header.Length); input.Seek(length, SeekOrigin.Current); while (reader.Peek() != -1 && input.Position < fullLength) { var adjustedBufferSize = (int)Math.Min(BufferSize, (fullLength - input.Position)); var buffer = reader.ReadBytes(adjustedBufferSize); sigStream.Write(buffer, 0, buffer.Length); } sigStream.Flush(); } using (var signedMessageLimtedLength = new NondestructivePositionLengthLimitingStream(input)) { signedMessageLimtedLength.SetLength(length); if (verifiedMessage != null) { using (Utility.ResetStreamWhenFinished(input)) { signedMessageLimtedLength.CopyTo(verifiedMessage); } } var verified = Verify(signedMessageLimtedLength, sigStream.ToArray(), prefixData: null, postfixData: hidden, inputLength: inputLength); input.Seek(fullLength, SeekOrigin.Begin); return(verified); } } } }
/// <summary> /// Verifies the specified data. /// </summary> /// <param name="input">The input.</param> /// <param name="signature">The signature.</param> /// <param name="prefixData">The prefix data.</param> /// <param name="postfixData">The postfix data.</param> /// <param name="inputLength">(optional) Length of the input.</param> /// <returns></returns> protected virtual bool Verify(Stream input, byte[] signature, object prefixData, object postfixData, long inputLength) { var stopLength = inputLength < 0 ? long.MaxValue : input.Position + inputLength; using (var reader = new NondestructiveBinaryReader(input)) { byte[] trimmedSig; var resetData = Utility.ResetStreamWhenFinished(input); foreach (var key in GetKeys(signature, out trimmedSig)) { resetData.Reset(); //in case there aren't any keys that match that hash we are going to fake verify. using (var verifyStream = key.Maybe(m => m.GetVerifyingStream(), () => new DummyStream())) { PrefixDataVerify(verifyStream, prefixData); while (reader.Peek() != -1 && input.Position < stopLength) { var adjustedBufferSize = (int)Math.Min(BufferSize, (stopLength - input.Position)); byte[] buffer = reader.ReadBytes(adjustedBufferSize); verifyStream.Write(buffer, 0, buffer.Length); } PostfixDataVerify(verifyStream, postfixData); try { if (verifyStream.VerifySignature(trimmedSig)) { return(true); } } catch (Exception e) { //We don't want exceptions to keep us from trying different keys System.Diagnostics.Debug.WriteLine(e.Message); System.Diagnostics.Debug.WriteLine(e.StackTrace); } } } return(false); } }
public void Encrypt(Stream input, Stream output, long inputLength = -1) { var stopLength = inputLength < 0 ? long.MaxValue : input.Position + inputLength; var key = GetPrimaryKey(); var header = new byte[HeaderLength]; Array.Copy(FormatBytes, 0, header, 0, FormatBytes.Length); Array.Copy(key.GetKeyHash(), 0, header, FormatBytes.Length, KeyHashLength); var cryptKey = key as IEncrypterKey; var resetStream = Utility.ResetStreamWhenFinished(output); using (var reader = new NondestructiveBinaryReader(input)) { FinishingStream encryptingStream; output.Write(header, 0, header.Length); encryptingStream = cryptKey.GetEncryptingStream(output); Stream wrapper = encryptingStream; if (Compression == CompressionType.Gzip) { wrapper = new GZipStream(encryptingStream, CompressionMode.Compress, true); } else if (Compression == CompressionType.Zlib) { wrapper = new ZlibStream(encryptingStream, CompressionMode.Compress, true); } using (encryptingStream) { encryptingStream.GetTagLength(header); using (Compression == CompressionType.None ? null : wrapper){ while (reader.Peek() != -1 && input.Position < stopLength) { var adjustedBufferSize = (int)Math.Min(BufferSize, (stopLength - input.Position)); byte[] buffer = reader.ReadBytes(adjustedBufferSize); wrapper.Write(buffer, 0, buffer.Length); } } encryptingStream.Finish(); } } byte[] hash; using (var outputReader = new NondestructiveBinaryReader(output)) using (var signingStream = cryptKey.GetAuthSigningStream()) { if (signingStream == null || signingStream.GetTagLength(header) == 0) { return; } resetStream.Reset(); while (outputReader.Peek() != -1) { byte[] buffer = outputReader.ReadBytes(BufferSize); signingStream.Write(buffer, 0, buffer.Length); } signingStream.Finish(); hash = signingStream.HashValue; } output.Write(hash, 0, hash.Length); }