<!-- task=tls_support plan=0 tag=TLS -->

# Code Review Reference - TLS

## 개요

date=2026-04-25
task=tls_support, plan=0, tag=TLS

## 이 파일을 읽는 리뷰 에이전트에게

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.

1. `CODE_REVIEW.md` → `code_review_0.log` (기존 code_review_*.log 수 = 0)
2. `PLAN.md` → `plan_0.log` (기존 plan_*.log 수 = 0)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [TLS-1] Python TLS TCP (`connect_tcp_tls` + `TcpServer` ssl_context) | [x] |
| [TLS-2] Python WSS (`connect_wss` + `WsServer` ssl_context) | [x] |
| [TLS-3] TypeScript TLS TCP (`connectTcpTls` + `TcpServer` tlsOptions) | [x] |
| [TLS-4] TypeScript WSS (`connectWss` + `WsServer` tlsOptions) | [x] |
| [TLS-5] Kotlin TLS TCP (`dialTcpTls` + `TcpServer` sslContext) | [x] |

## 계획 대비 변경 사항

- Python은 `toki_socket.__init__`에도 `connect_tcp_tls`, `connect_wss`를 export했다. 기존 `connect_tcp`, `connect_ws` 공개 방식과 맞추기 위함이다.
- TypeScript WSS 테스트의 클라이언트 옵션은 `{ ca: cert }`만 사용했다. `ws`의 `ClientOptions` 타입에 `servername`이 없고, 테스트 인증서에 `IP:127.0.0.1`, `DNS:localhost` SAN이 있어 검증에 충분하다.
- Kotlin `TcpServer`는 기존 `TcpServer(host, port) { ... }` trailing lambda 호출 호환성을 지키기 위해 `sslContext`를 `newClient` 람다 앞에 둔다. TLS 서버 생성은 `TcpServer(host, port, sslContext) { ... }` 형태로 사용한다.
- Kotlin은 기존 `DialTcp` 패턴에 맞춰 `DialTcpTls` wrapper도 함께 추가했다.

## 주요 설계 결정

- 테스트 인증서는 계획대로 `dart/test/certs/server.crt`, `server.key`를 각 언어 테스트 리소스 위치에 복사했다.
- Python/TypeScript 서버 TLS 설정은 선택 인자로 추가해 기존 non-TLS 호출 경로를 유지했다.
- TypeScript WSS 서버는 TLS 모드에서 `https.Server`를 보관하고 `stop()`에서 `WebSocketServer`와 함께 닫는다.
- Kotlin TLS 테스트는 `PKCS#8` PEM key와 X.509 cert로 테스트용 server/client `SSLContext`를 생성한다.

## 리뷰어를 위한 체크포인트

- `python/toki_socket/tcp_client.py` — `connect_tcp_tls()` 함수 존재, `asyncio.open_connection(ssl=...)` 사용 여부
- `python/toki_socket/tcp_server.py` — `__init__` `ssl_context` 파라미터 및 `start()`에서 전달 여부
- `python/toki_socket/ws_client.py` — `connect_wss()` 함수 존재, `ws_connect(uri, ssl=...)` 사용 여부
- `python/toki_socket/ws_server.py` — `__init__` `ssl_context` 파라미터 및 `ws_serve()` 두 경로에 전달 여부
- `python/test/certs/` — cert 파일 존재 여부
- `typescript/src/tcp_client.ts` — `connectTcpTls()` 함수 존재, `tls.connect()` + `secureConnect` 이벤트 사용 여부
- `typescript/src/tcp_server.ts` — `tlsOptions` 파라미터, `tls.createServer()` 분기 여부
- `typescript/src/ws_client.ts` — `connectWss()` 함수 존재 여부
- `typescript/src/ws_server.ts` — `tlsOptions` 파라미터, `https.createServer()` + `httpsServer.close()` 포함 여부
- `typescript/test/certs/` — cert 파일 존재 여부
- `kotlin/src/main/kotlin/.../TcpClient.kt` — `dialTcpTls()` 함수 존재 여부
- `kotlin/src/main/kotlin/.../TcpServer.kt` — `sslContext` 파라미터, TLS 분기, `port()` getter 여부
- `kotlin/src/test/resources/` — cert 파일 존재 여부
- 기존 테스트 회귀 없음 (Python 19개, TypeScript 27개, Kotlin 전체 PASS)

## 검증 결과

_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._

### TLS-1 중간 검증
```
$ cd python && python3 -m py_compile toki_socket/tcp_client.py toki_socket/tcp_server.py
(no output, exit 0)

$ cd python && python3 -m pytest test/test_tcp.py -q
......                                                                   [100%]
6 passed in 0.37s
```

### TLS-2 중간 검증
```
$ cd python && python3 -m py_compile toki_socket/ws_client.py toki_socket/ws_server.py
(no output, exit 0)

$ cd python && python3 -m pytest test/test_ws.py -q
......                                                                   [100%]
6 passed in 0.36s
```

### TLS-3 중간 검증
```
$ cd typescript && npx tsc --noEmit
(no output, exit 0)

$ cd typescript && npx vitest run test/tcp.test.ts
 RUN  v3.2.4 /config/workspace/toki_socket/typescript

 ✓ test/tcp.test.ts (5 tests) 85ms

 Test Files  1 passed (1)
      Tests  5 passed (5)
   Start at  05:18:33
   Duration  1.93s (transform 416ms, setup 0ms, collect 598ms, tests 85ms, environment 0ms, prepare 331ms)
```

### TLS-4 중간 검증
```
$ cd typescript && npx tsc --noEmit
(no output, exit 0)

$ cd typescript && npx vitest run test/ws.test.ts
 RUN  v3.2.4 /config/workspace/toki_socket/typescript

 ✓ test/ws.test.ts (5 tests) 85ms

 Test Files  1 passed (1)
      Tests  5 passed (5)
   Start at  05:18:54
   Duration  1.45s (transform 246ms, setup 0ms, collect 524ms, tests 85ms, environment 0ms, prepare 381ms)
```

### TLS-5 중간 검증
```
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew test --tests "*.TlsTcpTest"
> Task :test

BUILD SUCCESSFUL in 10s
11 actionable tasks: 3 executed, 8 up-to-date
```

### 최종 검증
```
$ cd python && python3 -m py_compile toki_socket/tcp_client.py toki_socket/tcp_server.py toki_socket/ws_client.py toki_socket/ws_server.py
(no output, exit 0)

$ cd python && python3 -m pytest test/ -q
...................                                                      [100%]
19 passed in 0.39s

$ cd typescript && npx tsc --noEmit && npx vitest run
 RUN  v3.2.4 /config/workspace/toki_socket/typescript

 ✓ test/communicator.test.ts (10 tests) 30ms
 ✓ test/base_client.test.ts (7 tests) 65ms
 ✓ test/tcp.test.ts (5 tests) 72ms
 ✓ test/ws.test.ts (5 tests) 68ms

 Test Files  4 passed (4)
      Tests  27 passed (27)
   Start at  05:22:53
   Duration  1.37s (transform 772ms, setup 0ms, collect 1.77s, tests 235ms, environment 1ms, prepare 1.31s)

$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew test
> Task :test

BUILD SUCCESSFUL in 14s
11 actionable tasks: 1 executed, 10 up-to-date
```
