Skip to content

Conversation

@yigityazicilar
Copy link
Contributor

Motivation:

This change implements support for Oblivious DNS over HTTPS (ODoH) as specified in RFC 9230. ODoH provides privacy-preserving DNS resolution by separating client identity from DNS query content through cryptographic encryption and proxy routing.

Modifications:

  • Extended ObliviousXError with new error cases for ODoH-specific validation failures
  • Added ODoHRoutine.swift with complete RFC 9230 implementation including HPKE-based encryption/decryption, configuration parsing, and message serialization
  • Implemented all ODoH protocol structures (configurations, plaintext messages, encrypted containers)
  • Added tests covering end-to-end ODoH workflow

Result:

After this change, ObliviousX will support the complete ODoH protocol, enabling privacy-preserving DNS operations.

// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import Foundation
Copy link
Contributor

Choose a reason for hiding this comment

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

This import seems unnecessary.

///
/// // 6. Send encrypted response back through proxy to client...
/// ```
public struct ODoH: Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm inclined to say we should move this to a separate target and product. That way for users who aren't doing ODoH, they don't need to pay the code size cost.

public struct Routine {
public private(set) var ct: HPKE.Ciphersuite
public private(set) var pkR: any HPKEDiffieHellmanPublicKey
public private(set) var keyID: Data
Copy link
Contributor

Choose a reason for hiding this comment

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

If the two first variables are going to be public, they need to have better variable names.

///
/// - Parameter version: The version to search for
/// - Returns: The first matching configuration, or `nil` if no configuration with that version exists
public func first(version: UInt16) -> ODoH.Configuration? {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be an Int in public API.

internal func encode() -> Data {
var data = Data()
let contentsData = self.contents.encode()
data.append(bigEndianBytes: self.version) // 2 bytes: version
Copy link
Contributor

Choose a reason for hiding this comment

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

Recommend we do a reserveCapacity on data once we have the length of contentsData.

///
/// - Returns: The encoded configuration contents ready for network transmission
internal func encode() -> Data {
var data = Data()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same note here on reserveCapacity.

///
/// - Returns: The encoded message ready for encryption
internal func encode() -> Data {
var data = Data()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same note here on reserveCapacity.

///
/// - Returns: The encoded message ready for network transmission
public func encode() -> Data {
var data = Data()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same note here about reserveCapacity.

@yigityazicilar
Copy link
Contributor Author

Closing to split up the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants