cultiva-auth-v1.2-handshake.md
═══════════════════════════════════════════════════════════════════════════════════════ CultivaAuth Device Handshake v1.2 — ASCII Sequence Diagram ═══════════════════════════════════════════════════════════════════════════════════════ ┌──────────┐ ┌──────────┐ │ Dispositivo │ │ Servidor │ └─────┬────┘ └────┬─────┘ │ │ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ FASE 1 · Negociación y Claves Efímeras │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ │ │ keygen() → │ │ │ │ ek_D, epk_D │ │ │ │ │ │ │ │ │── ClientHello(device_id, epk_D, ────────────>│ │ │ │ version="1.2", ts) │ │ │ │ │ │ │ │ │ keygen() → │ │ │ │ ek_S, epk_S │ │ │ │ nonce ← rand(32) │ │ │ │ │ │ │<── ServerHello(epk_S, nonce, cert_S) ────────│ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ FASE 2 · Derivación de Claves │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ │ │ dh_out = DH(ek_D, epk_S) ════ dh_out = DH(ek_S, epk_D) │ │ │ k_enc, k_mac = HKDF(IKM=dh_out, salt=nonce, │ │ │ info="cultiva-auth-v1.2-session") │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ FASE 3 · Autenticación del Dispositivo │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ │ │ transcript = │ │ │ │ H(Hello1||Hello2)│ │ │ │ σ_D = Sign( │ │ │ │ sk_D, transcript||nonce) │ │ │ │ │ │ │ │── DeviceAuth(cert_D, ─────────────────────>│ │ │ │ Enc(k_enc, σ_D||metadata)) │ │ │ │ │ │ │ │ │ Verify cert_D │ │ │ │ against CA │ │ │ │ Dec(k_enc, ct) │ │ │ │ Verify(pk_D, │ │ │ │ transcript,σ_D)│ │ │ │ │ │ [alt: auth falla]│ │ │ │ │<── AuthError(CERT_INVALID | SIG_FAIL) ───────│ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ FASE 4 · Confirmación de Sesión │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ │ │ │ │ session_id = │ │ │ │ H(transcript||ts)│ │ │ │ │ │ │<── SessionAck(session_id, ─────────────────-─│ │ │ │ Enc(k_enc, token||expiry)) │ │ │ │ │ │ │ Dec(k_enc, ct) → │ │ │ │ session_token │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ FASE 5 · Transferencia de Datos [loop] │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ │ │ │── DataPacket(seq_i, Enc(k_enc,─────────────>│ │ │ │ sensor_data, nonce_i)) │ │ │ │ │ │ │ │<── DataAck(seq_i, status) ───────────────────│ │ │ │ │ │ │ │── SessionClose ────────────────────────────->│ │ │ │<── SessionClosed ────────────────────────────│ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ┌─────┴────┐ ┌────┴─────┐ │Dispositivo│ │ Servidor │ └──────────┘ └──────────┘ ═══════════════════════════════════════════════════════════════════════════════════════
mermaid — cultiva-auth-v1.2-handshake.md
sequenceDiagram
participant D as Dispositivo
participant S as Servidor
rect rgba(28, 58, 94, 0.6)
Note over D,S: Fase 1 — Negociacion y Claves Efimeras
Note over D: keygen() → ek_D, epk_D
D->>S: ClientHello(device_id, epk_D, version="1.2", ts)
Note over S: version check — abort si no soportada
Note over S: keygen() → ek_S, epk_S
Note over S: nonce = rand(32 bytes)
S-->>D: ServerHello(epk_S, nonce, cert_S)
end
rect rgba(26, 61, 46, 0.6)
Note over D,S: Fase 2 — Derivacion de Claves
Note over D,S: dh_out = DH(ek_D, epk_S) = DH(ek_S, epk_D)
Note over D,S: k_enc, k_mac = HKDF(IKM=dh_out, salt=nonce, info="cultiva-auth-v1.2-session")
end
rect rgba(59, 43, 107, 0.6)
Note over D,S: Fase 3 — Autenticacion del Dispositivo
Note over D: transcript = H(ClientHello || ServerHello)
Note over D: sigma_D = Sign(sk_D_static, transcript || nonce)
D->>S: DeviceAuth(cert_D, Enc(k_enc, sigma_D || metadata))
Note over S: Verify cert_D contra CA NutriFlow
Note over S: Dec(k_enc, ct) → sigma_D
Note over S: Verify(pk_D, transcript, sigma_D)
alt autenticacion fallida
S-->>D: AuthError(CERT_INVALID o SIG_FAIL)
end
end
rect rgba(61, 43, 20, 0.6)
Note over D,S: Fase 4 — Confirmacion de Sesion
Note over S: session_id = H(transcript || ts_server)
S-->>D: SessionAck(session_id, Enc(k_enc, session_token || expiry))
Note over D: Dec(k_enc, ct) → session_token
end
rect rgba(26, 58, 64, 0.6)
Note over D,S: Fase 5 — Transferencia de Datos
loop cada paquete de sensor
D->>S: DataPacket(seq_i, Enc(k_enc, sensor_data, nonce_i))
S-->>D: DataAck(seq_i, status)
end
D->>S: SessionClose
S-->>D: SessionClosed
end