feat: extend certificate pinning to all TLS protocols and add SSH

host-key pinning
This commit is contained in:
2026-06-29 19:23:10 +02:00
parent e7ed3a334e
commit fc65ea8340
19 changed files with 355 additions and 25 deletions
+2 -1
View File
@@ -49,7 +49,8 @@ goget --url <URL> [OPTIONS]
| `--dns-servers` | `<IPs>` | Custom DNS servers, comma-separated (e.g. `1.1.1.1,8.8.8.8`) |
| `--bind-interface` | `<IFACE>` | Bind outgoing connections to a specific network interface (Linux only) |
| `--allow-private` | — | Allow connections to private/internal IPs (disabled by default for SSRF protection) |
| `--pinned-cert` | `<SHA256>` | Certificate pinning — abort if server cert SHA-256 doesn't match |
| `--pinned-cert` | `<SHA256>` | Certificate pinning (TLS protocols: HTTPS, FTPS, Gemini, WebDAVS) — abort if leaf cert SHA-256 doesn't match |
| `--pinned-host-key` | `<FINGERPRINT>` | SSH host-key pinning (SFTP) — accepts `SHA256:<base64>` (`ssh-keygen -lf`) or raw hex SHA-256 |
## HTTP / Network Flags
+12
View File
@@ -78,6 +78,7 @@ Custom FTP implementation supporting active and passive modes.
- **Explicit TLS (FTPS)** — AUTH TLS command on port 21
- **Resume** — REST command for partial transfers
- **Directory listing** — For recursive operations
- **Certificate pinning** — `--pinned-cert` enforces a SHA-256 leaf-cert match on FTPS connections
### Limitations
@@ -95,6 +96,9 @@ Custom FTP implementation supporting active and passive modes.
# Anonymous (default)
--url ftp://anonymous@ftp.example.com/file.zip
# Certificate pinning (FTPS only)
--url ftps://ftp.example.com/file.zip --pinned-cert a1b2c3d4e5f6...
```
## SFTP (`sftp://`)
@@ -108,6 +112,7 @@ SFTP over SSH protocol.
- **Known hosts verification** — Via `~/.ssh/known_hosts`
- **Resume** — Partial transfer support; parallel recursive downloads available via `--recursive-parallel N` with connection pooling
- **`known_hosts` verification** — Reads `~/.ssh/known_hosts`; does not write to it. First-connection accept via `--ssh-insecure`
- **Host-key pinning** — `--pinned-host-key` enforces an exact SSH host-key match (takes precedence over `--ssh-insecure` and `known_hosts`)
### Configuration
@@ -123,6 +128,9 @@ SFTP over SSH protocol.
# With password
--url sftp://user@host:/path/to/file.zip --password "secret"
# Host-key pinning (OpenSSH fingerprint from ssh-keygen -lf)
--url sftp://user@host:/path/to/file.zip --pinned-host-key SHA256:AAAAC3NzaC1lZDI1NTE5AAAAIE...
```
## Local File (`file://`)
@@ -202,6 +210,7 @@ Implements the Gemini protocol (a lightweight alternative to HTTP/HTTPS).
- **Redirect following** — Respects Gemini redirect status codes (3x), up to 10 redirects
- **Error handling** — Input prompts (1x) return an error with the prompt text; temporary (4x) and permanent (5x) failures are handled
- **Text and binary downloads** — 2x success responses stream content directly
- **Certificate pinning** — `--pinned-cert` enforces a SHA-256 leaf-cert match
### Limitations
@@ -217,6 +226,9 @@ goget --url gemini://gemini.example.com/file.zip
# Browse a capsule
goget --url gemini://gemini.example.com/
# Pin the server certificate
goget --url gemini://gemini.example.com/ --pinned-cert a1b2c3d4e5f6...
```
## Protocol Resolution Flow
+19 -2
View File
@@ -12,13 +12,30 @@ goget implements multiple security features to protect both the client and serve
### Certificate Pinning
Pin a specific certificate by its SHA-256 hash:
Pin a specific certificate by its SHA-256 hash. This works across every
TLS-bearing protocol goget supports: HTTPS, FTPS, Gemini, and WebDAVS.
```bash
goget --pinned-cert "a1b2c3d4e5f6..." --url https://example.com
goget --pinned-cert "a1b2c3d4e5f6..." --url ftps://ftp.example.com/file
goget --pinned-cert "a1b2c3d4e5f6..." --url gemini://geminiprotocol.net
goget --pinned-cert "a1b2c3d4e5f6..." --url webdavs://dav.example.com/file
```
If the server certificate's SHA-256 doesn't match, the connection is aborted.
If the leaf certificate's SHA-256 doesn't match, the connection is aborted.
### SSH Host-Key Pinning (SFTP)
Pin the SSH host key for SFTP by its OpenSSH fingerprint (the same value
printed by `ssh-keygen -lf ~/.ssh/known_hosts`). Pinning takes precedence
over `--ssh-insecure` and the `known_hosts` file.
```bash
goget --pinned-host-key "SHA256:AAAAC3NzaC1lZDI1NTE5AAAAIE+HHi0MtRj4VPl8mdP8gniGZDRb0SZTdI2TPxRyCm1H" \
--url sftp://example.com/file
```
The raw lowercase-hex SHA-256 of the key wire format is also accepted.
### Client Certificates (mTLS)