Skip to content

SessionKey handshake for V1-initial S7-1200 PLCs#761

Closed
gijzelaerr wants to merge 7 commits into
masterfrom
fix-tls-layering
Closed

SessionKey handshake for V1-initial S7-1200 PLCs#761
gijzelaerr wants to merge 7 commits into
masterfrom
fix-tls-layering

Conversation

@gijzelaerr

Copy link
Copy Markdown
Owner

Replaces #724 (GitHub's PR ref got stuck after force-push conflict resolution).

Summary

Adds the full session_auth package for V1-initial S7-1200 PLCs that require a SessionKey handshake before data operations:

  • s7/session_auth/: Public-key-based session authentication (Family 0 key derivation, fingerprint matching, SecurityKeyEncryptedKey blob generation, legitimation challenge solver, HMAC key derivation)
  • V3 HMAC framing for post-auth data operations
  • TIA-style CreateObject attributes (required by V1-initial firmware)
  • PAOM string stripping in ServerSessionVersion echo
  • Post-auth legitimation flow (challenge read + solved blob write)
  • Connection.connect(password=) parameter for auth flow

Test plan

Known limitations

Adds the full session_auth package (HarpoS7 port) for V1-initial S7-1200
PLCs that require a SessionKey handshake before data operations:

- s7/session_auth/: Public-key-based session authentication (Family 0
  key derivation, fingerprint matching, SecurityKeyEncryptedKey blob
  generation, legitimation challenge solver, HMAC key derivation)
- V3 HMAC framing for post-auth data operations
- TIA-style CreateObject attributes (required by V1-initial firmware)
- PAOM string stripping in ServerSessionVersion echo
- Post-auth legitimation flow (challenge read + solved blob write)
- Connection.connect(password=) parameter for auth flow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread s7/session_auth/legitimate.py Dismissed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread s7/session_auth/harpo_aes.py Dismissed
gijzelaerr and others added 4 commits July 11, 2026 14:00
Three places checked `self._server_session_version` against itself
(same variable on both sides of `or`/`and`). Simplify to single
checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
S7CommPlus responses use a 10-byte header (no SessionId field), not 14.
The 14-byte header is only for requests. This fix corrects the
CreateObject response parsing that crashed with "Unexpected end of VLQ
data" on V1 PLCs (e.g. S7-1200 FW v4.2) because the 4-byte offset
error caused the VLQ decoder to misparse object ID count as 161.

Also fixes the test server to match real PLC behavior (10-byte response
header with session ID in the body as ObjectIds[0], not in the header).

Fixes #710 (comment by xBiggs on d5e8aaf).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sionKey PLCs

V1-initial S7-1200 PLCs with SessionKey auth reject GET_MULTI_VARIABLES
(0x054C) with a TCP RST. They require GET_VAR_SUBSTREAMED (0x0586) and
SET_VAR_SUBSTREAMED (0x057C) for all data operations — the same function
codes that the legitimation handshake already uses successfully.

When connection.requires_substreamed is True (session_key is set),
db_read, db_write, db_read_multi, read_area, and write_area now route
through substreamed function codes with ItemAddress fields encoded in
the substreamed payload format.

Addresses #710 (xBiggs: db_read RST after successful SessionKey auth).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts:
#	s7/_s7commplus_server.py
#	s7/connection.py
#	s7/protocol.py
@gijzelaerr

Copy link
Copy Markdown
Owner Author

Superseded by a new PR rebased onto the s7commplus/ package split (#774). Same content, new branch (fix-tls-layering-v2).

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