Skip to content

Add TLS Record Layer - #18

Merged
kpodosin merged 1 commit into
mainfrom
kpodosin/addRecordLayer
Sep 21, 2026
Merged

kpodosin merged 1 commit into
mainfrom
kpodosin/addRecordLayer

Conversation

@kpodosin

Copy link
Copy Markdown
Contributor

This PR brings the TLS 1.3 record layer into the package, completing the path from raw network bytes to handshake messages and application data. TLSRecordParser incrementally reassembles records off the wire, TLSCiphertext/TLSInnerPlaintext handle AEAD protection and deprotection, TLSRecordProtector owns key and IV derivation along with per-record nonce construction, and TLSRecordHandler ties it together, driving the client and server handshake state machines, fragmenting outgoing messages across records, and rotating keys as encryption levels advance.
Added SwiftTLSHandshakeAndRecordManager to SwiftTLSProtocol.swift, the public entry point that wraps a record handler and exposes handshake progress, application data, and outgoing bytes to callers. CryptoWrappers.swift provides span-free fallbacks so the layer builds against Crypto releases without the newer span-based APIs. Added tests as well to cover record layer operations.

@kpodosin
kpodosin merged commit ffd3d94 into main Sep 21, 2026
22 checks passed

@FranzBusch FranzBusch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excited to see this addition but I have a few questions regarding the details of it.

}

public mutating func processNetworkData(networkDataIn: RawSpan) throws(SwiftTLSError) {
var buff = ByteBuffer(copying: networkDataIn)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of copying going on the PR. Have we thought about doing as much of the processing without copying?

Comment on lines +119 to +124
var message = [UInt8](unsafeUninitializedCapacity: encryptedRecord.byteCount) { buffer, initializedCount in
encryptedRecord.withUnsafeBytes { encryptedBuffer in
UnsafeMutableRawBufferPointer(buffer).copyMemory(from: encryptedBuffer)
}
initializedCount = encryptedRecord.byteCount
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to do this without unsafe code by using the OutputSpan based APIs instead.

Comment on lines +130 to +136
try message.withUnsafeMutableBytes { (messageBuffer) -> Result<(), CryptoKitMetaError> in
var ciphertextSpan = UnsafeMutableRawBufferPointer(
rebasing: messageBuffer[0..<ciphertextLength]
).mutableBytes
let tagSpan = UnsafeMutableRawBufferPointer(
rebasing: messageBuffer[ciphertextLength..<encryptedRecord.byteCount]
).mutableBytes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not using the extracting APIs on Span here to avoid the proliferation of unsafe code?

Comment on lines +242 to +243
try tagSpan.withUnsafeMutableBytes { tagBuffer throws(CryptoKitMetaError) in
var tagBytes = OutputRawSpan(buffer: tagBuffer, initializedCount: 0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we going from a span to an unsafe buffer to a span again? We should be able to go all the way using just safe Span APIs here unless I am missing something.

@FranzBusch

Copy link
Copy Markdown
Member

Tried to address some of the unsafe code with #19

FranzBusch added a commit to FranzBusch/swift-tls that referenced this pull request Sep 22, 2026
This PR reduces and isolates the unsafe code introduced in apple#18 to a minimum. This helps with ensuring that the TLS record layer implementation is as safe as possible.
@rnro rnro added the 🆕 semver/minor Adds new public API. label Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 semver/minor Adds new public API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants