bool DecryptRecordFragment(ContentType contentType, ref TlsBuffer buffer) { var read = Session.Read; if (read == null || read.Cipher == null) { return(false); } var output = read.Decrypt(contentType, buffer.GetRemaining()); buffer = new TlsBuffer(output); return(true); }
SecurityStatus _DecryptMessage(ref TlsBuffer incoming) { // Try to read the Record Content Type var contentType = (ContentType)incoming.ReadByte(); #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteLine("DecryptMessage({0}): {1}", IsServer ? "server" : "client", contentType); } #endif if (contentType == ContentType.Handshake) { #if INSTRUMENTATION if (HasInstrumentationEventSink) { InstrumentationEventSink.StartRenegotiation(this); } #endif incoming.Position--; return(SecurityStatus.Renegotiate); } ReadStandardBuffer(contentType, ref incoming); if (contentType == ContentType.Alert) { var level = (AlertLevel)incoming.ReadByte(); var description = (AlertDescription)incoming.ReadByte(); if (level == AlertLevel.Warning && description == AlertDescription.CloseNotify) { ReceivedCloseNotify = true; if (eventSink != null) { eventSink.ReceivedCloseNotify(); } return(SecurityStatus.ContextExpired); } DebugHelper.WriteLine("ALERT: {0} {1}", level, description); throw new TlsException(level, description); } else if (contentType == ContentType.ApplicationData) { return(SecurityStatus.OK); } throw new TlsException(AlertDescription.UnexpectedMessage, "Unknown content type {0}", contentType); }
public SecurityStatus GenerateNextToken(TlsBuffer incoming, TlsMultiBuffer outgoing) { try { CheckValid(); return(_GenerateNextToken(incoming, outgoing)); } catch (TlsException ex) { LastError = ex; var alert = CreateAlert(ex.Alert); outgoing.Add(alert); Clear(); return(SecurityStatus.ContextExpired); } catch { Clear(); throw; } }
public SecurityStatus EncryptMessage(ref TlsBuffer incoming) { try { CheckValid(); return(_EncryptMessage(ref incoming)); } catch (TlsException ex) { LastError = ex; var alert = CreateAlert(ex.Alert); incoming = new TlsBuffer(alert); Clear(); return(SecurityStatus.ContextExpired); } catch { Clear(); throw; } }
SecurityStatus _DecryptMessage(ref TlsBuffer incoming) { // Try to read the Record Content Type var contentType = (ContentType)incoming.ReadByte(); #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteLine("DecryptMessage: {0}", contentType); } #endif ReadStandardBuffer(contentType, ref incoming); if (contentType == ContentType.Alert) { var level = (AlertLevel)incoming.ReadByte(); var description = (AlertDescription)incoming.ReadByte(); if (level == AlertLevel.Warning && description == AlertDescription.CloseNotify) { ReceivedCloseNotify = true; return(SecurityStatus.ContextExpired); } DebugHelper.WriteLine("ALERT: {0} {1}", level, description); throw new TlsException(level, description); } else if (contentType == ContentType.ApplicationData) { return(SecurityStatus.OK); } else if (contentType != ContentType.Handshake) { throw new TlsException(AlertDescription.UnexpectedMessage, "Unknown content type {0}", contentType); } try { SecurityStatus status; var finished = ProcessHandshakeMessage(incoming, out status); DebugHelper.WriteLine("RENEGOTIATION REQUEST: {0} {1}", finished, status); return(status); } finally { incoming.Dispose(); incoming = null; } }
public SecurityStatus GenerateNextToken(TlsBuffer incoming, TlsMultiBuffer outgoing) { try { CheckValid(); return(_GenerateNextToken(incoming, outgoing)); } catch (TlsException ex) { var alert = OnError(ex); if (alert != null) { outgoing.Add(alert); } Clear(); return(SecurityStatus.ContextExpired); } catch { Clear(); throw; } }
bool ReadStandardBuffer(ContentType contentType, ref TlsBuffer buffer) { if (buffer.Remaining < 4) { throw new TlsException( AlertDescription.DecodeError, "buffer underrun"); } short protocolCode = buffer.ReadInt16(); short length = buffer.ReadInt16(); #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteLine("ReadStandardBuffer: {0:x} {1:x}", protocolCode, length); DebugHelper.WriteRemaining(" Buffer", buffer); } #endif if (HasNegotiatedProtocol) { var protocol = (TlsProtocolCode)protocolCode; if (protocol != NegotiatedProtocol) { throw new TlsException(AlertDescription.ProtocolVersion); } } else { if ((protocolCode >> 8 != 3) || ((protocolCode & 0x00ff) < 1)) { throw new TlsException(AlertDescription.ProtocolVersion); } } if (length != buffer.Remaining) { throw new TlsException( AlertDescription.DecodeError, "Invalid buffer size"); } return(DecryptRecordFragment(contentType, ref buffer)); }
SecurityStatus ProcessAlert(TlsBuffer buffer) { bool decrypted = false; if ((session.Read != null && session.Read.Cipher != null) || (buffer.Remaining != 2)) { decrypted = ReadStandardBuffer(ContentType.Alert, ref buffer); } if (buffer.Remaining != 2) { throw new TlsException(AlertDescription.IlegalParameter, "Invalid Alert message size"); } var level = (AlertLevel)buffer.ReadByte(); var description = (AlertDescription)buffer.ReadByte(); if (decrypted) { buffer.Dispose(); } if (level == AlertLevel.Warning) { if (description == AlertDescription.CloseNotify) { ReceivedCloseNotify = true; if (eventSink != null) { eventSink.ReceivedCloseNotify(); } return(SecurityStatus.ContextExpired); } DebugHelper.WriteLine("Received alert: {0}", description); return(SecurityStatus.ContinueNeeded); } else { throw new TlsException(description); } }
SecurityStatus _EncryptMessage(ref TlsBuffer incoming) { #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteRemaining("EncryptMessage", incoming); } #endif var buffer = EncodeRecord(ContentType.ApplicationData, incoming.GetRemaining()); #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteBuffer("EncryptMessage done", buffer); } #endif incoming = new TlsBuffer(buffer); return(SecurityStatus.OK); }
public SecurityStatus EncryptMessage(ref TlsBuffer incoming) { try { CheckValid(); return(_EncryptMessage(ref incoming)); } catch (TlsException ex) { var alert = OnError(ex); if (alert != null) { incoming = new TlsBuffer(alert); } else { incoming = null; } Clear(); return(SecurityStatus.ContextExpired); } catch { Clear(); throw; } }
public static void WriteFull (string message, TlsBuffer buffer) { WriteBuffer (message, true, buffer); }
public static void WriteBuffer (string message, bool full, TlsBuffer buffer) { var offset = full ? buffer.Offset : buffer.Position; var size = full ? buffer.Size : buffer.Remaining; DebugHelper.WriteBuffer (message, buffer.Buffer, offset, size); }
public void TestOutputOffset (TestContext ctx, [TestHost] IEncryptionTestHost host) { var input = GetBuffer (HelloWorldName); var output = new TlsBuffer (input.Size + host.MaxExtraEncryptedBytes + MagicDataSize); output.Write (GetBuffer (MagicDataName)); var startOffset = output.Offset; var startPos = output.Position; var startSize = output.Size; var length = host.Encrypt (input, output.GetRemaining ()); ctx.Assert (length, Is.GreaterThanOrEqualTo (0), "#1"); ctx.Assert (length, Is.GreaterThanOrEqualTo (input.Size + host.MinExtraEncryptedBytes), "#2a"); ctx.Assert (length, Is.LessThanOrEqualTo (input.Size + host.MaxExtraEncryptedBytes), "#2a"); ctx.Assert (output.Offset, Is.EqualTo (startOffset), "#2b"); ctx.Assert (output.Size, Is.EqualTo (startSize), "#2c"); output.Position = 0; var magic = output.ReadBytes (MagicDataSize); ctx.Assert (magic, Is.EqualTo (GetField (MagicDataName)), "#3"); var encrypted = output.ReadBytes (length); CheckOutput (ctx, HelloWorldResult, new BufferOffsetSize (encrypted)); }
public void Add(TlsBuffer buffer) { Add(buffer.Buffer, buffer.Offset, buffer.Size); }
public void TestDecryptWithInvalidPadding (TestContext ctx, [TestHost] IEncryptionTestHost host) { var input = GetBuffer (ExtraPaddingResult); var modified = new TlsBuffer (input.Size); modified.Write (input.Buffer); var theOffset = modified.Size - (2 * host.BlockSize) - 5; modified.Buffer [theOffset] ^= 0x01; input = new BufferOffsetSize (modified.Buffer, 0, modified.Size); try { host.Decrypt (input); ctx.AssertFail ("#1"); } catch (Exception ex) { ctx.Assert (ex, Is.InstanceOf<TlsException> (), "#2"); var tlsEx = (TlsException)ex; ctx.Assert (tlsEx.Alert.Level, Is.EqualTo (AlertLevel.Fatal), "#3"); ctx.Assert (tlsEx.Alert.Description, Is.EqualTo (AlertDescription.BadRecordMAC), "#4"); } }
public void TestDecrypt (TestContext ctx, [TestHost] IEncryptionTestHost host) { var input = GetBuffer (HelloWorldResult); var output = new TlsBuffer (input.Size); var hello = GetField (HelloWorldName); var length = host.Decrypt (input, output.GetRemaining ()); ctx.Assert (length, Is.EqualTo (hello.Length), "#1"); output.Position = 0; var decrypted = output.ReadBytes (length); ctx.Assert (decrypted, Is.EqualTo (hello), "#4"); }
SecurityStatus _GenerateNextToken(TlsBuffer incoming, TlsMultiBuffer outgoing) { #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteLine("GenerateNextToken: {0}", negotiationHandler); if (incoming != null) { DebugHelper.WriteRemaining(" incoming", incoming); } } #endif if (incoming == null) { negotiationHandler = negotiationHandler.GenerateReply(outgoing); return(SecurityStatus.ContinueNeeded); } var contentType = (ContentType)incoming.ReadByte(); #if DEBUG_FULL if (EnableDebugging) { DebugHelper.WriteLine(" received message type {0}", contentType); } #endif if (skipToOffset >= 0 && contentType != ContentType.Handshake) { throw new TlsException(AlertDescription.InternalError); } if (contentType == ContentType.Alert) { return(ProcessAlert(incoming)); } bool decrypted = false; if (cachedFragment != null) { if (contentType != ContentType.Handshake) { throw new TlsException(AlertDescription.DecodeError); } decrypted = ReadStandardBuffer(ContentType.Handshake, ref incoming); cachedFragment.Write(incoming.Buffer, incoming.Position, incoming.Position + incoming.Remaining); if (cachedFragment.Remaining > 0) { return(SecurityStatus.ContinueNeeded); } incoming.Dispose(); incoming = cachedFragment; cachedFragment = null; incoming.Position = 0; } else { decrypted = ReadStandardBuffer(contentType, ref incoming); } if (Session.Read != null && Session.Read.Cipher != null && !decrypted) { throw new TlsException(AlertDescription.DecryptError, "Expected encrypted message."); } try { if (contentType == ContentType.ChangeCipherSpec) { return(negotiationHandler.ProcessMessage(new TlsChangeCipherSpec())); } else if (contentType == ContentType.ApplicationData) { if (session.Read == null || session.Read.Cipher == null || !session.SecureRenegotiation) { throw new TlsException(AlertDescription.DecodeError); } // FIXME throw new NotImplementedException(); } else if (contentType != ContentType.Handshake) { throw new TlsException(AlertDescription.UnexpectedMessage); } if (skipToOffset >= 0) { incoming.Position = skipToOffset; skipToOffset = -1; } SecurityStatus result; bool finished; while (true) { var startOffset = incoming.Position; finished = ProcessHandshakeMessage(incoming, out result); if (result == SecurityStatus.CredentialsNeeded) { // Caller will call us again with the same input. skipToOffset = startOffset; if (decrypted) { Session.Read.ReadSequenceNumber--; } return(result); } if (incoming.Remaining == 0) { break; } if (finished || result != SecurityStatus.ContinueNeeded) { throw new TlsException(AlertDescription.UnexpectedMessage); } } if (finished) { negotiationHandler = negotiationHandler.GenerateReply(outgoing); } return(result); } finally { if (decrypted) { incoming.Dispose(); } } }
public void TestDecryptWithInvalidPadding2 (TestContext ctx, [TestHost] IEncryptionTestHost host) { var input = GetBuffer (Data11Result); var modified = new TlsBuffer (input.Size); modified.Write (input.Buffer); // Flip a bit in the last byte, this will affect the padding size. modified.Buffer [modified.Size - 1] ^= 0x01; input = new BufferOffsetSize (modified.Buffer, 0, modified.Size); try { host.Decrypt (input); ctx.AssertFail ("#1"); } catch (Exception ex) { ctx.Assert (ex, Is.InstanceOf<TlsException> (), "#2"); var tlsEx = (TlsException)ex; ctx.Assert (tlsEx.Alert.Level, Is.EqualTo (AlertLevel.Fatal), "#3"); ctx.Assert (tlsEx.Alert.Description, Is.EqualTo (AlertDescription.BadRecordMAC), "#4"); } }
public static void WriteLine(string message, TlsBuffer buffer) { Initialize(); DebugHelper.WriteLine(String.Format("{0} ({1} bytes)", message, buffer.Remaining)); DebugHelper.WriteBuffer(buffer); }
public TlsBuffer ReadBuffer (int length) { if (Position + length > EndOffset) throw new TlsException (AlertDescription.DecodeError, "Buffer overflow"); var retval = new TlsBuffer (Buffer, Position, length); Position += length; return retval; }
public void TestInputOffset (TestContext ctx, [TestHost] IEncryptionTestHost host) { var hello = GetBuffer (HelloWorldName); var input = new TlsBuffer (hello.Size + MagicDataSize + MagicData2Size); input.Write (GetField (MagicDataName)); var startPos = input.Position; input.Write (hello); input.Write (GetBuffer (MagicData2Name)); var output = host.Encrypt (new BufferOffsetSize (input.Buffer, startPos, hello.Size)); ctx.Assert (output, Is.Not.Null, "#1"); ctx.Assert (output.Size, Is.GreaterThanOrEqualTo (hello.Size + host.MinExtraEncryptedBytes), "#2"); ctx.Assert (output.Size, Is.LessThanOrEqualTo (hello.Size + host.MaxExtraEncryptedBytes), "#2"); CheckOutput (ctx, HelloWorldResult, output); }
public static void WriteFull(string message, TlsBuffer buffer) { WriteBuffer(message, true, buffer); }
public static void WriteRemaining (string message, TlsBuffer buffer) { WriteBuffer (message, false, buffer); }
int XITlsContext.EncryptMessage(ref TlsBuffer incoming) { return((int)EncryptMessage(ref incoming)); }
int XITlsContext.GenerateNextToken(TlsBuffer incoming, TlsMultiBuffer outgoing) { return((int)GenerateNextToken(incoming, outgoing)); }
public static void WriteRemaining(string message, TlsBuffer buffer) { WriteBuffer(message, false, buffer); }
public static void WriteBuffer(TlsBuffer buffer) { WriteBuffer(buffer.Buffer, buffer.Position, buffer.Remaining); }
public void SetCipherList (ICollection<CipherSuiteCode> ciphers) { var codes = new TlsBuffer (ciphers.Count * 2); foreach (var cipher in ciphers) codes.Write ((short)cipher); var ret = native_openssl_set_cipher_list (handle, codes.Buffer, ciphers.Count); CheckError (ret); }
public void Add (TlsBuffer buffer) { Add (buffer.Buffer, buffer.Offset, buffer.Size); }