forked from claw/flaskpaste
add /register endpoint for public certificate registration
Public endpoint allows anyone to obtain a client certificate for authentication. Features: - Higher PoW difficulty than paste creation (24 vs 20 bits) - Auto-generates CA on first registration if not present - Returns PKCS#12 bundle with cert, key, and CA - Configurable via FLASKPASTE_REGISTER_POW Endpoints: - GET /register/challenge - Get registration PoW challenge - POST /register - Register and receive PKCS#12 bundle
This commit is contained in:
@@ -1049,3 +1049,124 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
||||
|
||||
**Request:**
|
||||
```http
|
||||
GET /register/challenge HTTP/1.1
|
||||
Host: localhost:5000
|
||||
```
|
||||
|
||||
**Response (PoW disabled):**
|
||||
```json
|
||||
{
|
||||
"enabled": false,
|
||||
"difficulty": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Response (PoW enabled):**
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"nonce": "a1b2c3d4e5f6a7b8a1b2c3d4e5f6a7b8",
|
||||
"difficulty": 24,
|
||||
"expires": 1700000300,
|
||||
"token": "a1b2c3d4...:1700000300:24:signature"
|
||||
}
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- Registration difficulty defaults to 24 bits (vs 20 for paste creation)
|
||||
- Higher difficulty protects against automated certificate harvesting
|
||||
- Configurable via `FLASKPASTE_REGISTER_POW` environment variable
|
||||
|
||||
---
|
||||
|
||||
### POST /register
|
||||
|
||||
Register for a client certificate (public endpoint with PoW protection).
|
||||
|
||||
This endpoint allows anyone to obtain a client certificate for authentication. The CA is auto-generated on first registration if it doesn't exist.
|
||||
|
||||
**Request (with PoW):**
|
||||
```http
|
||||
POST /register HTTP/1.1
|
||||
Host: localhost:5000
|
||||
Content-Type: application/json
|
||||
X-PoW-Token: a1b2c3d4...:1700000300:24:signature
|
||||
X-PoW-Solution: 12345678
|
||||
|
||||
```
|
||||
|
||||
**Request (PoW disabled):**
|
||||
```http
|
||||
POST /register HTTP/1.1
|
||||
Host: localhost:5000
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/x-pkcs12
|
||||
Content-Disposition: attachment; filename="client.p12"
|
||||
X-Certificate-Fingerprint: b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3
|
||||
|
||||
<binary PKCS#12 data>
|
||||
```
|
||||
|
||||
**Response Headers:**
|
||||
| Header | Description |
|
||||
|--------|-------------|
|
||||
| `X-Certificate-Fingerprint` | SHA1 fingerprint for `X-SSL-Client-SHA1` header |
|
||||
|
||||
**PKCS#12 Bundle Contents:**
|
||||
- Client certificate (signed by CA)
|
||||
- Client private key (EC secp384r1)
|
||||
- CA certificate (for trust chain)
|
||||
|
||||
**Errors:**
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 400 | Proof-of-work required (when enabled) |
|
||||
| 400 | Proof-of-work failed (invalid/expired challenge) |
|
||||
| 500 | PKI_CA_PASSWORD not configured |
|
||||
| 500 | Certificate generation failed |
|
||||
|
||||
**Configuration:**
|
||||
```bash
|
||||
export FLASKPASTE_REGISTER_POW=24 # Registration PoW difficulty (0=disabled)
|
||||
export FLASKPASTE_PKI_CA_PASSWORD="..." # Required for certificate signing
|
||||
export FLASKPASTE_PKI_CERT_DAYS=365 # Client certificate validity
|
||||
export FLASKPASTE_PKI_CA_DAYS=3650 # CA certificate validity (auto-generated)
|
||||
```
|
||||
|
||||
**Using the Certificate:**
|
||||
|
||||
```bash
|
||||
# Extract certificate and key from PKCS#12
|
||||
openssl pkcs12 -in client.p12 -clcerts -nokeys -out client.crt
|
||||
openssl pkcs12 -in client.p12 -nocerts -nodes -out client.key
|
||||
|
||||
# Use with curl
|
||||
curl --cert client.crt --key client.key https://paste.example.com/
|
||||
|
||||
# Use fingerprint for header-based auth (behind reverse proxy)
|
||||
curl -H "X-SSL-Client-SHA1: $(openssl x509 -in client.crt -fingerprint -sha1 -noout | cut -d= -f2 | tr -d :)" \
|
||||
https://paste.example.com/pastes
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- `common_name` is optional; a random UUID is generated if omitted
|
||||
- The PKCS#12 bundle has no password (empty password)
|
||||
- CA is auto-generated on first registration if not present
|
||||
- Private key is generated server-side and included in response
|
||||
|
||||
# Use fingerprint for header-based auth (behind reverse proxy)
|
||||
curl -H "X-SSL-Client-SHA1: $(openssl x509 -in client.crt -fingerprint -sha1 -noout | cut -d= -f2 | tr -d :)" \
|
||||
https://paste.example.com/pastes
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- `common_name` is optional; a random UUID is generated if omitted
|
||||
- The PKCS#12 bundle has no password (empty password)
|
||||
- CA is auto-generated on first registration if not present
|
||||
- Private key is generated server-side and included in response
|
||||
|
||||
Reference in New Issue
Block a user