-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infrastructure for Tls #52
Conversation
|
||
namespace Bedrock.Framework.Experimental.Infrastructure | ||
{ | ||
public static class Endianness |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internal. Do you need this though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I don't have this I end up with a lot of (SomeEnum) BinaryPrimatives.Reverse((ushort) someEnum);
Etc it's really ugly and this using generics goes down all the way to basically the bswap in all cases. Also in later code for Tls there are other structs (including int24) that are just unsupported otherwise
src/Bedrock.Framework.Experimental/Protocols/Tls/ApplicationLayerProtocolType.cs
Show resolved
Hide resolved
namespace Bedrock.Framework.Experimental.Protocols.Tls.BulkCiphers | ||
{ | ||
[StructLayout(LayoutKind.Sequential, Pack = 1)] | ||
internal struct AdditionalInfo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mutable struct? Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a sequence number on this we increased for each message sent. We then feed this into BulkCipher as additional information used during the encryption for AES etc. Also by making the methods convert to the correct bitness in the set it means we can directly blit the struct (by using a pointer)
src/Bedrock.Framework.Experimental/Protocols/Tls/BulkCiphers/BulkCipher.cs
Outdated
Show resolved
Hide resolved
|
||
namespace Bedrock.Framework.Experimental.Protocols.Tls.BulkCiphers | ||
{ | ||
internal abstract class BulkCipher : IDisposable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this type for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a difference in how TLS 1.2 and TLS 1.3 for instance encrypt each record (different additional info, different IV calculations for each, different headers and footers for the encryption frame) so this way the up level protocol handlers can abstract that detail and not care. They just have a Decrypt/Encrypt. I will upload the TLS 1.2 and TLS 1.3 implementation of each of these next.
{ | ||
internal abstract class BulkCipherKey : IDisposable | ||
{ | ||
public abstract Memory<byte> IV { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to exist and why isn't it read only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IV is the initialisation vector that is used by the various symmetrical encryption algos. The spec defines how these are set so the "BulkCipher" will set them before every record that is encrypted (They contain a mixture of random/info from the handshake and counters). They are calculated differently for TLS 1.2 /1.3 etc and therefore cannot be controlled by the key implementation. They are mutated every record so they need to be editable.
{ | ||
internal abstract class BulkCipherProvider | ||
{ | ||
public abstract BulkCipher GetCipher<T>(BulkCipherType cipherType, Memory<byte> keyStorage) where T : BulkCipher, new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this memory writable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally this was "OwnedMemory" because it came from a pool, however the BulkCipher needed to hold it for it's lifetime and then say when it was done. Is there still a concept of this now?
src/Bedrock.Framework.Experimental/Protocols/Tls/Certificates/Certificate.cs
Outdated
Show resolved
Hide resolved
|
||
namespace Bedrock.Framework.Experimental.Protocols.Tls.Hashs | ||
{ | ||
internal abstract class Hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the same as below the provider below will provide an instance of this (from say OpenSsl or BCrypt)
|
||
namespace Bedrock.Framework.Experimental.Protocols.Tls.Hashs | ||
{ | ||
internal abstract class HashProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use any of the BCL types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So Tls during the handshake requires you to keep a running hash of the messages sent/received during the exchange. There is a BCL incremental hash function which is great but....
TLS requires you to grab the hash up until now at various points. This poses a problem as there is only a "gethashandreset" method where as I want to get the hash up to now and continue. Both BCrypt and OpenSsl support that scenario but the BCL does not.
Without this you would have to buffer the messages during the handshake which is significantly worse and the interop for hash isn't a big deal.
src/Bedrock.Framework.Experimental/Protocols/Tls/TlsFrameType.cs
Outdated
Show resolved
Hide resolved
All changed or answered, read for comment |
src/Bedrock.Framework.Experimental/Protocols/Tls/Certificates/CertificateType.cs
Outdated
Show resolved
Hide resolved
src/Bedrock.Framework.Experimental/Protocols/Tls/BulkCiphers/BulkCipher.cs
Outdated
Show resolved
Hide resolved
public abstract int Finish(Span<byte> output); | ||
public abstract HashType HashType { get; } | ||
|
||
public void HashData(SequenceReader<byte> reader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be ref?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are a few outstanding comments, but I don't see any reason to block this.
@Drawaes Can you rebase? |
Includes
I have not included any implementations yet and made all internal for now, this can be reviewed at a later date but none should be used externally for now (except TlsProtocolVersion).
Next there are a few steps
I will probably work on 1 first so that there is something to actually use in 2 when we come to it (and my Tls 1.3 is a little rusty so I need to review so I will work on 1.2 first for part 2).
Cheers
Tim