SPESİFİKASYON v2

YASP — Yemlee Anahtar Sorgulama Protokolü

YASP, bir e-posta adresinin genel anahtar paketini (bundle) DNS keşfi + HTTPS sorgusu ile bulunabilir kılar, böylece uçtan uca şifreleme için karmaşık anahtar sunucularına gerek kalmaz. Bu belge canlı sistemi olduğu gibi tanımlar.

Uyumluluk Bildirimi

YASP2, YASP1 ile geriye dönük uyumludur. Bundle her zaman YASP1 anahtarlarını (RSA/ECDSA) içerir; YASP2 yetenekli istemciler ek olarak X25519/Ed25519 takımını kullanır. Hiçbir mesaj, herhangi bir desteklenen istemci için çözülemez hâle gelmez.

İçindekiler

  1. DNS Keşfi
  2. Anahtar Paketi (Bundle) Uç Noktası
  3. Şifreleme Takımları (Ciphersuites)
  4. Mesaj Zarfı
  5. Öz-İmza (Authenticity)
  6. Anahtar Şeffaflığı (Key Transparency)
  7. İnsan-Doğrulanabilir Parmak İzi
  8. Aktarım ve Teslimat
  9. Güvenlik Kapsamı (Dürüst Not)

1. DNS Keşfi

Bir alan adının YASP uç noktası, _yasp alt alanındaki bir TXT kaydıyla ilan edilir. İstemci önce bu kaydı çözer, ardından api tabanına anahtar paketi sorgusu yapar.

Kayıt: _yasp.<alan>
Tür: TXT
Değer: v=YASP2; api=<https-taban-url>

Canlı Örnek Kayıt

_yasp.yemlee.com.  IN  TXT  "v=YASP2; api=https://yemlee.com/mail/api/yasp/"

2. Anahtar Paketi (Bundle) Uç Noktası

Bir adresin tüm genel anahtarlarını, desteklenen takımlarını, öz-imzasını ve anahtar şeffaflığı kanıtını tek sorguda döndürür.

İstek: GET {api}{kullanıcı_adı}
Örnek: GET https://yemlee.com/mail/api/yasp/ferhat

Başarılı Yanıt (200 OK)

{
  "v": "YASP2",
  "address": "[email protected]",
  "ciphersuite": "YASP1",
  "ciphersuites": ["YASP1", "YASP2-X25519"],
  "keys": [
    {
      "kid": "OkJ3hBMl6LLnvQpqyb4Bqv",
      "ciphersuite": "YASP1",
      "enc": { "alg": "RSA-OAEP-256", "spki": "<base64-SPKI>" },
      "sig": { "alg": "ECDSA-P256",   "spki": "<base64-SPKI>" },
      "created": 1717000000, "expires": null, "status": "active"
    },
    {
      "kid": "<22-karakter>",
      "ciphersuite": "YASP2-X25519",
      "enc": { "alg": "X25519",  "raw": "<base64-32B>" },
      "sig": { "alg": "Ed25519", "raw": "<base64-32B>" },
      "created": 1717000000, "expires": null, "status": "active",
      "self_sig": "<base64-Ed25519>"
    }
  ],
  "prev": [],
  "self_sig": "<base64-ECDSA>",
  "kt": {
    "sth": { "...": "imzalı ağaç başı (bkz. 6)" },
    "inclusion": { "leaf_index": 0, "tree_size": 2, "audit_path": ["..."], "leaf_data": "...", "leaf_hash": "..." },
    "log_pubkey": "<base64-Ed25519>"
  }
}

Alan bulunamazsa 404 ve {"v":"YASP2","error":"not_found"} döner. kid değeri, ilgili anahtar materyalinin SHA-256 özetinin URL-güvenli base64 ile kısaltılmış (22 karakter) hâlidir.

3. Şifreleme Takımları (Ciphersuites)

YASP1 (taban, zorunlu)

YASP2-X25519 (modern, ek)

Sealed-box telgraf biçimi (kesin):

env  = ephemeral_pub(32B) ‖ nonce(12B) ‖ AES-256-GCM-ciphertext
JSON = { "v": "YASP2-X25519-v1", "env": base64(env) }

shared = X25519(ephemeral_priv, recipient_pub)
key    = HKDF-SHA256( ikm=shared,
                      salt=ephemeral_pub ‖ recipient_pub,
                      info="YASP2-X25519-v1", L=32 )
AEAD   = AES-256-GCM, AAD = "YASP2-X25519-v1"

4. Mesaj Zarfı

İçerik tek bir AES-256-GCM oturum anahtarıyla şifrelenir; bu anahtar her alıcı için hem RSA (keys) hem de X25519 sealed-box (ckeys) ile sarılır. Böylece YASP2 istemciler curve yolunu, eski istemciler RSA yolunu kullanır — aynı mesaj.

{
  "iv":      "<base64 12B>",
  "content": "<base64 AES-256-GCM şifreli gövde>",
  "keys":    { "<kullanıcı>": "<base64 RSA-OAEP ile sarılı AES anahtarı>" },
  "ckeys":   { "<kullanıcı>": "{\"v\":\"YASP2-X25519-v1\",\"env\":\"...\"}" }
}

Çözme sırası: istemci önce ckeys içindeki sealed-box'ı kendi X25519 özel anahtarıyla açmayı dener; başarısız olursa keys içindeki RSA sarmalını çözer. Düz metin yalnızca istemci cihazında oluşur.

5. Öz-İmza (Authenticity)

Bir adresin kendi anahtarlarını bağladığını kanıtlamak için, kullanıcı kendi imza anahtarıyla kanonik bir dizgiyi imzalar. Doğrulayıcı, imzayı bundle'daki imza genel anahtarıyla kontrol eder.

YASP2-X25519 curve öz-imzası (Ed25519 ile imzalanır):

canon = "YASP2-X25519-SELFSIG\n" + address + "\n" + x25519_raw_b64 + "\n" + ed25519_raw_b64
sig   = Ed25519_sign(ed25519_priv, canon)

YASP1 için eşdeğer bir ECDSA öz-imzası bundle'ın üst düzey self_sig alanında taşınır. Kanonik dizgiler, doğrulamanın yetkili (sunucudan dönen) anahtar değerleri üzerinden yapılmasını gerektirir.

6. Anahtar Şeffaflığı (Key Transparency)

Yayınlanan her (kullanıcı → anahtar paketi) bağlaması, Sertifika Şeffaflığı (RFC 6962) tarzı, yalnızca-ekleme yapılan bir Merkle günlüğüne kaydedilir. Bu, sunucunun sessizce sahte bir anahtar yayınlamasını tespit edilebilir kılar.

Merkle ve yaprak (RFC 6962)

leafHash(d)   = SHA-256(0x00 ‖ d)
nodeHash(l,r) = SHA-256(0x01 ‖ l ‖ r)

leaf_data    = username + "\n" + bundle_hash_hex + "\n" + timestamp
bundle_hash  = SHA-256( enc_spki + "\n" + sig_spki + "\n"
                        + x25519_raw + "\n" + ed25519_raw )   (onaltılık)

İmzalı Ağaç Başı (STH)

Her eklemeden sonra kök yeniden hesaplanır ve günlüğün Ed25519 anahtarıyla imzalanır:

canon = "YASP-KT-STH-v1\n" + epoch + "\n" + tree_size + "\n"
        + root_b64 + "\n" + prev_root_b64 + "\n" + signed_at
sig   = Ed25519_sign(log_priv, canon)

Uç Noktalar (public)

GET {api}kt/sth
  → { v, epoch, tree_size, root, prev_root, signed_at, sig, alg, log_pubkey }

GET {api}kt/proof/{kullanıcı}
  → { leaf_index, tree_size, leaf_data, leaf_hash, bundle_hash, audit_path[], sth }

GET {api}kt/consistency?first=N
  → { first, second, proof[], sth }

İstemci doğrulaması (her girişte)

  1. STH imzası, ilan edilen log_pubkey ile Ed25519 olarak doğrulanır.
  2. Inclusion proof (RFC 6962) ile kendi yaprağının STH kökünü ürettiği doğrulanır.
  3. Yaprağın bundle_hash değeri, istemcinin gerçek yayınlanan anahtarlarından yeniden hesaplanan değerle eşleştirilir.
  4. İlk görülen STH güvenilir kabul edilir (TOFU); sonraki girişlerde consistency kanıtıyla günlüğün çatallanmadığı doğrulanır. Log imza anahtarının değişmesi, ağacın küçülmesi veya tutarsızlık durumunda kullanıcı uyarılır.

7. İnsan-Doğrulanabilir Parmak İzi

Anahtar parmak izi onaltılık (hex) gösterimin yanı sıra okunması kolay sözcükler (proquint) ve QR kodu olarak sunulur; iki kullanıcı bunu yan kanaldan (telefon, yüz yüze) karşılaştırarak ortadaki-adam saldırısını eler.

GET {api}../fpqr?d=<parmak-izi>   → image/png (QR)

8. Aktarım ve Teslimat

9. Güvenlik Kapsamı (Dürüst Not)

  • Uçtan uca şifreleme, Yemlee kullanıcıları arasında ve depolanan gelen postada geçerlidir. Harici alıcılara giden posta uçtan uca şifreli değildir (yalnızca TLS + DKIM/SPF/DMARC).
  • Anahtar şeffaflığı v1 tek günlüklüdür ve bağımsız tanık (witness) içermez; tam split-view koruması için gossip/tanık altyapısı planlanmaktadır.
  • Bu belge canlı sistemi tanımlamayı amaçlar; bir özellik henüz devrede değilse burada öyle belirtilir.